[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp

Chris Lattner sabre at nondot.org
Mon Feb 26 20:18:31 PST 2007



Changes in directory llvm/lib/Target/X86:

X86ISelLowering.cpp updated: 1.341 -> 1.342
---
Log message:

refactor x86-64 argument lowering yet again, this time eliminating templates,
'clients', etc, and adding CCValAssign instead.



---
Diffs of the changes:  (+179 -166)

 X86ISelLowering.cpp |  345 ++++++++++++++++++++++++++--------------------------
 1 files changed, 179 insertions(+), 166 deletions(-)


Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.341 llvm/lib/Target/X86/X86ISelLowering.cpp:1.342
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.341	Mon Feb 26 01:59:53 2007
+++ llvm/lib/Target/X86/X86ISelLowering.cpp	Mon Feb 26 22:18:15 2007
@@ -1061,7 +1061,7 @@
 class CallingConvState {
   unsigned StackOffset;
   const MRegisterInfo &MRI;
-  SmallVector<uint32_t, 32> UsedRegs;
+  SmallVector<uint32_t, 16> UsedRegs;
 public:
   CallingConvState(const MRegisterInfo &mri) : MRI(mri) {
     // No stack is used.
@@ -1119,19 +1119,88 @@
   }
 };
 
+/// CCValAssign - Represent assignment of one arg/retval to a location.
+class CCValAssign {
+public:
+  enum LocInfo {
+    Full,   // The value fills the full location.
+    SExt,   // The value is sign extended in the location.
+    ZExt,   // The value is zero extended in the location.
+    AExt    // The value is extended with undefined upper bits.
+    // TODO: a subset of the value is in the location.
+  };
+private:
+  /// ValNo - This is the value number begin assigned (e.g. an argument number).
+  unsigned ValNo;
+  
+  /// Loc is either a stack offset or a register number.
+  unsigned Loc;
+  
+  /// isMem - True if this is a memory loc, false if it is a register loc.
+  bool isMem : 1;
+  
+  /// Information about how the value is assigned.
+  LocInfo HTP : 7;
+  
+  /// ValVT - The type of the value being assigned.
+  MVT::ValueType ValVT : 8;
+
+  /// LocVT - The type of the location being assigned to.
+  MVT::ValueType LocVT : 8;
+public:
+    
+  static CCValAssign getReg(unsigned ValNo, MVT::ValueType ValVT,
+                            unsigned RegNo, MVT::ValueType LocVT,
+                            LocInfo HTP) {
+    CCValAssign Ret;
+    Ret.ValNo = ValNo;
+    Ret.Loc = RegNo;
+    Ret.isMem = false;
+    Ret.HTP = HTP;
+    Ret.ValVT = ValVT;
+    Ret.LocVT = LocVT;
+    return Ret;
+  }
+  static CCValAssign getMem(unsigned ValNo, MVT::ValueType ValVT,
+                            unsigned Offset, MVT::ValueType LocVT,
+                            LocInfo HTP) {
+    CCValAssign Ret;
+    Ret.ValNo = ValNo;
+    Ret.Loc = Offset;
+    Ret.isMem = true;
+    Ret.HTP = HTP;
+    Ret.ValVT = ValVT;
+    Ret.LocVT = LocVT;
+    return Ret;
+  }
+  
+  unsigned getValNo() const { return ValNo; }
+  MVT::ValueType getValVT() const { return ValVT; }
+
+  bool isRegLoc() const { return !isMem; }
+  bool isMemLoc() const { return isMem; }
+  
+  unsigned getLocReg() const { assert(isRegLoc()); return Loc; }
+  unsigned getLocMemOffset() const { assert(isMemLoc()); return Loc; }
+  MVT::ValueType getLocVT() const { return LocVT; }
+  
+  LocInfo getLocInfo() const { return HTP; }
+};
+
+
 /// X86_64_CCC_AssignArgument - Implement the X86-64 C Calling Convention.
-template<typename Client, typename DataTy>
-static void X86_64_CCC_AssignArgument(Client &C, CallingConvState &State,
+static void X86_64_CCC_AssignArgument(unsigned ValNo,
                                       MVT::ValueType ArgVT, unsigned ArgFlags,
-                                      DataTy Data) {
+                                      CallingConvState &State,
+                                      SmallVector<CCValAssign, 16> &Locs) {
   MVT::ValueType LocVT = ArgVT;
-  unsigned ExtendType = ISD::ANY_EXTEND;
+  CCValAssign::LocInfo LocInfo = CCValAssign::Full;
   
   // Promote the integer to 32 bits.  If the input type is signed use a
   // sign extend, otherwise use a zero extend.
   if (ArgVT == MVT::i8 || ArgVT == MVT::i16) {
     LocVT = MVT::i32;
-    ExtendType = (ArgFlags & 1) ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
+    LocInfo = (ArgFlags & 1) ? CCValAssign::SExt : CCValAssign::ZExt;
   }
   
   // If this is a 32-bit value, assign to a 32-bit register if any are
@@ -1141,7 +1210,7 @@
       X86::EDI, X86::ESI, X86::EDX, X86::ECX, X86::R8D, X86::R9D
     };
     if (unsigned Reg = State.AllocateReg(GPR32ArgRegs, 6)) {
-      C.AssignToReg(Data, Reg, ArgVT, LocVT, ExtendType);
+      Locs.push_back(CCValAssign::getReg(ValNo, ArgVT, Reg, LocVT, LocInfo));
       return;
     }
   }
@@ -1153,7 +1222,7 @@
       X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8, X86::R9
     };
     if (unsigned Reg = State.AllocateReg(GPR64ArgRegs, 6)) {
-      C.AssignToReg(Data, Reg, ArgVT, LocVT, ExtendType);
+      Locs.push_back(CCValAssign::getReg(ValNo, ArgVT, Reg, LocVT, LocInfo));
       return;
     }
   }
@@ -1166,7 +1235,7 @@
       X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
     };
     if (unsigned Reg = State.AllocateReg(XMMArgRegs, 8)) {
-      C.AssignToReg(Data, Reg, ArgVT, LocVT, ExtendType);
+      Locs.push_back(CCValAssign::getReg(ValNo, ArgVT, Reg, LocVT, LocInfo));
       return;
     }
   }
@@ -1176,144 +1245,19 @@
   if (LocVT == MVT::i32 || LocVT == MVT::i64 ||
       LocVT == MVT::f32 || LocVT == MVT::f64) {
     unsigned Offset = State.AllocateStack(8, 8);
-    C.AssignToStack(Data, Offset, ArgVT, LocVT, ExtendType);
+    Locs.push_back(CCValAssign::getMem(ValNo, ArgVT, Offset, LocVT, LocInfo));
     return;
   }
   
   // Vectors get 16-byte stack slots that are 16-byte aligned.
   if (MVT::isVector(LocVT)) {
     unsigned Offset = State.AllocateStack(16, 16);
-    C.AssignToStack(Data, Offset, ArgVT, LocVT, ExtendType);
+    Locs.push_back(CCValAssign::getMem(ValNo, ArgVT, Offset, LocVT, LocInfo));
     return;
   }
   assert(0 && "Unknown argument type!");
 }
 
-class LowerArgumentsClient {
-  SelectionDAG &DAG;
-  X86TargetLowering &TLI;
-  SmallVector<SDOperand, 8> &ArgValues;
-  SDOperand Chain;
-public:
-  LowerArgumentsClient(SelectionDAG &dag, X86TargetLowering &tli,
-                       SmallVector<SDOperand, 8> &argvalues,
-                       SDOperand chain)
-    : DAG(dag), TLI(tli), ArgValues(argvalues), Chain(chain) {
-      
-  }
-  
-  void AssignToReg(SDOperand Arg, unsigned RegNo,
-                   MVT::ValueType ArgVT, MVT::ValueType RegVT,
-                   unsigned ExtendType) {
-    TargetRegisterClass *RC = NULL;
-    if (RegVT == MVT::i32)
-      RC = X86::GR32RegisterClass;
-    else if (RegVT == MVT::i64)
-      RC = X86::GR64RegisterClass;
-    else if (RegVT == MVT::f32)
-      RC = X86::FR32RegisterClass;
-    else if (RegVT == MVT::f64)
-      RC = X86::FR64RegisterClass;
-    else {
-      RC = X86::VR128RegisterClass;
-    }
-      
-    SDOperand ArgValue = DAG.getCopyFromReg(Chain, RegNo, RegVT);
-    AddLiveIn(DAG.getMachineFunction(), RegNo, RC);
-
-    // If this is an 8 or 16-bit value, it is really passed promoted to 32
-    // bits.  Insert an assert[sz]ext to capture this, then truncate to the
-    // right size.
-    if (ArgVT < RegVT) {
-      if (ExtendType == ISD::SIGN_EXTEND) {
-        ArgValue = DAG.getNode(ISD::AssertSext, RegVT, ArgValue,
-                               DAG.getValueType(ArgVT));
-      } else if (ExtendType == ISD::ZERO_EXTEND) {
-        ArgValue = DAG.getNode(ISD::AssertZext, RegVT, ArgValue,
-                               DAG.getValueType(ArgVT));
-      }
-      ArgValue = DAG.getNode(ISD::TRUNCATE, ArgVT, ArgValue);
-    }
-    
-    ArgValues.push_back(ArgValue);
-  }
-  
-  void AssignToStack(SDOperand Arg, unsigned Offset,
-                     MVT::ValueType ArgVT, MVT::ValueType DestVT,
-                     unsigned ExtendType) {
-    // Create the SelectionDAG nodes corresponding to a load from this
-    // parameter.
-    MachineFunction &MF = DAG.getMachineFunction();
-    MachineFrameInfo *MFI = MF.getFrameInfo();
-    int FI = MFI->CreateFixedObject(MVT::getSizeInBits(ArgVT)/8, Offset);
-    SDOperand FIN = DAG.getFrameIndex(FI, TLI.getPointerTy());
-    ArgValues.push_back(DAG.getLoad(ArgVT, Chain, FIN, NULL, 0));
-  }
-};
-
-class LowerCallArgumentsClient {
-  SelectionDAG &DAG;
-  X86TargetLowering &TLI;
-  SmallVector<std::pair<unsigned, SDOperand>, 8> &RegsToPass;
-  SmallVector<SDOperand, 8> &MemOpChains;
-  SDOperand Chain;
-  SDOperand StackPtr;
-public:
-  LowerCallArgumentsClient(SelectionDAG &dag, X86TargetLowering &tli,
-                           SmallVector<std::pair<unsigned, SDOperand>, 8> &rtp,
-                           SmallVector<SDOperand, 8> &moc,
-                           SDOperand chain)
-    : DAG(dag), TLI(tli), RegsToPass(rtp), MemOpChains(moc), Chain(chain) {
-      
-  }
-  
-  void AssignToReg(SDOperand Arg, unsigned RegNo,
-                   MVT::ValueType ArgVT, MVT::ValueType RegVT,
-                   unsigned ExtendType) {
-    // If the argument has to be extended somehow before being passed, do so.
-    if (ArgVT < RegVT)
-      Arg = DAG.getNode(ExtendType, RegVT, Arg);
-    
-    RegsToPass.push_back(std::make_pair(RegNo, Arg));
-  }
-  
-  void AssignToStack(SDOperand Arg, unsigned Offset,
-                     MVT::ValueType ArgVT, MVT::ValueType DestVT,
-                     unsigned ExtendType) {
-    // If the argument has to be extended somehow before being stored, do so.
-    if (ArgVT < DestVT)
-      Arg = DAG.getNode(ExtendType, DestVT, Arg);
-    
-    SDOperand SP = getSP();
-    SDOperand PtrOff = DAG.getConstant(Offset, SP.getValueType());
-    PtrOff = DAG.getNode(ISD::ADD, SP.getValueType(), SP, PtrOff);
-    MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
-  }
-private:
-  SDOperand getSP() {
-    if (StackPtr.Val == 0) {
-      MVT::ValueType PtrTy = TLI.getPointerTy();
-      StackPtr = DAG.getRegister(TLI.getStackPtrReg(), PtrTy);
-    }
-    return StackPtr;
-  }
-};
-
-class EmptyArgumentsClient {
-public:
-  EmptyArgumentsClient() {}
-  
-  void AssignToReg(SDOperand Arg, unsigned RegNo,
-                   MVT::ValueType ArgVT, MVT::ValueType RegVT,
-                   unsigned ExtendType) {
-  }
-  
-  void AssignToStack(SDOperand Arg, unsigned Offset,
-                     MVT::ValueType ArgVT, MVT::ValueType DestVT,
-                     unsigned ExtendType) {
-  }
-};
-
 
 SDOperand
 X86TargetLowering::LowerX86_64CCCArguments(SDOperand Op, SelectionDAG &DAG) {
@@ -1335,15 +1279,62 @@
   
   
   CallingConvState CCState(*getTargetMachine().getRegisterInfo());
-  LowerArgumentsClient Client(DAG, *this, ArgValues, Root);
-    
+  SmallVector<CCValAssign, 16> ArgLocs;
+  
   for (unsigned i = 0; i != NumArgs; ++i) {
     MVT::ValueType ArgVT = Op.getValue(i).getValueType();
     unsigned ArgFlags = cast<ConstantSDNode>(Op.getOperand(3+i))->getValue();
-
-    X86_64_CCC_AssignArgument(Client, CCState, ArgVT, ArgFlags, SDOperand());
+    X86_64_CCC_AssignArgument(i, ArgVT, ArgFlags, CCState, ArgLocs);
   }
-
+  
+  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
+    CCValAssign &VA = ArgLocs[i];
+  
+    
+    if (VA.isRegLoc()) {
+      MVT::ValueType RegVT = VA.getLocVT();
+      TargetRegisterClass *RC;
+      if (RegVT == MVT::i32)
+        RC = X86::GR32RegisterClass;
+      else if (RegVT == MVT::i64)
+        RC = X86::GR64RegisterClass;
+      else if (RegVT == MVT::f32)
+        RC = X86::FR32RegisterClass;
+      else if (RegVT == MVT::f64)
+        RC = X86::FR64RegisterClass;
+      else {
+        assert(MVT::isVector(RegVT));
+        RC = X86::VR128RegisterClass;
+      }
+      
+      SDOperand ArgValue = DAG.getCopyFromReg(Root, VA.getLocReg(), RegVT);
+      AddLiveIn(DAG.getMachineFunction(), VA.getLocReg(), RC);
+      
+      // If this is an 8 or 16-bit value, it is really passed promoted to 32
+      // bits.  Insert an assert[sz]ext to capture this, then truncate to the
+      // right size.
+      if (VA.getLocInfo() == CCValAssign::SExt)
+        ArgValue = DAG.getNode(ISD::AssertSext, RegVT, ArgValue,
+                               DAG.getValueType(VA.getValVT()));
+      else if (VA.getLocInfo() == CCValAssign::ZExt)
+        ArgValue = DAG.getNode(ISD::AssertZext, RegVT, ArgValue,
+                               DAG.getValueType(VA.getValVT()));
+      
+      if (VA.getLocInfo() != CCValAssign::Full)
+        ArgValue = DAG.getNode(ISD::TRUNCATE, VA.getValVT(), ArgValue);
+      
+      ArgValues.push_back(ArgValue);
+    } else {
+      assert(VA.isMemLoc());
+    
+      // Create the nodes corresponding to a load from this parameter slot.
+      int FI = MFI->CreateFixedObject(MVT::getSizeInBits(VA.getValVT())/8,
+                                      VA.getLocMemOffset());
+      SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy());
+      ArgValues.push_back(DAG.getLoad(VA.getValVT(), Root, FIN, NULL, 0));
+    }
+  }
+  
   unsigned StackSize = CCState.getNextStackOffset();
   
   // If the function takes variable number of arguments, make a frame index for
@@ -1412,40 +1403,62 @@
   SDOperand Callee    = Op.getOperand(4);
   unsigned NumOps     = (Op.getNumOperands() - 5) / 2;
 
-  // Count how many bytes are to be pushed on the stack.
-  unsigned NumBytes = 0;
-  {
-    CallingConvState CCState(*getTargetMachine().getRegisterInfo());
-    EmptyArgumentsClient Client;
-
-    for (unsigned i = 0; i != NumOps; ++i) {
-      SDOperand Arg = Op.getOperand(5+2*i);
-      MVT::ValueType ArgVT = Arg.getValueType();
-      unsigned ArgFlags =
-        cast<ConstantSDNode>(Op.getOperand(5+2*i+1))->getValue();
-      X86_64_CCC_AssignArgument(Client, CCState, ArgVT, ArgFlags, Arg);
-    }
-    
-    NumBytes = CCState.getNextStackOffset();
+  CallingConvState CCState(*getTargetMachine().getRegisterInfo());
+  SmallVector<CCValAssign, 16> ArgLocs;
+
+  for (unsigned i = 0; i != NumOps; ++i) {
+    MVT::ValueType ArgVT = Op.getOperand(5+2*i).getValueType();
+    unsigned ArgFlags =cast<ConstantSDNode>(Op.getOperand(5+2*i+1))->getValue();
+    X86_64_CCC_AssignArgument(i, ArgVT, ArgFlags, CCState, ArgLocs);
   }
     
-
+  // Get a count of how many bytes are to be pushed on the stack.
+  unsigned NumBytes = CCState.getNextStackOffset();
   Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, getPointerTy()));
 
   SmallVector<std::pair<unsigned, SDOperand>, 8> RegsToPass;
   SmallVector<SDOperand, 8> MemOpChains;
 
-  CallingConvState CCState(*getTargetMachine().getRegisterInfo());
-  LowerCallArgumentsClient Client(DAG, *this, RegsToPass, MemOpChains, Chain);
+  SDOperand StackPtr;
+  
+  // Walk the register/memloc assignments, inserting copies/loads.
+  unsigned LastVal = ~0U;
+  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
+    CCValAssign &VA = ArgLocs[i];
     
-  for (unsigned i = 0; i != NumOps; ++i) {
-    SDOperand Arg = Op.getOperand(5+2*i);
-    MVT::ValueType ArgVT = Arg.getValueType();
-    unsigned ArgFlags =
-      cast<ConstantSDNode>(Op.getOperand(5+2*i+1))->getValue();
-    X86_64_CCC_AssignArgument(Client, CCState, ArgVT, ArgFlags, Arg);
-  }
+    assert(VA.getValNo() != LastVal &&
+           "Don't support value assigned to multiple locs yet");
+    LastVal = VA.getValNo();
+
+    SDOperand Arg = Op.getOperand(5+2*VA.getValNo());
+    
+    // Promote the value if needed.
+    switch (VA.getLocInfo()) {
+    default: assert(0 && "Unknown loc info!");
+    case CCValAssign::Full: break;
+    case CCValAssign::SExt:
+      Arg = DAG.getNode(ISD::SIGN_EXTEND, VA.getLocVT(), Arg);
+      break;
+    case CCValAssign::ZExt:
+      Arg = DAG.getNode(ISD::ZERO_EXTEND, VA.getLocVT(), Arg);
+      break;
+    case CCValAssign::AExt:
+      Arg = DAG.getNode(ISD::ANY_EXTEND, VA.getLocVT(), Arg);
+      break;
+    }
     
+    if (VA.isRegLoc()) {
+      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
+    } else {
+      assert(VA.isMemLoc());
+      if (StackPtr.Val == 0)
+        StackPtr = DAG.getRegister(getStackPtrReg(), getPointerTy());
+      SDOperand PtrOff = DAG.getConstant(VA.getLocMemOffset(), getPointerTy());
+      PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
+      MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
+    }
+  }
+  
   if (!MemOpChains.empty())
     Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
                         &MemOpChains[0], MemOpChains.size());






More information about the llvm-commits mailing list