[llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp

Evan Cheng evan.cheng at apple.com
Wed Jan 25 16:22:37 PST 2006



Changes in directory llvm/utils/TableGen:

DAGISelEmitter.cpp updated: 1.141 -> 1.142
---
Log message:

Incoming (and optional) flag bugs. They may be embedded inside a inner node of
a pattern. Also, nodes which take incoming flag should not be folded if it has
more than one use.


---
Diffs of the changes:  (+56 -30)

 DAGISelEmitter.cpp |   86 ++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 56 insertions(+), 30 deletions(-)


Index: llvm/utils/TableGen/DAGISelEmitter.cpp
diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.141 llvm/utils/TableGen/DAGISelEmitter.cpp:1.142
--- llvm/utils/TableGen/DAGISelEmitter.cpp:1.141	Tue Jan 24 14:46:50 2006
+++ llvm/utils/TableGen/DAGISelEmitter.cpp	Wed Jan 25 18:22:25 2006
@@ -1909,6 +1909,7 @@
     unsigned OpNo = 0;
     bool NodeHasChain = NodeHasProperty(N, SDNodeInfo::SDNPHasChain, ISE);
     bool HasChain = PatternHasProperty(N, SDNodeInfo::SDNPHasChain, ISE);
+    bool EmittedCheck = false;
     if (HasChain) {
       if (NodeHasChain)
         OpNo = 1;
@@ -1916,6 +1917,7 @@
         const SDNodeInfo &CInfo = ISE.getSDNodeInfo(N->getOperator());
         OS << "      if (!" << RootName << ".hasOneUse()) goto P"
            << PatternNo << "Fail;   // Multiple uses of actual result?\n";
+        EmittedCheck = true;
         if (NodeHasChain)
           OS << "      if (CodeGenMap.count(" << RootName
              << ".getValue(" << CInfo.getNumResults() << "))) goto P"
@@ -1927,6 +1929,20 @@
       }
     }
 
+    // Don't fold any node which reads or writes a flag and has multiple uses.
+    // FIXME: we really need to separate the concepts of flag and "glue". Those
+    // real flag results, e.g. X86CMP output, can have multiple uses.
+    if (!EmittedCheck &&
+        (PatternHasProperty(N, SDNodeInfo::SDNPInFlag, ISE) ||
+         PatternHasProperty(N, SDNodeInfo::SDNPOptInFlag, ISE) ||
+         PatternHasProperty(N, SDNodeInfo::SDNPOutFlag, ISE))) {
+      if (!isRoot) {
+        const SDNodeInfo &CInfo = ISE.getSDNodeInfo(N->getOperator());
+        OS << "      if (!" << RootName << ".hasOneUse()) goto P"
+           << PatternNo << "Fail;   // Multiple uses of actual result?\n";
+      }
+    }
+
     for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
       OS << "      SDOperand " << RootName << OpNo << " = "
          << RootName << ".getOperand(" << OpNo << ");\n";
@@ -2116,19 +2132,21 @@
       const DAGInstruction &Inst = ISE.getInstruction(Op);
       bool HasImpInputs  = Inst.getNumImpOperands() > 0;
       bool HasImpResults = Inst.getNumImpResults() > 0;
-      bool HasOptInFlag  = isRoot &&
-        NodeHasProperty(Pattern, SDNodeInfo::SDNPOptInFlag, ISE);
+      bool HasOptInFlag = isRoot &&
+        PatternHasProperty(Pattern, SDNodeInfo::SDNPOptInFlag, ISE);
       bool HasInFlag  = isRoot &&
-        NodeHasProperty(Pattern, SDNodeInfo::SDNPInFlag, ISE);
-      bool HasOutFlag = HasImpResults ||
+        PatternHasProperty(Pattern, SDNodeInfo::SDNPInFlag, ISE);
+      bool NodeHasOutFlag = HasImpResults ||
         (isRoot && PatternHasProperty(Pattern, SDNodeInfo::SDNPOutFlag, ISE));
       bool NodeHasChain =
         NodeHasProperty(Pattern, SDNodeInfo::SDNPHasChain, ISE);
       bool HasChain   = II.hasCtrlDep ||
         (isRoot && PatternHasProperty(Pattern, SDNodeInfo::SDNPHasChain, ISE));
 
-      if (HasOutFlag || HasInFlag || HasOptInFlag || HasImpInputs)
+      if (HasInFlag || NodeHasOutFlag || HasOptInFlag || HasImpInputs)
         OS << "      SDOperand InFlag = SDOperand(0, 0);\n";
+      if (HasOptInFlag)
+        OS << "      bool HasOptInFlag = false;\n";
 
       // How many results is this pattern expected to produce?
       unsigned NumExpectedResults = 0;
@@ -2173,16 +2191,8 @@
       bool ChainEmitted = HasChain;
       if (HasChain)
         OS << "      Chain = Select(Chain);\n";
-      if (HasImpInputs)
-        EmitCopyToRegs(Pattern, "N", ChainEmitted, true);
-      if (HasInFlag || HasOptInFlag) {
-        unsigned FlagNo = (unsigned) NodeHasChain + Pattern->getNumChildren();
-        if (HasOptInFlag)
-          OS << "      if (N.getNumOperands() == " << FlagNo+1 << ") ";
-        else
-          OS << "      ";
-        OS << "InFlag = Select(N.getOperand(" << FlagNo << "));\n";
-      }
+      if (HasInFlag || HasOptInFlag || HasImpInputs)
+        EmitInFlagSelectCode(Pattern, "N", ChainEmitted, true);
 
       unsigned NumResults = Inst.getNumResults();    
       unsigned ResNo = TmpNo++;
@@ -2191,7 +2201,7 @@
            << II.Namespace << "::" << II.TheDef->getName();
         if (N->getTypeNum(0) != MVT::isVoid)
           OS << ", MVT::" << getEnumName(N->getTypeNum(0));
-        if (HasOutFlag)
+        if (NodeHasOutFlag)
           OS << ", MVT::Flag";
 
         unsigned LastOp = 0;
@@ -2205,11 +2215,11 @@
           OS << "      Chain = Tmp" << LastOp << ".getValue("
              << NumResults << ");\n";
         }
-      } else if (HasChain || HasOutFlag) {
+      } else if (HasChain || NodeHasOutFlag) {
         if (HasOptInFlag) {
           OS << "      SDOperand Result = SDOperand(0, 0);\n";
           unsigned FlagNo = (unsigned) NodeHasChain + Pattern->getNumChildren();
-          OS << "      if (N.getNumOperands() == " << FlagNo+1 << ")\n";
+          OS << "      if (HasOptInFlag)\n";
           OS << "        Result = CurDAG->getTargetNode("
              << II.Namespace << "::" << II.TheDef->getName();
 
@@ -2221,7 +2231,7 @@
           }
           if (HasChain)
             OS << ", MVT::Other";
-          if (HasOutFlag)
+          if (NodeHasOutFlag)
             OS << ", MVT::Flag";
 
           // Inputs.
@@ -2242,7 +2252,7 @@
           }
           if (HasChain)
             OS << ", MVT::Other";
-          if (HasOutFlag)
+          if (NodeHasOutFlag)
             OS << ", MVT::Flag";
 
           // Inputs.
@@ -2261,7 +2271,7 @@
           }
           if (HasChain)
             OS << ", MVT::Other";
-          if (HasOutFlag)
+          if (NodeHasOutFlag)
             OS << ", MVT::Flag";
 
           // Inputs.
@@ -2282,7 +2292,7 @@
         if (HasChain)
           OS << "      Chain = Result.getValue(" << ValNo << ");\n";
 
-        if (HasOutFlag)
+        if (NodeHasOutFlag)
           OS << "      InFlag = Result.getValue("
              << ValNo + (unsigned)HasChain << ");\n";
 
@@ -2307,10 +2317,10 @@
           OS << "Chain;\n";
         }
 
-        if (HasOutFlag)
+        if (NodeHasOutFlag)
           OS << "      CodeGenMap[N.getValue(" << ValNo << ")] = InFlag;\n";
 
-        if (AddedChain && HasOutFlag) {
+        if (AddedChain && NodeHasOutFlag) {
           if (NumExpectedResults == 0) {
             OS << "      return Result.getValue(N.ResNo+1);\n";
           } else {
@@ -2330,7 +2340,7 @@
            << II.Namespace << "::" << II.TheDef->getName();
         if (N->getTypeNum(0) != MVT::isVoid)
           OS << ", MVT::" << getEnumName(N->getTypeNum(0));
-        if (HasOutFlag)
+        if (NodeHasOutFlag)
           OS << ", MVT::Flag";
         for (unsigned i = 0, e = Ops.size(); i != e; ++i)
           OS << ", Tmp" << Ops[i];
@@ -2342,7 +2352,7 @@
            << II.Namespace << "::" << II.TheDef->getName();
         if (N->getTypeNum(0) != MVT::isVoid)
           OS << ", MVT::" << getEnumName(N->getTypeNum(0));
-        if (HasOutFlag)
+        if (NodeHasOutFlag)
           OS << ", MVT::Flag";
         for (unsigned i = 0, e = Ops.size(); i != e; ++i)
           OS << ", Tmp" << Ops[i];
@@ -2396,17 +2406,19 @@
   }
 
 private:
-  /// EmitCopyToRegs - Emit the flag operands for the DAG that is
+  /// EmitInFlagSelectCode - Emit the flag operands for the DAG that is
   /// being built.
-  void EmitCopyToRegs(TreePatternNode *N, const std::string &RootName,
-                      bool &ChainEmitted, bool isRoot = false) {
+  void EmitInFlagSelectCode(TreePatternNode *N, const std::string &RootName,
+                            bool &ChainEmitted, bool isRoot = false) {
     const CodeGenTarget &T = ISE.getTargetInfo();
     unsigned OpNo =
       (unsigned) NodeHasProperty(N, SDNodeInfo::SDNPHasChain, ISE);
+    bool HasInFlag = NodeHasProperty(N, SDNodeInfo::SDNPInFlag, ISE);
+    bool HasOptInFlag = NodeHasProperty(N, SDNodeInfo::SDNPOptInFlag, ISE);
     for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
       TreePatternNode *Child = N->getChild(i);
       if (!Child->isLeaf()) {
-        EmitCopyToRegs(Child, RootName + utostr(OpNo), ChainEmitted);
+        EmitInFlagSelectCode(Child, RootName + utostr(OpNo), ChainEmitted);
       } else {
         if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) {
           if (!Child->getName().empty()) {
@@ -2441,6 +2453,20 @@
         }
       }
     }
+
+    if (HasInFlag || HasOptInFlag) {
+      if (HasOptInFlag) {
+        OS << "      if (" << RootName << ".getNumOperands() == "
+           << OpNo+1 << ") {\n";
+        OS << "  ";
+      }
+      OS << "      InFlag = Select(" << RootName << ".getOperand("
+         << OpNo << "));\n";
+      if (HasOptInFlag) {
+        OS << "        HasOptInFlag = true;\n";
+      OS << "      }\n";
+      }
+    }
   }
 
   /// EmitCopyFromRegs - Emit code to copy result to physical registers






More information about the llvm-commits mailing list