[llvm-commits] [llvm] r51699 - in /llvm/trunk: lib/Target/Target.td lib/Target/TargetSelectionDAG.td lib/Target/X86/X86ISelDAGToDAG.cpp lib/Target/X86/X86InstrInfo.td utils/TableGen/CodeGenDAGPatterns.cpp utils/TableGen/CodeGenInstruction.cpp utils/TableGen/DAGISelEmitter.cpp utils/TableGen/InstrInfoEmitter.cpp

Dan Gohman gohman at apple.com
Thu May 29 12:57:41 PDT 2008


Author: djg
Date: Thu May 29 14:57:41 2008
New Revision: 51699

URL: http://llvm.org/viewvc/llvm-project?rev=51699&view=rev
Log:
Fix a tblgen problem handling variable_ops in tblgen instruction
definitions. This adds a new construct, "discard", for indicating
that a named node in the input matching pattern is to be discarded,
instead of corresponding to a node in the output pattern. This
allows tblgen to know where the arguments for the varaible_ops are
supposed to begin.

This fixes "rdar://5791600", whatever that is ;-).

Modified:
    llvm/trunk/lib/Target/Target.td
    llvm/trunk/lib/Target/TargetSelectionDAG.td
    llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
    llvm/trunk/lib/Target/X86/X86InstrInfo.td
    llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
    llvm/trunk/utils/TableGen/CodeGenInstruction.cpp
    llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
    llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp

Modified: llvm/trunk/lib/Target/Target.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Target.td?rev=51699&r1=51698&r2=51699&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Target.td (original)
+++ llvm/trunk/lib/Target/Target.td Thu May 29 14:57:41 2008
@@ -259,6 +259,12 @@
 /// of operands.
 def variable_ops;
 
+/// discard definition - Mark this operand as being matched in the input
+/// but omitted from the output. This is necessary in some situations
+/// involving variable_ops to help the pattern matcher determine which
+/// input nodes to forward on to the variable_ops portion of the output.
+def discard;
+
 /// ptr_rc definition - Mark this operand as being a pointer value whose
 /// register class is resolved dynamically via a callback to TargetInstrInfo.
 /// FIXME: We should probably change this to a class which contain a list of

Modified: llvm/trunk/lib/Target/TargetSelectionDAG.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetSelectionDAG.td?rev=51699&r1=51698&r2=51699&view=diff

==============================================================================
--- llvm/trunk/lib/Target/TargetSelectionDAG.td (original)
+++ llvm/trunk/lib/Target/TargetSelectionDAG.td Thu May 29 14:57:41 2008
@@ -470,6 +470,7 @@
 def vtInt      : PatLeaf<(vt),  [{ return MVT::isInteger(N->getVT()); }]>;
 def vtFP       : PatLeaf<(vt),  [{ return MVT::isFloatingPoint(N->getVT()); }]>;
 
+def immAllZeros : PatLeaf<(imm), [{ return N->isNullValue(); }]>;
 def immAllOnes : PatLeaf<(imm), [{ return N->isAllOnesValue(); }]>;
 def immAllOnesV: PatLeaf<(build_vector), [{
   return ISD::isBuildVectorAllOnes(N);

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

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Thu May 29 14:57:41 2008
@@ -1175,35 +1175,6 @@
     case X86ISD::GlobalBaseReg: 
       return getGlobalBaseReg();
 
-    // FIXME: This is a workaround for a tblgen problem: rdar://5791600
-    case X86ISD::RET_FLAG:
-      if (ConstantSDNode *Amt = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
-        if (Amt->getSignExtended() != 0) break;
-        
-        // Match (X86retflag 0).
-        SDOperand Chain = N.getOperand(0);
-        bool HasInFlag = N.getOperand(N.getNumOperands()-1).getValueType()
-                          == MVT::Flag;
-        SmallVector<SDOperand, 8> Ops0;
-        AddToISelQueue(Chain);
-        SDOperand InFlag(0, 0);
-        if (HasInFlag) {
-          InFlag = N.getOperand(N.getNumOperands()-1);
-          AddToISelQueue(InFlag);
-        }
-        for (unsigned i = 2, e = N.getNumOperands()-(HasInFlag?1:0); i != e;
-             ++i) {
-          AddToISelQueue(N.getOperand(i));
-          Ops0.push_back(N.getOperand(i));
-        }
-        Ops0.push_back(Chain);
-        if (HasInFlag)
-          Ops0.push_back(InFlag);
-        return CurDAG->getTargetNode(X86::RET, MVT::Other,
-                                     &Ops0[0], Ops0.size());
-      }
-      break;
-      
     case ISD::ADD: {
       // Turn ADD X, c to MOV32ri X+c. This cannot be done with tblgen'd
       // code and is matched first so to prevent it from being turned into

Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=51699&r1=51698&r2=51699&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Thu May 29 14:57:41 2008
@@ -45,7 +45,7 @@
 def SDT_X86CallSeqEnd   : SDCallSeqEnd<[ SDTCisVT<0, i32>,
                                          SDTCisVT<1, i32> ]>;
 
-def SDT_X86Call   : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
+def SDT_X86Call   : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
 
 def SDTX86RepStr  : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
 
@@ -322,9 +322,9 @@
 // Return instructions.
 let isTerminator = 1, isReturn = 1, isBarrier = 1,
     hasCtrlDep = 1, FPForm = SpecialFP, FPFormBits = SpecialFP.Value in {
-  def RET    : I   <0xC3, RawFrm, (outs), (ins variable_ops),
+  def RET    : I   <0xC3, RawFrm, (outs), (ins discard:$amt, variable_ops),
                     "ret",
-                    [/*(X86retflag 0)*/ /*FIXME: Disabled: rdar://5791600*/]>;
+                    [(X86retflag immAllZeros:$amt)]>;
   def RETI   : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt, variable_ops),
                     "ret\t$amt",
                     [(X86retflag imm:$amt)]>;

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

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Thu May 29 14:57:41 2008
@@ -916,6 +916,8 @@
         MadeChange |= Child->UpdateNodeType(MVT::iPTR, TP);
       } else if (OperandNode->getName() == "unknown") {
         MadeChange |= Child->UpdateNodeType(MVT::isUnknown, TP);
+      } else if (OperandNode->getName() == "discard") {
+        MadeChange |= Child->UpdateNodeType(MVT::isUnknown, TP);
       } else {
         assert(0 && "Unknown operand type!");
         abort();

Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.cpp?rev=51699&r1=51698&r2=51699&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenInstruction.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenInstruction.cpp Thu May 29 14:57:41 2008
@@ -163,7 +163,8 @@
       isVariadic = true;
       continue;
     } else if (!Rec->isSubClassOf("RegisterClass") && 
-               Rec->getName() != "ptr_rc" && Rec->getName() != "unknown")
+               Rec->getName() != "ptr_rc" && Rec->getName() != "unknown" &&
+               Rec->getName() != "discard")
       throw "Unknown operand class '" + Rec->getName() +
             "' in instruction '" + R->getName() + "' instruction!";
 

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

==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Thu May 29 14:57:41 2008
@@ -947,22 +947,20 @@
       // instruction operands to do this.
       std::vector<std::string> AllOps;
       unsigned NumEAInputs = 0; // # of synthesized 'execute always' inputs.
+      unsigned NumDiscardedInputs = 0; // # of 'discard' inputs to skip.
       for (unsigned ChildNo = 0, InstOpNo = NumResults;
            InstOpNo != II.OperandList.size(); ++InstOpNo) {
         std::vector<std::string> Ops;
         
-        // If this is a normal operand or a predicate operand without
-        // 'execute always', emit it.
+        // Determine what to emit for this operand.
         Record *OperandNode = II.OperandList[InstOpNo].Rec;
-        if ((!OperandNode->isSubClassOf("PredicateOperand") &&
-             !OperandNode->isSubClassOf("OptionalDefOperand")) ||
-            CGP.getDefaultOperand(OperandNode).DefaultOps.empty()) {
-          Ops = EmitResultCode(N->getChild(ChildNo), DstRegs,
-                               InFlagDecled, ResNodeDecled);
-          AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
-          ++ChildNo;
-        } else {
-          // Otherwise, this is a predicate or optional def operand, emit the
+        if (OperandNode->getName() == "discard") {
+          // This is a "discard" operand; emit nothing. Just note it.
+          ++NumDiscardedInputs;
+        } else if ((OperandNode->isSubClassOf("PredicateOperand") ||
+                    OperandNode->isSubClassOf("OptionalDefOperand")) &&
+                   !CGP.getDefaultOperand(OperandNode).DefaultOps.empty()) {
+          // This is a predicate or optional def operand; emit the
           // 'default ops' operands.
           const DAGDefaultOperand &DefaultOp =
             CGP.getDefaultOperand(II.OperandList[InstOpNo].Rec);
@@ -972,6 +970,13 @@
             AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
             NumEAInputs += Ops.size();
           }
+        } else {
+          // Otherwise this is a normal operand or a predicate operand without
+          // 'execute always'; emit it.
+          Ops = EmitResultCode(N->getChild(ChildNo), DstRegs,
+                               InFlagDecled, ResNodeDecled);
+          AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
+          ++ChildNo;
         }
       }
 
@@ -1049,19 +1054,23 @@
         if (NodeHasOutFlag)
           Code += ", MVT::Flag";
 
-        // Figure out how many fixed inputs the node has.  This is important to
-        // know which inputs are the variable ones if present.
-        unsigned NumInputs = AllOps.size();
-        NumInputs += NodeHasChain;
-        
         // Inputs.
         if (HasVarOps) {
+          // Figure out how many fixed inputs the node has.  This is important
+          // to know which inputs are the variable ones if present. Include
+          // the 'discard' and chain inputs in the count, and adjust for the
+          // number of operands that are 'execute always'. This is the index
+          // where we should start copying operands into the 'variable_ops'
+          // portion of the output.
+          unsigned InputIndex = AllOps.size() +
+                                NumDiscardedInputs +
+                                NodeHasChain -
+                                NumEAInputs;
+        
           for (unsigned i = 0, e = AllOps.size(); i != e; ++i)
             emitCode("Ops" + utostr(OpsNo) + ".push_back(" + AllOps[i] + ");");
           AllOps.clear();
-        }
 
-        if (HasVarOps) {
           // Figure out whether any operands at the end of the op list are not
           // part of the variable section.
           std::string EndAdjust;
@@ -1070,7 +1079,7 @@
           else if (NodeHasOptInFlag)
             EndAdjust = "-(HasInFlag?1:0)"; // May have a flag.
 
-          emitCode("for (unsigned i = " + utostr(NumInputs - NumEAInputs) +
+          emitCode("for (unsigned i = " + utostr(InputIndex) +
                    ", e = N.getNumOperands()" + EndAdjust + "; i != e; ++i) {");
 
           emitCode("  AddToISelQueue(N.getOperand(i));");

Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=51699&r1=51698&r2=51699&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Thu May 29 14:57:41 2008
@@ -85,6 +85,10 @@
       Record *OpR = OperandList[j].Rec;
       std::string Res;
       
+      // Discard "discard" operands.
+      if (OpR->getName() == "discard")
+        continue;
+
       if (OpR->isSubClassOf("RegisterClass"))
         Res += getQualifiedName(OpR) + "RegClassID, ";
       else
@@ -201,6 +205,14 @@
     // Each logical operand can be multiple MI operands.
     MinOperands = Inst.OperandList.back().MIOperandNo +
                   Inst.OperandList.back().MINumOperands;
+
+  // Subtract the number of "discard" operands, which we'll be skipping
+  // when emitting OperandInfo records.
+  for (unsigned j = 0, e = Inst.OperandList.size(); j != e; ++j) {
+    Record *OpR = Inst.OperandList[j].Rec;
+    if (OpR->getName() == "discard")
+      --MinOperands;
+  }
   
   OS << "  { ";
   OS << Num << ",\t" << MinOperands << ",\t"





More information about the llvm-commits mailing list