[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp SelectionDAGISel.cpp

Chris Lattner lattner at cs.uiuc.edu
Thu Feb 23 11:21:16 PST 2006



Changes in directory llvm/lib/CodeGen/SelectionDAG:

ScheduleDAG.cpp updated: 1.66 -> 1.67
SelectionDAGISel.cpp updated: 1.168 -> 1.169
---
Log message:

Record all of the expanded registers in the DAG and machine instr, fixing
several bugs in inline asm expanded operands.


---
Diffs of the changes:  (+125 -74)

 ScheduleDAG.cpp      |   31 ++++++---
 SelectionDAGISel.cpp |  168 +++++++++++++++++++++++++++++++--------------------
 2 files changed, 125 insertions(+), 74 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.66 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.67
--- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.66	Wed Feb  8 20:23:13 2006
+++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp	Thu Feb 23 13:21:04 2006
@@ -309,23 +309,32 @@
       MI->addExternalSymbolOperand(AsmStr, false);
       
       // Add all of the operand registers to the instruction.
-      for (unsigned i = 2; i != NumOps; i += 2) {
-        unsigned Flags =cast<ConstantSDNode>(Node->getOperand(i+1))->getValue();
-        switch (Flags) {
+      for (unsigned i = 2; i != NumOps;) {
+        unsigned Flags = cast<ConstantSDNode>(Node->getOperand(i))->getValue();
+        unsigned NumOps = Flags >> 3;
+        
+        MI->addZeroExtImm64Operand(NumOps);
+        ++i;  // Skip the ID value.
+        
+        switch (Flags & 7) {
         default: assert(0 && "Bad flags!");
-        case 1: { // Use of register.
-          unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
-          MI->addMachineRegOperand(Reg, MachineOperand::Use);
+        case 1:  // Use of register.
+          for (; NumOps; --NumOps, ++i) {
+            unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
+            MI->addMachineRegOperand(Reg, MachineOperand::Use);
+          }
           break;
-        }
-        case 2: { // Def of register.
-          unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
-          MI->addMachineRegOperand(Reg, MachineOperand::Def);
+        case 2:   // Def of register.
+          for (; NumOps; --NumOps, ++i) {
+            unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
+            MI->addMachineRegOperand(Reg, MachineOperand::Def);
+          }
           break;
-        }
         case 3: { // Immediate.
+          assert(NumOps == 1 && "Unknown immediate value!");
           uint64_t Val = cast<ConstantSDNode>(Node->getOperand(i))->getValue();
           MI->addZeroExtImm64Operand(Val);
+          ++i;
           break;
         }
         }


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.168 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.169
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.168	Wed Feb 22 17:09:03 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	Thu Feb 23 13:21:04 2006
@@ -113,6 +113,18 @@
     /// Chain/Flag as the input and updates them for the output Chain/Flag.
     SDOperand getCopyFromRegs(SelectionDAG &DAG,
                               SDOperand &Chain, SDOperand &Flag);
+
+    /// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
+    /// specified value into the registers specified by this object.  This uses 
+    /// Chain/Flag as the input and updates them for the output Chain/Flag.
+    void getCopyToRegs(SDOperand Val, SelectionDAG &DAG,
+                       SDOperand &Chain, SDOperand &Flag);
+    
+    /// AddInlineAsmOperands - Add this value to the specified inlineasm node
+    /// operand list.  This adds the code marker and includes the number of 
+    /// values added into it.
+    void AddInlineAsmOperands(unsigned Code, SelectionDAG &DAG,
+                              std::vector<SDOperand> &Ops);
   };
 }
 
@@ -1195,7 +1207,41 @@
     return DAG.getNode(ISD::FP_ROUND, ValueVT, Val);
 }
 
+/// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
+/// specified value into the registers specified by this object.  This uses 
+/// Chain/Flag as the input and updates them for the output Chain/Flag.
+void RegsForValue::getCopyToRegs(SDOperand Val, SelectionDAG &DAG,
+                                 SDOperand &Chain, SDOperand &Flag) {
+  if (Regs.size() == 1) {
+    // If there is a single register and the types differ, this must be
+    // a promotion.
+    if (RegVT != ValueVT) {
+      if (MVT::isInteger(RegVT))
+        Val = DAG.getNode(ISD::ANY_EXTEND, RegVT, Val);
+      else
+        Val = DAG.getNode(ISD::FP_EXTEND, RegVT, Val);
+    }
+    Chain = DAG.getCopyToReg(Chain, Regs[0], Val, Flag);
+    Flag = Chain.getValue(1);
+  } else {
+    for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+      SDOperand Part = DAG.getNode(ISD::EXTRACT_ELEMENT, RegVT, Val, 
+                                   DAG.getConstant(i, MVT::i32));
+      Chain = DAG.getCopyToReg(Chain, Regs[i], Part, Flag);
+      Flag = Chain.getValue(1);
+    }
+  }
+}
 
+/// AddInlineAsmOperands - Add this value to the specified inlineasm node
+/// operand list.  This adds the code marker and includes the number of 
+/// values added into it.
+void RegsForValue::AddInlineAsmOperands(unsigned Code, SelectionDAG &DAG,
+                                        std::vector<SDOperand> &Ops) {
+  Ops.push_back(DAG.getConstant(Code | (Regs.size() << 3), MVT::i32));
+  for (unsigned i = 0, e = Regs.size(); i != e; ++i)
+    Ops.push_back(DAG.getRegister(Regs[i], RegVT));
+}
 
 /// isAllocatableRegister - If the specified register is safe to allocate, 
 /// i.e. it isn't a stack pointer or some other special register, return the
@@ -1453,96 +1499,92 @@
       
       // Add information to the INLINEASM node to know that this register is
       // set.
-      
-      // FIXME:
-      // FIXME: Handle multiple regs here.
-      // FIXME:
-      unsigned DestReg = Regs.Regs[0];
-      AsmNodeOperands.push_back(DAG.getRegister(DestReg, Regs.RegVT));
-      AsmNodeOperands.push_back(DAG.getConstant(2, MVT::i32)); // ISDEF
+      Regs.AddInlineAsmOperands(2 /*REGDEF*/, DAG, AsmNodeOperands);
       break;
     }
     case InlineAsm::isInput: {
       Value *CallOperand = I.getOperand(OpNum);
       OpNum++;  // Consumes a call operand.
 
-      SDOperand ResOp;
-      unsigned ResOpType;
       SDOperand InOperandVal = getValue(CallOperand);
       
       if (isdigit(ConstraintCode[0])) {    // Matching constraint?
         // If this is required to match an output register we have already set,
         // just use its register.
         unsigned OperandNo = atoi(ConstraintCode.c_str());
-        unsigned SrcReg;
-        SrcReg = cast<RegisterSDNode>(AsmNodeOperands[OperandNo*2+2])->getReg();
-        ResOp = DAG.getRegister(SrcReg, ConstraintVTs[i]);
-        ResOpType = 1;
         
-        Chain = DAG.getCopyToReg(Chain, SrcReg, InOperandVal, Flag);
-        Flag = Chain.getValue(1);
+        // Scan until we find the definition we already emitted of this operand.
+        // When we find it, create a RegsForValue operand.
+        unsigned CurOp = 2;  // The first operand.
+        for (; OperandNo; --OperandNo) {
+          // Advance to the next operand.
+          unsigned NumOps = 
+            cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getValue();
+          assert((NumOps & 7) == 2 /*REGDEF*/ &&
+                 "Skipped past definitions?");
+          CurOp += (NumOps>>3)+1;
+        }
+
+        unsigned NumOps = 
+          cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getValue();
+        assert((NumOps & 7) == 2 /*REGDEF*/ &&
+               "Skipped past definitions?");
+        
+        // Add NumOps>>3 registers to MatchedRegs.
+        RegsForValue MatchedRegs;
+        MatchedRegs.ValueVT = InOperandVal.getValueType();
+        MatchedRegs.RegVT   = AsmNodeOperands[CurOp+1].getValueType();
+        for (unsigned i = 0, e = NumOps>>3; i != e; ++i) {
+          unsigned Reg=cast<RegisterSDNode>(AsmNodeOperands[++CurOp])->getReg();
+          MatchedRegs.Regs.push_back(Reg);
+        }
+        
+        // Use the produced MatchedRegs object to 
+        MatchedRegs.getCopyToRegs(InOperandVal, DAG, Chain, Flag);
+        MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, DAG, AsmNodeOperands);
       } else {
         TargetLowering::ConstraintType CTy = TargetLowering::C_RegisterClass;
         if (ConstraintCode.size() == 1)   // not a physreg name.
           CTy = TLI.getConstraintType(ConstraintCode[0]);
         
-        switch (CTy) {
-        default: assert(0 && "Unknown constraint type! FAIL!");
-        case TargetLowering::C_RegisterClass: {
-          // Copy the input into the appropriate registers.
-          RegsForValue InRegs =
-            GetRegistersForValue(ConstraintCode, ConstraintVTs[i],
-                                 false, true, OutputRegs, InputRegs);
-          // FIXME: should be match fail.
-          assert(!InRegs.Regs.empty() && "Couldn't allocate input reg!");
-
-          if (InRegs.Regs.size() == 1) {
-            // If there is a single register and the types differ, this must be
-            // a promotion.
-            if (InRegs.RegVT != InRegs.ValueVT) {
-              if (MVT::isInteger(InRegs.RegVT))
-                InOperandVal = DAG.getNode(ISD::ANY_EXTEND, InRegs.RegVT,
-                                           InOperandVal);
-              else
-                InOperandVal = DAG.getNode(ISD::FP_EXTEND, InRegs.RegVT,
-                                           InOperandVal);
-            }
-            Chain = DAG.getCopyToReg(Chain, InRegs.Regs[0], InOperandVal, Flag);
-            Flag = Chain.getValue(1);
-            
-            ResOp = DAG.getRegister(InRegs.Regs[0], InRegs.RegVT);
-          } else {
-            for (unsigned i = 0, e = InRegs.Regs.size(); i != e; ++i) {
-              SDOperand Part = DAG.getNode(ISD::EXTRACT_ELEMENT, InRegs.RegVT,
-                                           InOperandVal, 
-                                           DAG.getConstant(i, MVT::i32));
-              Chain = DAG.getCopyToReg(Chain, InRegs.Regs[i], Part, Flag);
-              Flag = Chain.getValue(1);
-            }
-            ResOp = DAG.getRegister(InRegs.Regs[0], InRegs.RegVT);
-          }
-          
-          ResOpType = 1;
-          break;
-        }
-        case TargetLowering::C_Other:
+        if (CTy == TargetLowering::C_Other) {
           if (!TLI.isOperandValidForConstraint(InOperandVal, ConstraintCode[0]))
             assert(0 && "MATCH FAIL!");
-          ResOp = InOperandVal;
-          ResOpType = 3;
+          
+          // Add information to the INLINEASM node to know about this input.
+          unsigned ResOpType = 3 /*imm*/ | (1 << 3);
+          AsmNodeOperands.push_back(DAG.getConstant(ResOpType, MVT::i32));
+          AsmNodeOperands.push_back(InOperandVal);
           break;
         }
+        
+        assert(CTy == TargetLowering::C_RegisterClass && "Unknown op type!");
+
+        // Copy the input into the appropriate registers.
+        RegsForValue InRegs =
+          GetRegistersForValue(ConstraintCode, ConstraintVTs[i],
+                               false, true, OutputRegs, InputRegs);
+        // FIXME: should be match fail.
+        assert(!InRegs.Regs.empty() && "Couldn't allocate input reg!");
+
+        InRegs.getCopyToRegs(InOperandVal, DAG, Chain, Flag);
+        
+        InRegs.AddInlineAsmOperands(1/*REGUSE*/, DAG, AsmNodeOperands);
+        break;
       }
-      
-      // Add information to the INLINEASM node to know about this input.
-      AsmNodeOperands.push_back(ResOp);
-      AsmNodeOperands.push_back(DAG.getConstant(ResOpType, MVT::i32));
       break;
     }
-    case InlineAsm::isClobber:
-      // Nothing to do.
+    case InlineAsm::isClobber: {
+      RegsForValue ClobberedRegs =
+        GetRegistersForValue(ConstraintCode, MVT::Other, false, false,
+                             OutputRegs, InputRegs);
+      // Add the clobbered value to the operand list, so that the register
+      // allocator is aware that the physreg got clobbered.
+      if (!ClobberedRegs.Regs.empty())
+        ClobberedRegs.AddInlineAsmOperands(2/*REGDEF*/, DAG, AsmNodeOperands);
       break;
     }
+    }
   }
   
   // Finish up input operands.






More information about the llvm-commits mailing list