[llvm-commits] [llvm] r67546 - in /llvm/branches/Apple/Dib: include/llvm/ include/llvm/CodeGen/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/CodeGen/SelectionDAG/ lib/Target/X86/ test/CodeGen/X86/

Bill Wendling isanbard at gmail.com
Mon Mar 23 11:36:07 PDT 2009


Author: void
Date: Mon Mar 23 13:36:00 2009
New Revision: 67546

URL: http://llvm.org/viewvc/llvm-project?rev=67546&view=rev
Log:
--- Merging (from foreign repository) r67387 into '.':
U    include/llvm/InlineAsm.h
U    lib/CodeGen/AsmPrinter/AsmPrinter.cpp
U    lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
U    lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
U    lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
U    lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
U    lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp

For inline asm output operand that matches an input. Encode the input operand
index in the high bits.

--- Merging (from foreign repository) r67335 into '.':
U    include/llvm/CodeGen/MachineInstr.h
G    lib/CodeGen/LiveIntervalAnalysis.cpp
U    lib/CodeGen/Spiller.cpp
U    lib/CodeGen/MachineInstr.cpp
U    lib/CodeGen/RegAllocLocal.cpp
U    lib/CodeGen/TwoAddressInstructionPass.cpp

Added MachineInstr::isRegTiedToDefOperand to check for two-addressness.

--- Merging (from foreign repository) r67512 into '.':
A    test/CodeGen/X86/inline-asm-2addr.ll
G    include/llvm/InlineAsm.h
U    lib/CodeGen/LiveIntervalAnalysis.cpp
A    test/CodeGen/X86/inline-asm-2addr.ll
G    lib/CodeGen/MachineInstr.cpp
G    lib/CodeGen/TwoAddressInstructionPass.cpp
G    lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
U    lib/Target/X86/X86FloatingPoint.cpp

Model inline asm constraint which ties an input to an output register as machine
operand TIED_TO constraint. This eliminated the need to pre-allocate registers
for these. This also allows register allocator can eliminate the unneeded
copies.

Added:
    llvm/branches/Apple/Dib/test/CodeGen/X86/inline-asm-2addr.ll
Modified:
    llvm/branches/Apple/Dib/include/llvm/CodeGen/MachineInstr.h
    llvm/branches/Apple/Dib/include/llvm/InlineAsm.h
    llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/LiveIntervalAnalysis.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/MachineInstr.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/RegAllocLocal.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/Spiller.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/TwoAddressInstructionPass.cpp
    llvm/branches/Apple/Dib/lib/Target/X86/X86FloatingPoint.cpp
    llvm/branches/Apple/Dib/test/CodeGen/X86/2008-02-20-InlineAsmClobber.ll
    llvm/branches/Apple/Dib/test/CodeGen/X86/2008-09-18-inline-asm-2.ll
    llvm/branches/Apple/Dib/test/CodeGen/X86/2008-12-19-EarlyClobberBug.ll

Modified: llvm/branches/Apple/Dib/include/llvm/CodeGen/MachineInstr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/CodeGen/MachineInstr.h?rev=67546&r1=67545&r2=67546&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/CodeGen/MachineInstr.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/CodeGen/MachineInstr.h Mon Mar 23 13:36:00 2009
@@ -245,6 +245,11 @@
   /// check if the register def is a re-definition due to two addr elimination.
   bool isRegReDefinedByTwoAddr(unsigned DefIdx) const;
 
+  /// isRegTiedToDefOperand - Return true if the use operand of the specified
+  /// index is tied to an def operand. It also returns the def operand index by
+  /// reference if DefOpIdx is not null.
+  bool isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx = 0);
+
   /// copyKillDeadInfo - Copies kill / dead operand properties from MI.
   ///
   void copyKillDeadInfo(const MachineInstr *MI);

Modified: llvm/branches/Apple/Dib/include/llvm/InlineAsm.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/InlineAsm.h?rev=67546&r1=67545&r2=67546&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/InlineAsm.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/InlineAsm.h Mon Mar 23 13:36:00 2009
@@ -128,6 +128,23 @@
   static inline bool classof(const Value *V) {
     return V->getValueID() == Value::InlineAsmVal;
   }
+
+  /// getNumOperandRegisters - Extract the number of registers field from the
+  /// inline asm operand flag.
+  static unsigned getNumOperandRegisters(unsigned Flag) {
+    return (Flag & 0xffff) >> 3;
+  }
+
+  /// isUseOperandTiedToDef - Return true if the flag of the inline asm
+  /// operand indicates it is an use operand that's matched to a def operand.
+  static bool isUseOperandTiedToDef(unsigned Flag, unsigned &Idx) {
+    if ((Flag & 0x80000000) == 0)
+      return false;
+    Idx = (Flag & ~0x80000000) >> 16;
+    return true;
+  }
+
+
 };
 
 } // End llvm namespace

Modified: llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=67546&r1=67545&r2=67546&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Mon Mar 23 13:36:00 2009
@@ -1401,7 +1401,7 @@
         for (; Val; --Val) {
           if (OpNo >= MI->getNumOperands()) break;
           unsigned OpFlags = MI->getOperand(OpNo).getImm();
-          OpNo += (OpFlags >> 3) + 1;
+          OpNo += InlineAsm::getNumOperandRegisters(OpFlags) + 1;
         }
 
         if (OpNo >= MI->getNumOperands()) {

Modified: llvm/branches/Apple/Dib/lib/CodeGen/LiveIntervalAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=67546&r1=67545&r2=67546&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/LiveIntervalAnalysis.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/LiveIntervalAnalysis.cpp Mon Mar 23 13:36:00 2009
@@ -477,8 +477,8 @@
       assert(interval.containsOneValue());
       unsigned DefIndex = getDefIndex(interval.getValNumInfo(0)->def);
       unsigned RedefIndex = getDefIndex(MIIdx);
-      // It cannot be an early clobber MO.
-      assert(!MO.isEarlyClobber() && "Unexpected early clobber!");
+      if (MO.isEarlyClobber())
+        RedefIndex = getUseIndex(MIIdx);
 
       const LiveRange *OldLR = interval.getLiveRangeContaining(RedefIndex-1);
       VNInfo *OldValNo = OldLR->valno;
@@ -499,6 +499,8 @@
       // Value#0 is now defined by the 2-addr instruction.
       OldValNo->def  = RedefIndex;
       OldValNo->copy = 0;
+      if (MO.isEarlyClobber())
+        OldValNo->redefByEC = true;
       
       // Add the new live interval which replaces the range for the input copy.
       LiveRange LR(DefIndex, RedefIndex, ValNo);
@@ -546,8 +548,8 @@
       // live until the end of the block.  We've already taken care of the
       // rest of the live range.
       unsigned defIndex = getDefIndex(MIIdx);
-      // It cannot be an early clobber MO.
-      assert(!MO.isEarlyClobber() && "Unexpected early clobber!");
+      if (MO.isEarlyClobber())
+        defIndex = getUseIndex(MIIdx);
       
       VNInfo *ValNo;
       MachineInstr *CopyMI = NULL;
@@ -1062,8 +1064,6 @@
                             SmallVector<unsigned, 2> &Ops,
                             unsigned &MRInfo,
                             SmallVector<unsigned, 2> &FoldOps) {
-  const TargetInstrDesc &TID = MI->getDesc();
-
   MRInfo = 0;
   for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
     unsigned OpIdx = Ops[i];
@@ -1075,8 +1075,7 @@
       MRInfo |= (unsigned)VirtRegMap::isMod;
     else {
       // Filter out two-address use operand(s).
-      if (!MO.isImplicit() &&
-          TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1) {
+      if (MI->isRegTiedToDefOperand(OpIdx)) {
         MRInfo = VirtRegMap::isModRef;
         continue;
       }
@@ -2160,8 +2159,7 @@
         MachineInstr *LastUse = getInstructionFromIndex(LastUseIdx);
         int UseIdx = LastUse->findRegisterUseOperandIdx(LI->reg, false);
         assert(UseIdx != -1);
-        if (LastUse->getOperand(UseIdx).isImplicit() ||
-            LastUse->getDesc().getOperandConstraint(UseIdx,TOI::TIED_TO) == -1){
+        if (!LastUse->isRegTiedToDefOperand(UseIdx)) {
           LastUse->getOperand(UseIdx).setIsKill();
           vrm.addKillPoint(LI->reg, LastUseIdx);
         }

Modified: llvm/branches/Apple/Dib/lib/CodeGen/MachineInstr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/MachineInstr.cpp?rev=67546&r1=67545&r2=67546&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/MachineInstr.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/MachineInstr.cpp Mon Mar 23 13:36:00 2009
@@ -11,8 +11,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Constants.h"
 #include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/Constants.h"
+#include "llvm/InlineAsm.h"
 #include "llvm/Value.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
@@ -689,9 +690,38 @@
   return -1;
 }
   
-/// isRegReDefinedByTwoAddr - Given the index of a register def operand,
+/// isRegReDefinedByTwoAddr - Given the index of a register operand,
 /// check if the register def is a re-definition due to two addr elimination.
 bool MachineInstr::isRegReDefinedByTwoAddr(unsigned DefIdx) const{
+  if (getOpcode() == TargetInstrInfo::INLINEASM) {
+    assert(DefIdx >= 2);
+    const MachineOperand &MO = getOperand(DefIdx);
+    if (!MO.isReg() || !MO.isDef())
+      return false;
+    // Determine the actual operand no corresponding to this index.
+    unsigned DefNo = 0;
+    for (unsigned i = 1, e = getNumOperands(); i < e; ) {
+      const MachineOperand &FMO = getOperand(i);
+      assert(FMO.isImm());
+      // Skip over this def.
+      i += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1;
+      if (i > DefIdx)
+        break;
+      ++DefNo;
+    }
+    for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+      const MachineOperand &FMO = getOperand(i);
+      if (!FMO.isImm())
+        continue;
+      if (i+1 >= e || !getOperand(i+1).isReg() || !getOperand(i+1).isUse())
+        continue;
+      unsigned Idx;
+      if (InlineAsm::isUseOperandTiedToDef(FMO.getImm(), Idx) && 
+          Idx == DefNo)
+        return true;
+    }
+  }
+
   assert(getOperand(DefIdx).isDef() && "DefIdx is not a def!");
   const TargetInstrDesc &TID = getDesc();
   for (unsigned i = 0, e = TID.getNumOperands(); i != e; ++i) {
@@ -703,6 +733,53 @@
   return false;
 }
 
+/// isRegTiedToDefOperand - Return true if the operand of the specified index
+/// is a register use and it is tied to an def operand. It also returns the def
+/// operand index by reference.
+bool MachineInstr::isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx){
+  if (getOpcode() == TargetInstrInfo::INLINEASM) {
+    const MachineOperand &MO = getOperand(UseOpIdx);
+    if (!MO.isReg() || !MO.isUse())
+      return false;
+    assert(UseOpIdx > 0);
+    const MachineOperand &UFMO = getOperand(UseOpIdx-1);
+    if (!UFMO.isImm())
+      return false;  // Must be physreg uses.
+    unsigned DefNo;
+    if (InlineAsm::isUseOperandTiedToDef(UFMO.getImm(), DefNo)) {
+      if (!DefOpIdx)
+        return true;
+
+      unsigned DefIdx = 1;
+      // Remember to adjust the index. First operand is asm string, then there
+      // is a flag for each.
+      while (DefNo) {
+        const MachineOperand &FMO = getOperand(DefIdx);
+        assert(FMO.isImm());
+        // Skip over this def.
+        DefIdx += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1;
+        --DefNo;
+      }
+      *DefOpIdx = DefIdx+1;
+      return true;
+    }
+    return false;
+  }
+
+  const TargetInstrDesc &TID = getDesc();
+  if (UseOpIdx >= TID.getNumOperands())
+    return false;
+  const MachineOperand &MO = getOperand(UseOpIdx);
+  if (!MO.isReg() || !MO.isUse())
+    return false;
+  int DefIdx = TID.getOperandConstraint(UseOpIdx, TOI::TIED_TO);
+  if (DefIdx == -1)
+    return false;
+  if (DefOpIdx)
+    *DefOpIdx = (unsigned)DefIdx;
+  return true;
+}
+
 /// copyKillDeadInfo - Copies kill / dead operand properties from MI.
 ///
 void MachineInstr::copyKillDeadInfo(const MachineInstr *MI) {

Modified: llvm/branches/Apple/Dib/lib/CodeGen/RegAllocLocal.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/RegAllocLocal.cpp?rev=67546&r1=67545&r2=67546&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/RegAllocLocal.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/RegAllocLocal.cpp Mon Mar 23 13:36:00 2009
@@ -695,7 +695,7 @@
     if (isPhysReg || !usedOutsideBlock) {
       if (MO.isUse()) {
         // Don't mark uses that are tied to defs as kills.
-        if (MI->getDesc().getOperandConstraint(idx, TOI::TIED_TO) == -1)
+        if (!MI->isRegTiedToDefOperand(idx))
           MO.setIsKill(true);
       } else
         MO.setIsDead(true);

Modified: llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=67546&r1=67545&r2=67546&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Mar 23 13:36:00 2009
@@ -1974,7 +1974,8 @@
 
     bool HasInFlag = Ops.back().getValueType() == MVT::Flag;
     for (unsigned i = 2, e = Ops.size()-HasInFlag; i < e; ) {
-      unsigned NumVals = cast<ConstantSDNode>(Ops[i])->getZExtValue() >> 3;
+      unsigned NumVals = InlineAsm::
+        getNumOperandRegisters(cast<ConstantSDNode>(Ops[i])->getZExtValue());
       for (++i; NumVals; ++i, --NumVals) {
         SDValue Op = LegalizeOp(Ops[i]);
         if (Op != Ops[i]) {

Modified: llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=67546&r1=67545&r2=67546&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Mon Mar 23 13:36:00 2009
@@ -632,7 +632,7 @@
       for (unsigned i = 2; i != NumOps;) {
         unsigned Flags =
           cast<ConstantSDNode>(Node->getOperand(i))->getZExtValue();
-        unsigned NumVals = Flags >> 3;
+        unsigned NumVals = (Flags & 0xffff) >> 3;
 
         ++i; // Skip the ID value.
         if ((Flags & 7) == 2 || (Flags & 7) == 6) {

Modified: llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp?rev=67546&r1=67545&r2=67546&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp Mon Mar 23 13:36:00 2009
@@ -561,7 +561,7 @@
     for (unsigned i = 2; i != NumOps;) {
       unsigned Flags =
         cast<ConstantSDNode>(Node->getOperand(i))->getZExtValue();
-      unsigned NumVals = Flags >> 3;
+      unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
         
       MI->addOperand(MachineOperand::CreateImm(Flags));
       ++i;  // Skip the ID value.

Modified: llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=67546&r1=67545&r2=67546&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Mon Mar 23 13:36:00 2009
@@ -228,10 +228,11 @@
                        SDValue &Chain, SDValue *Flag) const;
 
     /// 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<SDValue> &Ops) const;
+    /// operand list.  This adds the code marker, matching input operand index
+    /// (if applicable), and includes the number of values added into it.
+    void AddInlineAsmOperands(unsigned Code,
+                              bool HasMatching, unsigned MatchingIdx,
+                              SelectionDAG &DAG, std::vector<SDValue> &Ops) const;
   };
 }
 
@@ -4659,10 +4660,16 @@
 /// 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,
+void RegsForValue::AddInlineAsmOperands(unsigned Code,
+                                        bool HasMatching,unsigned MatchingIdx,
+                                        SelectionDAG &DAG,
                                         std::vector<SDValue> &Ops) const {
   MVT IntPtrTy = DAG.getTargetLoweringInfo().getPointerTy();
-  Ops.push_back(DAG.getTargetConstant(Code | (Regs.size() << 3), IntPtrTy));
+  assert(Regs.size() < (1 << 13) && "Too many inline asm outputs!");
+  unsigned Flag = Code | (Regs.size() << 3);
+  if (HasMatching)
+    Flag |= 0x80000000 | (MatchingIdx << 16);
+  Ops.push_back(DAG.getTargetConstant(Flag, IntPtrTy));
   for (unsigned Value = 0, Reg = 0, e = ValueVTs.size(); Value != e; ++Value) {
     unsigned NumRegs = TLI->getNumRegisters(ValueVTs[Value]);
     MVT RegisterVT = RegVTs[Value];
@@ -4925,28 +4932,17 @@
   std::vector<unsigned> RegClassRegs;
   const TargetRegisterClass *RC = PhysReg.second;
   if (RC) {
-    // If this is a tied register, our regalloc doesn't know how to maintain
-    // the constraint, so we have to pick a register to pin the input/output to.
-    // If it isn't a matched constraint, go ahead and create vreg and let the
-    // regalloc do its thing.
-    if (!OpInfo.hasMatchingInput()) {
-      RegVT = *PhysReg.second->vt_begin();
-      if (OpInfo.ConstraintVT == MVT::Other)
-        ValueVT = RegVT;
-
-      // Create the appropriate number of virtual registers.
-      MachineRegisterInfo &RegInfo = MF.getRegInfo();
-      for (; NumRegs; --NumRegs)
-        Regs.push_back(RegInfo.createVirtualRegister(PhysReg.second));
-
-      OpInfo.AssignedRegs = RegsForValue(TLI, Regs, RegVT, ValueVT);
-      return;
-    }
+    RegVT = *PhysReg.second->vt_begin();
+    if (OpInfo.ConstraintVT == MVT::Other)
+      ValueVT = RegVT;
 
-    // Otherwise, we can't allocate it.  Let the code below figure out how to
-    // maintain these constraints.
-    RegClassRegs.assign(PhysReg.second->begin(), PhysReg.second->end());
+    // Create the appropriate number of virtual registers.
+    MachineRegisterInfo &RegInfo = MF.getRegInfo();
+    for (; NumRegs; --NumRegs)
+      Regs.push_back(RegInfo.createVirtualRegister(PhysReg.second));
 
+    OpInfo.AssignedRegs = RegsForValue(TLI, Regs, RegVT, ValueVT);
+    return;
   } else {
     // This is a reference to a register class that doesn't directly correspond
     // to an LLVM register class.  Allocate NumRegs consecutive, available,
@@ -5230,6 +5226,8 @@
       OpInfo.AssignedRegs.AddInlineAsmOperands(OpInfo.isEarlyClobber ?
                                                6 /* EARLYCLOBBER REGDEF */ :
                                                2 /* REGDEF */ ,
+                                               false,
+                                               0,
                                                DAG, AsmNodeOperands);
       break;
     }
@@ -5246,40 +5244,46 @@
         unsigned CurOp = 2;  // The first operand.
         for (; OperandNo; --OperandNo) {
           // Advance to the next operand.
-          unsigned NumOps =
+          unsigned OpFlag =
             cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue();
-          assert(((NumOps & 7) == 2 /*REGDEF*/ ||
-                  (NumOps & 7) == 6 /*EARLYCLOBBER REGDEF*/ ||
-                  (NumOps & 7) == 4 /*MEM*/) &&
+          assert(((OpFlag & 7) == 2 /*REGDEF*/ ||
+                  (OpFlag & 7) == 6 /*EARLYCLOBBER REGDEF*/ ||
+                  (OpFlag & 7) == 4 /*MEM*/) &&
                  "Skipped past definitions?");
-          CurOp += (NumOps>>3)+1;
+          CurOp += InlineAsm::getNumOperandRegisters(OpFlag)+1;
         }
 
-        unsigned NumOps =
+        unsigned OpFlag =
           cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue();
-        if ((NumOps & 7) == 2 /*REGDEF*/
-            || (NumOps & 7) == 6 /* EARLYCLOBBER REGDEF */) {
-          // Add NumOps>>3 registers to MatchedRegs.
+        if ((OpFlag & 7) == 2 /*REGDEF*/
+            || (OpFlag & 7) == 6 /* EARLYCLOBBER REGDEF */) {
+          // Add (OpFlag&0xffff)>>3 registers to MatchedRegs.
           RegsForValue MatchedRegs;
           MatchedRegs.TLI = &TLI;
           MatchedRegs.ValueVTs.push_back(InOperandVal.getValueType());
-          MatchedRegs.RegVTs.push_back(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);
-          }
+          MVT RegVT = AsmNodeOperands[CurOp+1].getValueType();
+          MatchedRegs.RegVTs.push_back(RegVT);
+          MachineRegisterInfo &RegInfo = DAG.getMachineFunction().getRegInfo();
+          for (unsigned i = 0, e = InlineAsm::getNumOperandRegisters(OpFlag);
+               i != e; ++i)
+            MatchedRegs.Regs.
+              push_back(RegInfo.createVirtualRegister(TLI.getRegClassFor(RegVT)));
 
           // Use the produced MatchedRegs object to
           MatchedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(),
                                     Chain, &Flag);
-          MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, DAG, AsmNodeOperands);
+          MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/,
+                                           true, OpInfo.getMatchedOperand(),
+                                           DAG, AsmNodeOperands);
           break;
         } else {
-          assert(((NumOps & 7) == 4) && "Unknown matching constraint!");
-          assert((NumOps >> 3) == 1 && "Unexpected number of operands");
+          assert(((OpFlag & 7) == 4) && "Unknown matching constraint!");
+          assert((InlineAsm::getNumOperandRegisters(OpFlag)) == 1 &&
+                 "Unexpected number of operands");
           // Add information to the INLINEASM node to know about this input.
-          AsmNodeOperands.push_back(DAG.getTargetConstant(NumOps,
+          // See InlineAsm.h isUseOperandTiedToDef.
+          OpFlag |= 0x80000000 | (OpInfo.getMatchedOperand() << 16);
+          AsmNodeOperands.push_back(DAG.getTargetConstant(OpFlag,
                                                           TLI.getPointerTy()));
           AsmNodeOperands.push_back(AsmNodeOperands[CurOp+1]);
           break;
@@ -5334,7 +5338,7 @@
       OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(),
                                         Chain, &Flag);
 
-      OpInfo.AssignedRegs.AddInlineAsmOperands(1/*REGUSE*/,
+      OpInfo.AssignedRegs.AddInlineAsmOperands(1/*REGUSE*/, false, 0,
                                                DAG, AsmNodeOperands);
       break;
     }
@@ -5343,7 +5347,7 @@
       // allocator is aware that the physreg got clobbered.
       if (!OpInfo.AssignedRegs.Regs.empty())
         OpInfo.AssignedRegs.AddInlineAsmOperands(6 /* EARLYCLOBBER REGDEF */,
-                                                 DAG, AsmNodeOperands);
+                                                 false, 0, DAG,AsmNodeOperands);
       break;
     }
     }

Modified: llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=67546&r1=67545&r2=67546&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Mar 23 13:36:00 2009
@@ -1168,10 +1168,12 @@
     unsigned Flags = cast<ConstantSDNode>(InOps[i])->getZExtValue();
     if ((Flags & 7) != 4 /*MEM*/) {
       // Just skip over this operand, copying the operands verbatim.
-      Ops.insert(Ops.end(), InOps.begin()+i, InOps.begin()+i+(Flags >> 3) + 1);
-      i += (Flags >> 3) + 1;
+      Ops.insert(Ops.end(), InOps.begin()+i,
+                 InOps.begin()+i+InlineAsm::getNumOperandRegisters(Flags) + 1);
+      i += InlineAsm::getNumOperandRegisters(Flags) + 1;
     } else {
-      assert((Flags >> 3) == 1 && "Memory operand with multiple values?");
+      assert(InlineAsm::getNumOperandRegisters(Flags) == 1 &&
+             "Memory operand with multiple values?");
       // Otherwise, this is a memory operand.  Ask the target to select it.
       std::vector<SDValue> SelOps;
       if (SelectInlineAsmMemoryOperand(InOps[i+1], 'm', SelOps)) {

Modified: llvm/branches/Apple/Dib/lib/CodeGen/Spiller.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/Spiller.cpp?rev=67546&r1=67545&r2=67546&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/Spiller.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/Spiller.cpp Mon Mar 23 13:36:00 2009
@@ -233,8 +233,7 @@
       KillOps[Reg]->setIsKill(false);
       KillOps[Reg] = NULL;
       RegKills.reset(Reg);
-      if (i < TID.getNumOperands() &&
-          TID.getOperandConstraint(i, TOI::TIED_TO) == -1)
+      if (!MI.isRegTiedToDefOperand(i))
         // Unless it's a two-address operand, this is the new kill.
         MO.setIsKill();
     }
@@ -748,8 +747,8 @@
     int UseIdx = DefMI->findRegisterUseOperandIdx(DestReg, false);
     if (UseIdx == -1)
       return false;
-    int DefIdx = TID.getOperandConstraint(UseIdx, TOI::TIED_TO);
-    if (DefIdx == -1)
+    unsigned DefIdx;
+    if (!MI.isRegTiedToDefOperand(UseIdx, &DefIdx))
       return false;
     assert(DefMI->getOperand(DefIdx).isReg() &&
            DefMI->getOperand(DefIdx).getReg() == SrcReg);
@@ -890,7 +889,7 @@
         continue;
       if (!LastUD || (LastUD->isUse() && MO.isDef()))
         LastUD = &MO;
-      if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1)
+      if (LastUDMI->isRegTiedToDefOperand(i))
         return;
     }
     if (LastUD->isDef())
@@ -1168,8 +1167,8 @@
         // aren't allowed to modify the reused register.  If none of these cases
         // apply, reuse it.
         bool CanReuse = true;
-        int ti = TID.getOperandConstraint(i, TOI::TIED_TO);
-        if (ti != -1) {
+        bool isTied = MI.isRegTiedToDefOperand(i);
+        if (isTied) {
           // Okay, we have a two address operand.  We can reuse this physreg as
           // long as we are allowed to clobber the value and there isn't an
           // earlier def that has already clobbered the physreg.
@@ -1206,7 +1205,7 @@
           // we can get at R0 or its alias.
           ReusedOperands.addReuse(i, ReuseSlot, PhysReg,
                                   VRM.getPhys(VirtReg), VirtReg);
-          if (ti != -1)
+          if (isTied)
             // Only mark it clobbered if this is a use&def operand.
             ReusedOperands.markClobbered(PhysReg);
           ++NumReused;
@@ -1226,7 +1225,7 @@
           // Mark is isKill if it's there no other uses of the same virtual
           // register and it's not a two-address operand. IsKill will be
           // unset if reg is reused.
-          if (ti == -1 && KilledMIRegs.count(VirtReg) == 0) {
+          if (!isTied && KilledMIRegs.count(VirtReg) == 0) {
             MI.getOperand(i).setIsKill();
             KilledMIRegs.insert(VirtReg);
           }
@@ -1325,7 +1324,7 @@
       Spills.addAvailable(SSorRMId, PhysReg);
       // Assumes this is the last use. IsKill will be unset if reg is reused
       // unless it's a two-address operand.
-      if (TID.getOperandConstraint(i, TOI::TIED_TO) == -1 &&
+      if (!MI.isRegTiedToDefOperand(i) &&
           KilledMIRegs.count(VirtReg) == 0) {
         MI.getOperand(i).setIsKill();
         KilledMIRegs.insert(VirtReg);

Modified: llvm/branches/Apple/Dib/lib/CodeGen/TwoAddressInstructionPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/TwoAddressInstructionPass.cpp?rev=67546&r1=67545&r2=67546&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/TwoAddressInstructionPass.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/TwoAddressInstructionPass.cpp Mon Mar 23 13:36:00 2009
@@ -234,7 +234,7 @@
   for (unsigned i = 0, e = TID.getNumOperands(); i != e; ++i) {
     MachineOperand &MO = UseMI->getOperand(i);
     if (MO.isReg() && MO.getReg() == Reg &&
-        (MO.isDef() || TID.getOperandConstraint(i, TOI::TIED_TO) != -1))
+        (MO.isDef() || UseMI->isRegTiedToDefOperand(i)))
       // Earlier use is a two-address one.
       return true;
   }
@@ -338,8 +338,8 @@
     const MachineOperand &MO = MI.getOperand(i);
     if (!MO.isReg() || !MO.isUse() || MO.getReg() != Reg)
       continue;
-    int ti = TID.getOperandConstraint(i, TOI::TIED_TO);
-    if (ti != -1) {
+    unsigned ti;
+    if (MI.isRegTiedToDefOperand(i, &ti)) {
       DstReg = MI.getOperand(ti).getReg();
       return true;
     }
@@ -634,9 +634,11 @@
 
       ProcessCopy(&*mi, &*mbbi, Processed);
 
-      for (unsigned si = 1, e = TID.getNumOperands(); si < e; ++si) {
-        int ti = TID.getOperandConstraint(si, TOI::TIED_TO);
-        if (ti == -1)
+      unsigned NumOps = (mi->getOpcode() == TargetInstrInfo::INLINEASM)
+        ? mi->getNumOperands() : TID.getNumOperands();
+      for (unsigned si = 0; si < NumOps; ++si) {
+        unsigned ti = 0;
+        if (!mi->isRegTiedToDefOperand(si, &ti))
           continue;
 
         if (FirstTied) {
@@ -660,8 +662,7 @@
           unsigned regA = mi->getOperand(ti).getReg();
           unsigned regB = mi->getOperand(si).getReg();
 
-          assert(TargetRegisterInfo::isVirtualRegister(regA) &&
-                 TargetRegisterInfo::isVirtualRegister(regB) &&
+          assert(TargetRegisterInfo::isVirtualRegister(regB) &&
                  "cannot update physical register live information");
 
 #ifndef NDEBUG
@@ -669,7 +670,7 @@
           // b + a for example) because our transformation will not work. This
           // should never occur because we are in SSA form.
           for (unsigned i = 0; i != mi->getNumOperands(); ++i)
-            assert((int)i == ti ||
+            assert(i == ti ||
                    !mi->getOperand(i).isReg() ||
                    mi->getOperand(i).getReg() != regA);
 #endif
@@ -753,7 +754,7 @@
           }
 
         InstructionRearranged:
-          const TargetRegisterClass* rc = MRI->getRegClass(regA);
+          const TargetRegisterClass* rc = MRI->getRegClass(regB);
           MachineInstr *DefMI = MRI->getVRegDef(regB);
           // If it's safe and profitable, remat the definition instead of
           // copying it.

Modified: llvm/branches/Apple/Dib/lib/Target/X86/X86FloatingPoint.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Target/X86/X86FloatingPoint.cpp?rev=67546&r1=67545&r2=67546&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/Target/X86/X86FloatingPoint.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Target/X86/X86FloatingPoint.cpp Mon Mar 23 13:36:00 2009
@@ -1017,9 +1017,37 @@
   case X86::MOV_Fp8032:
   case X86::MOV_Fp8064: 
   case X86::MOV_Fp8080: {
-    unsigned SrcReg = getFPReg(MI->getOperand(1));
-    unsigned DestReg = getFPReg(MI->getOperand(0));
+    const MachineOperand &MO1 = MI->getOperand(1);
+    unsigned SrcReg = getFPReg(MO1);
 
+    const MachineOperand &MO0 = MI->getOperand(0);
+    // These can be created due to inline asm. Two address pass can introduce
+    // copies from RFP registers to virtual registers.
+    if (MO0.getReg() == X86::ST0 && SrcReg == 0) {
+      assert(MO1.isKill());
+      // Treat %ST0<def> = MOV_Fp8080 %FP0<kill>
+      // like  FpSET_ST0_80 %FP0<kill>, %ST0<imp-def>
+      assert((StackTop == 1 || StackTop == 2)
+             && "Stack should have one or two element on it to return!");
+      --StackTop;   // "Forget" we have something on the top of stack!
+      break;
+    } else if (MO0.getReg() == X86::ST1 && SrcReg == 1) {
+      assert(MO1.isKill());
+      // Treat %ST1<def> = MOV_Fp8080 %FP1<kill>
+      // like  FpSET_ST1_80 %FP0<kill>, %ST1<imp-def>
+      // StackTop can be 1 if a FpSET_ST0_* was before this. Exchange them.
+      if (StackTop == 1) {
+        BuildMI(*MBB, I, dl, TII->get(X86::XCH_F)).addReg(X86::ST1);
+        NumFXCH++;
+        StackTop = 0;
+        break;
+      }
+      assert(StackTop == 2 && "Stack should have two element on it to return!");
+      --StackTop;   // "Forget" we have something on the top of stack!
+      break;
+    }
+
+    unsigned DestReg = getFPReg(MO0);
     if (MI->killsRegister(X86::FP0+SrcReg)) {
       // If the input operand is killed, we can just change the owner of the
       // incoming stack slot into the result.

Modified: llvm/branches/Apple/Dib/test/CodeGen/X86/2008-02-20-InlineAsmClobber.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/test/CodeGen/X86/2008-02-20-InlineAsmClobber.ll?rev=67546&r1=67545&r2=67546&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/test/CodeGen/X86/2008-02-20-InlineAsmClobber.ll (original)
+++ llvm/branches/Apple/Dib/test/CodeGen/X86/2008-02-20-InlineAsmClobber.ll Mon Mar 23 13:36:00 2009
@@ -1,5 +1,5 @@
-; RUN: llvm-as < %s | llc | grep {a: %ecx %ecx}
-; RUN: llvm-as < %s | llc | grep {b: %ecx %edx %ecx}
+; RUN: llvm-as < %s | llc | grep {a:} | not grep ax
+; RUN: llvm-as < %s | llc | grep {b:} | not grep ax
 ; PR2078
 ; The clobber list says that "ax" is clobbered.  Make sure that eax isn't 
 ; allocated to the input/output register.

Modified: llvm/branches/Apple/Dib/test/CodeGen/X86/2008-09-18-inline-asm-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/test/CodeGen/X86/2008-09-18-inline-asm-2.ll?rev=67546&r1=67545&r2=67546&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/test/CodeGen/X86/2008-09-18-inline-asm-2.ll (original)
+++ llvm/branches/Apple/Dib/test/CodeGen/X86/2008-09-18-inline-asm-2.ll Mon Mar 23 13:36:00 2009
@@ -1,5 +1,5 @@
-; RUN: llvm-as < %s | llc -march=x86 | grep "#%ebp %eax %edx 8(%esi) %ebx (%edi)"
-; RUN: llvm-as < %s | llc -march=x86 -regalloc=local | grep "#%ecx %eax %edx 8(%edi) %ebx (%esi)"
+; RUN: llvm-as < %s | llc -march=x86 | grep "#%ebp %edi %esi 8(%edx) %eax (%ebx)"
+; RUN: llvm-as < %s | llc -march=x86 -regalloc=local | grep "#%edi %edx %ebp 8(%ebx) %eax (%esi)"
 ; The 1st, 2nd, 3rd and 5th registers above must all be different.  The registers
 ; referenced in the 4th and 6th operands must not be the same as the 1st or 5th
 ; operand.  There are many combinations that work; this is what llc puts out now.

Modified: llvm/branches/Apple/Dib/test/CodeGen/X86/2008-12-19-EarlyClobberBug.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/test/CodeGen/X86/2008-12-19-EarlyClobberBug.ll?rev=67546&r1=67545&r2=67546&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/test/CodeGen/X86/2008-12-19-EarlyClobberBug.ll (original)
+++ llvm/branches/Apple/Dib/test/CodeGen/X86/2008-12-19-EarlyClobberBug.ll Mon Mar 23 13:36:00 2009
@@ -1,5 +1,6 @@
-; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin | %prcontext End 1 | grep {movl.*%ecx}
+; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin | %prcontext End 2 | grep mov
 ; PR3149
+; Make sure the copy after inline asm is not coalesced away.
 
 @"\01LC" = internal constant [7 x i8] c"n0=%d\0A\00"		; <[7 x i8]*> [#uses=1]
 @llvm.used = appending global [1 x i8*] [ i8* bitcast (i32 (i64, i64)* @umoddi3 to i8*) ], section "llvm.metadata"		; <[1 x i8*]*> [#uses=0]

Added: llvm/branches/Apple/Dib/test/CodeGen/X86/inline-asm-2addr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/test/CodeGen/X86/inline-asm-2addr.ll?rev=67546&view=auto

==============================================================================
--- llvm/branches/Apple/Dib/test/CodeGen/X86/inline-asm-2addr.ll (added)
+++ llvm/branches/Apple/Dib/test/CodeGen/X86/inline-asm-2addr.ll Mon Mar 23 13:36:00 2009
@@ -0,0 +1,9 @@
+; RUN: llvm-as < %s | llc -march=x86-64 | grep movq | count 1
+
+define i64 @t(i64 %a, i64 %b) nounwind ssp {
+entry:
+	%asmtmp = tail call i64 asm "rorq $1,$0", "=r,J,0,~{dirflag},~{fpsr},~{flags},~{cc}"(i32 1, i64 %a) nounwind		; <i64> [#uses=1]
+	%asmtmp1 = tail call i64 asm "rorq $1,$0", "=r,J,0,~{dirflag},~{fpsr},~{flags},~{cc}"(i32 1, i64 %b) nounwind		; <i64> [#uses=1]
+	%0 = add i64 %asmtmp1, %asmtmp		; <i64> [#uses=1]
+	ret i64 %0
+}





More information about the llvm-commits mailing list