[llvm] r280011 - GlobalISel: use multi-dimensional arrays for legalize actions.

Tim Northover via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 29 14:00:00 PDT 2016


Author: tnorthover
Date: Mon Aug 29 16:00:00 2016
New Revision: 280011

URL: http://llvm.org/viewvc/llvm-project?rev=280011&view=rev
Log:
GlobalISel: use multi-dimensional arrays for legalize actions.

Instead of putting all possible requests into a single table, we can perform
the extremely dense lookup based on opcode and type-index in constant time
using multi-dimensional array-like things.

This roughly halves the time spent doing legalization, which was dominated by
queries against the Actions table.

Modified:
    llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h
    llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
    llvm/trunk/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp

Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h?rev=280011&r1=280010&r2=280011&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h Mon Aug 29 16:00:00 2016
@@ -17,6 +17,7 @@
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/CodeGen/LowLevelType.h"
+#include "llvm/Target/TargetOpcodes.h"
 
 #include <cstdint>
 #include <functional>
@@ -44,21 +45,6 @@ struct InstrAspect {
   }
 };
 
-template <> struct DenseMapInfo<InstrAspect> {
-  static inline InstrAspect getEmptyKey() { return {-1u, 0, LLT{}}; }
-
-  static inline InstrAspect getTombstoneKey() { return {-2u, 0, LLT{}}; }
-
-  static unsigned getHashValue(const InstrAspect &Val) {
-    return DenseMapInfo<std::pair<uint64_t, LLT>>::getHashValue(
-        {(uint64_t)Val.Opcode << 32 | Val.Idx, Val.Type});
-  }
-
-  static bool isEqual(const InstrAspect &LHS, const InstrAspect &RHS) {
-    return LHS == RHS;
-  }
-};
-
 class MachineLegalizer {
 public:
   enum LegalizeAction : std::uint8_t {
@@ -103,6 +89,9 @@ public:
     /// This operation is completely unsupported on the target. A programming
     /// error has occurred.
     Unsupported,
+
+    /// Sentinel value for when no action was found in the specified table.
+    NotFound,
   };
 
   MachineLegalizer();
@@ -116,7 +105,10 @@ public:
   /// representation.
   void setAction(const InstrAspect &Aspect, LegalizeAction Action) {
     TablesInitialized = false;
-    Actions[Aspect] = Action;
+    unsigned Opcode = Aspect.Opcode - FirstOp;
+    if (Actions[Opcode].size() <= Aspect.Idx)
+      Actions[Opcode].resize(Aspect.Idx + 1);
+    Actions[Aspect.Opcode - FirstOp][Aspect.Idx][Aspect.Type] = Action;
   }
 
   /// If an operation on a given vector type (say <M x iN>) isn't explicitly
@@ -152,11 +144,12 @@ public:
   LLT findLegalType(const InstrAspect &Aspect,
                     std::function<LLT(LLT)> NextType) const {
     LegalizeAction Action;
+    const TypeMap &Map = Actions[Aspect.Opcode - FirstOp][Aspect.Idx];
     LLT Ty = Aspect.Type;
     do {
       Ty = NextType(Ty);
-      auto ActionIt = Actions.find({Aspect.Opcode, Aspect.Idx, Ty});
-      if (ActionIt == Actions.end())
+      auto ActionIt = Map.find(Ty);
+      if (ActionIt == Map.end())
         Action = DefaultActions.find(Aspect.Opcode)->second;
       else
         Action = ActionIt->second;
@@ -173,13 +166,32 @@ public:
     return std::make_pair(Action, findLegalType(Aspect, Action));
   }
 
+  /// Find the specified \p Aspect in the primary (explicitly set) Actions
+  /// table. Returns either the action the target requested or NotFound if there
+  /// was no setAction call.
+  LegalizeAction findInActions(const InstrAspect &Aspect) const {
+    if (Aspect.Opcode < FirstOp || Aspect.Opcode > LastOp)
+      return NotFound;
+    if (Aspect.Idx >= Actions[Aspect.Opcode - FirstOp].size())
+      return NotFound;
+    const TypeMap &Map = Actions[Aspect.Opcode - FirstOp][Aspect.Idx];
+    auto ActionIt =  Map.find(Aspect.Type);
+    if (ActionIt == Map.end())
+      return NotFound;
+
+    return ActionIt->second;
+  }
+
   bool isLegal(const MachineInstr &MI) const;
 
 private:
-  typedef DenseMap<InstrAspect, LegalizeAction> ActionMap;
+  static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
+  static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
+
+  typedef DenseMap<LLT, LegalizeAction> TypeMap;
   typedef DenseMap<std::pair<unsigned, LLT>, LegalizeAction> SIVActionMap;
 
-  ActionMap Actions;
+  SmallVector<TypeMap, 1> Actions[LastOp - FirstOp + 1];
   SIVActionMap ScalarInVectorActions;
   DenseMap<std::pair<unsigned, LLT>, uint16_t> MaxLegalVectorElts;
   DenseMap<unsigned, LegalizeAction> DefaultActions;

Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp?rev=280011&r1=280010&r2=280011&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp Mon Aug 29 16:00:00 2016
@@ -17,9 +17,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/CodeGen/GlobalISel/MachineLegalizer.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/CodeGen/GlobalISel/MachineLegalizer.h"
 #include "llvm/IR/Type.h"
 #include "llvm/Target/TargetOpcodes.h"
 using namespace llvm;
@@ -39,14 +39,18 @@ MachineLegalizer::MachineLegalizer() : T
 }
 
 void MachineLegalizer::computeTables() {
-  for (auto &Op : Actions) {
-    LLT Ty = Op.first.Type;
-    if (!Ty.isVector())
-      continue;
-
-    auto &Entry = MaxLegalVectorElts[std::make_pair(Op.first.Opcode,
-                                                    Ty.getElementType())];
-    Entry = std::max(Entry, Ty.getNumElements());
+  for (unsigned Opcode = 0; Opcode <= LastOp - FirstOp; ++Opcode) {
+    for (unsigned Idx = 0; Idx != Actions[Opcode].size(); ++Idx) {
+      for (auto &Action : Actions[Opcode][Idx]) {
+        LLT Ty = Action.first;
+        if (!Ty.isVector())
+          continue;
+
+        auto &Entry = MaxLegalVectorElts[std::make_pair(Opcode + FirstOp,
+                                                        Ty.getElementType())];
+        Entry = std::max(Entry, Ty.getNumElements());
+      }
+    }
   }
 
   TablesInitialized = true;
@@ -68,9 +72,9 @@ MachineLegalizer::getAction(const InstrA
       Aspect.Opcode == TargetOpcode::G_EXTRACT)
     return std::make_pair(Legal, Aspect.Type);
 
-  auto ActionIt = Actions.find(Aspect);
-  if (ActionIt != Actions.end())
-    return findLegalAction(Aspect, ActionIt->second);
+  LegalizeAction Action = findInActions(Aspect);
+  if (Action != NotFound)
+    return findLegalAction(Aspect, Action);
 
   unsigned Opcode = Aspect.Opcode;
   LLT Ty = Aspect.Type;

Modified: llvm/trunk/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp?rev=280011&r1=280010&r2=280011&view=diff
==============================================================================
--- llvm/trunk/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp (original)
+++ llvm/trunk/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp Mon Aug 29 16:00:00 2016
@@ -21,6 +21,7 @@ using llvm::MachineLegalizer::LegalizeAc
 using llvm::MachineLegalizer::LegalizeAction::Libcall;
 using llvm::MachineLegalizer::LegalizeAction::Custom;
 using llvm::MachineLegalizer::LegalizeAction::Unsupported;
+using llvm::MachineLegalizer::LegalizeAction::NotFound;
 
 // Define a couple of pretty printers to help debugging when things go wrong.
 namespace llvm {
@@ -36,6 +37,7 @@ operator<<(std::ostream &OS, const llvm:
   case Libcall: OS << "Libcall"; break;
   case Custom: OS << "Custom"; break;
   case Unsupported: OS << "Unsupported"; break;
+  case NotFound: OS << "NotFound";
   }
   return OS;
 }




More information about the llvm-commits mailing list