Rewrite tblgen handling of subtarget features so
[oota-llvm.git] / utils / TableGen / DAGISelEmitter.cpp
index 7a1920ceac7b2e11bbcdf4fbbe51075ec3481ed7..472edbccbe0fd6149a7cdd03cf889b49adad176a 100644 (file)
@@ -313,6 +313,12 @@ private:
   std::vector<std::pair<std::string, std::string> > OrigChains;
   std::set<std::string> Duplicates;
 
+  /// LSI - Load/Store information.
+  /// Save loads/stores matched by a pattern, and generate a MemOperandSDNode
+  /// for each memory access. This facilitates the use of AliasAnalysis in
+  /// the backend.
+  std::vector<std::string> LSI;
+
   /// GeneratedCode - This is the buffer that we emit code to.  The first int
   /// indicates whether this is an exit predicate (something that should be
   /// tested, and if true, the match fails) [when 1], or normal code to emit
@@ -373,6 +379,16 @@ public:
   void EmitMatchCode(TreePatternNode *N, TreePatternNode *P,
                      const std::string &RootName, const std::string &ChainSuffix,
                      bool &FoundChain) {
+
+    // Save loads/stores matched by a pattern.
+    if (!N->isLeaf() && N->getName().empty()) {
+      std::string EnumName = N->getOperator()->getValueAsString("Opcode");
+      if (EnumName == "ISD::LOAD" ||
+          EnumName == "ISD::STORE") {
+        LSI.push_back(RootName);
+      }
+    }
+
     bool isRoot = (P == NULL);
     // Emit instruction predicates. Each predicate is just a string for now.
     if (isRoot) {
@@ -748,6 +764,18 @@ public:
         Val = TmpVar;
         ModifiedVal = true;
         NodeOps.push_back(Val);
+      } else if (!N->isLeaf() && N->getOperator()->getName() == "fpimm") {
+        assert(N->getExtTypes().size() == 1 && "Multiple types not handled!");
+        std::string TmpVar =  "Tmp" + utostr(ResNo);
+        emitCode("SDOperand " + TmpVar + 
+                 " = CurDAG->getTargetConstantFP(cast<ConstantFPSDNode>(" + 
+                 Val + ")->getValueAPF(), cast<ConstantFPSDNode>(" + Val +
+                 ")->getValueType(0));");
+        // Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
+        // value if used multiple times by this pattern result.
+        Val = TmpVar;
+        ModifiedVal = true;
+        NodeOps.push_back(Val);
       } else if (!N->isLeaf() && N->getOperator()->getName() == "texternalsym"){
         Record *Op = OperatorMap[N->getName()];
         // Transform ExternalSymbol to TargetExternalSymbol
@@ -944,6 +972,18 @@ public:
         }
       }
 
+      // Generate MemOperandSDNodes nodes for each memory accesses covered by this
+      // pattern.
+      if (isRoot) {
+        std::vector<std::string>::const_iterator mi, mie;
+        for (mi = LSI.begin(), mie = LSI.end(); mi != mie; ++mi) {
+          emitCode("SDOperand LSI_" + *mi + " = "
+                   "CurDAG->getMemOperand(cast<LSBaseSDNode>(" +
+                   *mi + ")->getMemOperand());");
+          AllOps.push_back("LSI_" + *mi);
+        }
+      }
+
       // Emit all the chain and CopyToReg stuff.
       bool ChainEmitted = NodeHasChain;
       if (NodeHasChain)
@@ -1861,6 +1901,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
      << "  case ISD::Register:\n"
      << "  case ISD::HANDLENODE:\n"
      << "  case ISD::TargetConstant:\n"
+     << "  case ISD::TargetConstantFP:\n"
      << "  case ISD::TargetConstantPool:\n"
      << "  case ISD::TargetFrameIndex:\n"
      << "  case ISD::TargetExternalSymbol:\n"