[llvm-commits] [llvm] r55156 - in /llvm/trunk: include/llvm/CodeGen/FastISel.h lib/CodeGen/SelectionDAG/FastISel.cpp lib/Target/X86/X86FastISel.cpp test/CodeGen/X86/fast-isel.ll utils/TableGen/CodeGenDAGPatterns.cpp utils/TableGen/CodeGenDAGPatterns.h utils/TableGen/DAGISelEmitter.cpp utils/TableGen/FastISelEmitter.cpp

Dan Gohman gohman at apple.com
Thu Aug 21 17:20:27 PDT 2008


Author: djg
Date: Thu Aug 21 19:20:26 2008
New Revision: 55156

URL: http://llvm.org/viewvc/llvm-project?rev=55156&view=rev
Log:
Factor out the predicate check code from DAGISelEmitter.cpp
and use it in FastISelEmitter.cpp, and make FastISel
subtarget aware. Among other things, this lets it work
properly on x86 targets that don't have SSE, where it
successfully selects x87 instructions.

Modified:
    llvm/trunk/include/llvm/CodeGen/FastISel.h
    llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
    llvm/trunk/lib/Target/X86/X86FastISel.cpp
    llvm/trunk/test/CodeGen/X86/fast-isel.ll
    llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
    llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h
    llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
    llvm/trunk/utils/TableGen/FastISelEmitter.cpp

Modified: llvm/trunk/include/llvm/CodeGen/FastISel.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/FastISel.h?rev=55156&r1=55155&r2=55156&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/FastISel.h (original)
+++ llvm/trunk/include/llvm/CodeGen/FastISel.h Thu Aug 21 19:20:26 2008
@@ -26,18 +26,21 @@
 class TargetData;
 class TargetInstrInfo;
 class TargetLowering;
+class TargetMachine;
 class TargetRegisterClass;
 
 /// FastISel - This is a fast-path instruction selection class that
 /// generates poor code and doesn't support illegal types or non-trivial
 /// lowering, but runs quickly.
 class FastISel {
+protected:
   MachineBasicBlock *MBB;
   MachineFunction &MF;
   MachineRegisterInfo &MRI;
+  const TargetMachine &TM;
   const TargetData &TD;
   const TargetInstrInfo &TII;
-  TargetLowering &TLI;
+  const TargetLowering &TLI;
 
 public:
   /// SelectInstructions - Do "fast" instruction selection over the

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=55156&r1=55155&r2=55156&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Thu Aug 21 19:20:26 2008
@@ -220,10 +220,12 @@
 }
 
 FastISel::FastISel(MachineFunction &mf)
-  : MF(mf), MRI(mf.getRegInfo()),
-    TD(*mf.getTarget().getTargetData()),
-    TII(*mf.getTarget().getInstrInfo()),
-    TLI(*mf.getTarget().getTargetLowering()) {
+  : MF(mf),
+    MRI(mf.getRegInfo()),
+    TM(mf.getTarget()),
+    TD(*TM.getTargetData()),
+    TII(*TM.getInstrInfo()),
+    TLI(*TM.getTargetLowering()) {
 }
 
 FastISel::~FastISel() {}

Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=55156&r1=55155&r2=55156&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Thu Aug 21 19:20:26 2008
@@ -17,4 +17,5 @@
 #include "X86RegisterInfo.h"
 #include "X86ISelLowering.h"
 #include "X86FastISel.h"
+#include "X86TargetMachine.h"
 #include "X86GenFastISel.inc"

Modified: llvm/trunk/test/CodeGen/X86/fast-isel.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fast-isel.ll?rev=55156&r1=55155&r2=55156&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/X86/fast-isel.ll (original)
+++ llvm/trunk/test/CodeGen/X86/fast-isel.ll Thu Aug 21 19:20:26 2008
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | llc -fast-isel -march=x86 -mattr=sse2
+; RUN: llvm-as < %s | llc -fast-isel -march=x86
 
 ; This tests very minimal fast-isel functionality.
 

Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=55156&r1=55155&r2=55156&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Thu Aug 21 19:20:26 2008
@@ -141,6 +141,33 @@
 }
 
 //===----------------------------------------------------------------------===//
+// PatternToMatch implementation
+//
+
+/// getPredicateCheck - Return a single string containing all of this
+/// pattern's predicates concatenated with "&&" operators.
+///
+std::string PatternToMatch::getPredicateCheck() const {
+  std::string PredicateCheck;
+  for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) {
+    if (DefInit *Pred = dynamic_cast<DefInit*>(Predicates->getElement(i))) {
+      Record *Def = Pred->getDef();
+      if (!Def->isSubClassOf("Predicate")) {
+#ifndef NDEBUG
+        Def->dump();
+#endif
+        assert(0 && "Unknown predicate type!");
+      }
+      if (!PredicateCheck.empty())
+        PredicateCheck += " && ";
+      PredicateCheck += "(" + Def->getValueAsString("CondString") + ")";
+    }
+  }
+
+  return PredicateCheck;
+}
+
+//===----------------------------------------------------------------------===//
 // SDTypeConstraint implementation
 //
 

Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h?rev=55156&r1=55155&r2=55156&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h (original)
+++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h Thu Aug 21 19:20:26 2008
@@ -444,6 +444,8 @@
   TreePatternNode *getDstPattern() const { return DstPattern; }
   const std::vector<Record*> &getDstRegs() const { return Dstregs; }
   unsigned         getAddedComplexity() const { return AddedComplexity; }
+
+  std::string getPredicateCheck() const;
 };
 
   

Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=55156&r1=55155&r2=55156&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Thu Aug 21 19:20:26 2008
@@ -317,7 +317,7 @@
   CodeGenDAGPatterns &CGP;
 
   // Predicates.
-  ListInit *Predicates;
+  std::string PredicateCheck;
   // Pattern cost.
   unsigned Cost;
   // Instruction selector pattern.
@@ -395,7 +395,7 @@
     VTNo++;
   }
 public:
-  PatternCodeEmitter(CodeGenDAGPatterns &cgp, ListInit *preds,
+  PatternCodeEmitter(CodeGenDAGPatterns &cgp, std::string predcheck,
                      TreePatternNode *pattern, TreePatternNode *instr,
                      std::vector<std::pair<unsigned, std::string> > &gc,
                      std::set<std::string> &gd,
@@ -403,7 +403,7 @@
                      std::vector<std::string> &tv,
                      bool &oiv,
                      unsigned &niro)
-  : CGP(cgp), Predicates(preds), Pattern(pattern), Instruction(instr),
+  : CGP(cgp), PredicateCheck(predcheck), Pattern(pattern), Instruction(instr),
     GeneratedCode(gc), GeneratedDecl(gd),
     TargetOpcodes(to), TargetVTs(tv),
     OutputIsVariadic(oiv), NumInputRootOps(niro),
@@ -431,22 +431,6 @@
       if (DisablePatternForFastISel(N, CGP))
         emitCheck("!Fast");
 
-      std::string PredicateCheck;
-      for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) {
-        if (DefInit *Pred = dynamic_cast<DefInit*>(Predicates->getElement(i))) {
-          Record *Def = Pred->getDef();
-          if (!Def->isSubClassOf("Predicate")) {
-#ifndef NDEBUG
-            Def->dump();
-#endif
-            assert(0 && "Unknown predicate type!");
-          }
-          if (!PredicateCheck.empty())
-            PredicateCheck += " && ";
-          PredicateCheck += "(" + Def->getValueAsString("CondString") + ")";
-        }
-      }
-      
       emitCheck(PredicateCheck);
     }
 
@@ -1412,7 +1396,7 @@
   OutputIsVariadic = false;
   NumInputRootOps = 0;
 
-  PatternCodeEmitter Emitter(CGP, Pattern.getPredicates(),
+  PatternCodeEmitter Emitter(CGP, Pattern.getPredicateCheck(),
                              Pattern.getSrcPattern(), Pattern.getDstPattern(),
                              GeneratedCode, GeneratedDecl,
                              TargetOpcodes, TargetVTs,

Modified: llvm/trunk/utils/TableGen/FastISelEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FastISelEmitter.cpp?rev=55156&r1=55155&r2=55156&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/FastISelEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/FastISelEmitter.cpp Thu Aug 21 19:20:26 2008
@@ -175,10 +175,11 @@
   OS << "namespace " << InstNS.substr(0, InstNS.size() - 2) << " {\n";
   OS << "\n";
   
-  typedef std::map<MVT::SimpleValueType, InstructionMemo> TypeMap;
-  typedef std::map<std::string, TypeMap> OpcodeTypeMap;
-  typedef std::map<OperandsSignature, OpcodeTypeMap> OperandsOpcodeTypeMap;
-  OperandsOpcodeTypeMap SimplePatterns;
+  typedef std::map<std::string, InstructionMemo> PredMap;
+  typedef std::map<MVT::SimpleValueType, PredMap> TypePredMap;
+  typedef std::map<std::string, TypePredMap> OpcodeTypePredMap;
+  typedef std::map<OperandsSignature, OpcodeTypePredMap> OperandsOpcodeTypePredMap;
+  OperandsOpcodeTypePredMap SimplePatterns;
 
   for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(),
        E = CGP.ptm_end(); I != E; ++I) {
@@ -230,27 +231,32 @@
     if (!Operands.initialize(InstPatNode, Target, VT, DstRC))
       continue;
 
+    // Get the predicate that guards this pattern.
+    std::string PredicateCheck = Pattern.getPredicateCheck();
+
     // Ok, we found a pattern that we can handle. Remember it.
     InstructionMemo Memo = {
       Pattern.getDstPattern()->getOperator()->getName(),
       DstRC
     };
-    SimplePatterns[Operands][OpcodeName][VT] = Memo;
+    assert(!SimplePatterns[Operands][OpcodeName][VT].count(PredicateCheck) &&
+           "Duplicate pattern!");
+    SimplePatterns[Operands][OpcodeName][VT][PredicateCheck] = Memo;
   }
 
   // Declare the target FastISel class.
   OS << "class FastISel : public llvm::FastISel {\n";
-  for (OperandsOpcodeTypeMap::const_iterator OI = SimplePatterns.begin(),
+  for (OperandsOpcodeTypePredMap::const_iterator OI = SimplePatterns.begin(),
        OE = SimplePatterns.end(); OI != OE; ++OI) {
     const OperandsSignature &Operands = OI->first;
-    const OpcodeTypeMap &OTM = OI->second;
+    const OpcodeTypePredMap &OTM = OI->second;
 
-    for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end();
+    for (OpcodeTypePredMap::const_iterator I = OTM.begin(), E = OTM.end();
          I != E; ++I) {
       const std::string &Opcode = I->first;
-      const TypeMap &TM = I->second;
+      const TypePredMap &TM = I->second;
 
-      for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end();
+      for (TypePredMap::const_iterator TI = TM.begin(), TE = TM.end();
            TI != TE; ++TI) {
         MVT::SimpleValueType VT = TI->first;
 
@@ -279,8 +285,19 @@
     Operands.PrintParameters(OS);
     OS << ");\n";
   }
+  OS << "\n";
+
+  // Declare the Subtarget member, which is used for predicate checks.
+  OS << "  const " << InstNS.substr(0, InstNS.size() - 2)
+     << "Subtarget *Subtarget;\n";
+  OS << "\n";
+
+  // Declare the constructor.
   OS << "public:\n";
-  OS << "  explicit FastISel(MachineFunction &mf) : llvm::FastISel(mf) {}\n";
+  OS << "  explicit FastISel(MachineFunction &mf)\n";
+  OS << "     : llvm::FastISel(mf),\n";
+  OS << "       Subtarget(&TM.getSubtarget<" << InstNS.substr(0, InstNS.size() - 2)
+     << "Subtarget>()) {}\n";
   OS << "};\n";
   OS << "\n";
 
@@ -291,25 +308,26 @@
   OS << "\n";
 
   // Now emit code for all the patterns that we collected.
-  for (OperandsOpcodeTypeMap::const_iterator OI = SimplePatterns.begin(),
+  for (OperandsOpcodeTypePredMap::const_iterator OI = SimplePatterns.begin(),
        OE = SimplePatterns.end(); OI != OE; ++OI) {
     const OperandsSignature &Operands = OI->first;
-    const OpcodeTypeMap &OTM = OI->second;
+    const OpcodeTypePredMap &OTM = OI->second;
 
-    for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end();
+    for (OpcodeTypePredMap::const_iterator I = OTM.begin(), E = OTM.end();
          I != E; ++I) {
       const std::string &Opcode = I->first;
-      const TypeMap &TM = I->second;
+      const TypePredMap &TM = I->second;
 
       OS << "// FastEmit functions for " << Opcode << ".\n";
       OS << "\n";
 
       // Emit one function for each opcode,type pair.
-      for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end();
+      for (TypePredMap::const_iterator TI = TM.begin(), TE = TM.end();
            TI != TE; ++TI) {
         MVT::SimpleValueType VT = TI->first;
-        const InstructionMemo &Memo = TI->second;
-  
+        const PredMap &PM = TI->second;
+        bool HasPred = false;
+
         OS << "unsigned FastISel::FastEmit_"
            << getLegalCName(Opcode)
            << "_" << getLegalCName(getName(VT)) << "_";
@@ -317,14 +335,34 @@
         OS << "(";
         Operands.PrintParameters(OS);
         OS << ") {\n";
-        OS << "  return FastEmitInst_";
-        Operands.PrintManglingSuffix(OS);
-        OS << "(" << InstNS << Memo.Name << ", ";
-        OS << InstNS << Memo.RC->getName() << "RegisterClass";
-        if (!Operands.empty())
-          OS << ", ";
-        Operands.PrintArguments(OS);
-        OS << ");\n";
+
+        // Emit code for each possible instruction. There may be
+        // multiple if there are subtarget concerns.
+        for (PredMap::const_iterator PI = PM.begin(), PE = PM.end();
+             PI != PE; ++PI) {
+          std::string PredicateCheck = PI->first;
+          const InstructionMemo &Memo = PI->second;
+  
+          if (PredicateCheck.empty()) {
+            assert(!HasPred && "Multiple instructions match, at least one has "
+                               "a predicate and at least one doesn't!");
+          } else {
+            OS << "  if (" + PredicateCheck + ")\n";
+            OS << "  ";
+            HasPred = true;
+          }
+          OS << "  return FastEmitInst_";
+          Operands.PrintManglingSuffix(OS);
+          OS << "(" << InstNS << Memo.Name << ", ";
+          OS << InstNS << Memo.RC->getName() << "RegisterClass";
+          if (!Operands.empty())
+            OS << ", ";
+          Operands.PrintArguments(OS);
+          OS << ");\n";
+        }
+        // Return 0 if none of the predicates were satisfied.
+        if (HasPred)
+          OS << "  return 0;\n";
         OS << "}\n";
         OS << "\n";
       }
@@ -339,7 +377,7 @@
       Operands.PrintParameters(OS);
       OS << ") {\n";
       OS << "  switch (VT) {\n";
-      for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end();
+      for (TypePredMap::const_iterator TI = TM.begin(), TE = TM.end();
            TI != TE; ++TI) {
         MVT::SimpleValueType VT = TI->first;
         std::string TypeName = getName(VT);
@@ -366,7 +404,7 @@
     Operands.PrintParameters(OS);
     OS << ") {\n";
     OS << "  switch (Opcode) {\n";
-    for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end();
+    for (OpcodeTypePredMap::const_iterator I = OTM.begin(), E = OTM.end();
          I != E; ++I) {
       const std::string &Opcode = I->first;
 





More information about the llvm-commits mailing list