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

Evan Cheng evan.cheng at apple.com
Tue Apr 25 18:20:29 PDT 2006



Changes in directory llvm/lib/Target/X86:

X86ISelLowering.cpp updated: 1.187 -> 1.188
X86ISelLowering.h updated: 1.59 -> 1.60
---
Log message:

Switching over FORMAL_ARGUMENTS mechanism to lower call arguments.


---
Diffs of the changes:  (+177 -80)

 X86ISelLowering.cpp |  245 +++++++++++++++++++++++++++++++++++-----------------
 X86ISelLowering.h   |   12 ++
 2 files changed, 177 insertions(+), 80 deletions(-)


Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.187 llvm/lib/Target/X86/X86ISelLowering.cpp:1.188
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.187	Tue Apr 25 15:13:52 2006
+++ llvm/lib/Target/X86/X86ISelLowering.cpp	Tue Apr 25 20:20:17 2006
@@ -363,9 +363,16 @@
 
 std::vector<SDOperand>
 X86TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
+  std::vector<SDOperand> Args = TargetLowering::LowerArguments(F, DAG);
+
+  FormalArgs.clear();
+  // This sets BytesToPopOnReturn, BytesCallerReserves, etc. which have to be set
+  // before the rest of the function can be lowered.
   if (F.getCallingConv() == CallingConv::Fast && EnableFastCC)
-    return LowerFastCCArguments(F, DAG);
-  return LowerCCCArguments(F, DAG);
+    PreprocessFastCCArguments(Args[0], F, DAG);
+  else
+    PreprocessCCCArguments(Args[0], F, DAG);
+  return Args;
 }
 
 std::pair<SDOperand, SDOperand>
@@ -393,10 +400,41 @@
 //                    C Calling Convention implementation
 //===----------------------------------------------------------------------===//
 
-std::vector<SDOperand>
-X86TargetLowering::LowerCCCArguments(Function &F, SelectionDAG &DAG) {
-  std::vector<SDOperand> ArgValues;
+void X86TargetLowering::PreprocessCCCArguments(SDOperand Op, Function &F,
+                                               SelectionDAG &DAG) {
+  unsigned NumArgs = Op.Val->getNumValues();
+  MachineFunction &MF = DAG.getMachineFunction();
+  MachineFrameInfo *MFI = MF.getFrameInfo();
+
+  unsigned ArgOffset = 0;   // Frame mechanisms handle retaddr slot
+  for (unsigned i = 0; i < NumArgs; ++i) {
+    MVT::ValueType ObjectVT = Op.Val->getValueType(i);
+    unsigned ArgIncrement = 4;
+    unsigned ObjSize;
+    switch (ObjectVT) {
+    default: assert(0 && "Unhandled argument type!");
+    case MVT::i1:
+    case MVT::i8:  ObjSize = 1;                break;
+    case MVT::i16: ObjSize = 2;                break;
+    case MVT::i32: ObjSize = 4;                break;
+    case MVT::i64: ObjSize = ArgIncrement = 8; break;
+    case MVT::f32: ObjSize = 4;                break;
+    case MVT::f64: ObjSize = ArgIncrement = 8; break;
+    }
+    ArgOffset += ArgIncrement;   // Move on to the next argument...
+  }
 
+  // If the function takes variable number of arguments, make a frame index for
+  // the start of the first vararg value... for expansion of llvm.va_start.
+  if (F.isVarArg())
+    VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset);
+  ReturnAddrIndex = 0;     // No return address slot generated yet.
+  BytesToPopOnReturn = 0;  // Callee pops nothing.
+  BytesCallerReserves = ArgOffset;
+}
+
+void X86TargetLowering::LowerCCCArguments(SDOperand Op, SelectionDAG &DAG) {
+  unsigned NumArgs = Op.Val->getNumValues();
   MachineFunction &MF = DAG.getMachineFunction();
   MachineFrameInfo *MFI = MF.getFrameInfo();
 
@@ -409,8 +447,8 @@
   //    ...
   //
   unsigned ArgOffset = 0;   // Frame mechanisms handle retaddr slot
-  for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
-    MVT::ValueType ObjectVT = getValueType(I->getType());
+  for (unsigned i = 0; i < NumArgs; ++i) {
+    MVT::ValueType ObjectVT = Op.Val->getValueType(i);
     unsigned ArgIncrement = 4;
     unsigned ObjSize;
     switch (ObjectVT) {
@@ -429,31 +467,11 @@
     // Create the SelectionDAG nodes corresponding to a load from this parameter
     SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
 
-    // Don't codegen dead arguments.  FIXME: remove this check when we can nuke
-    // dead loads.
-    SDOperand ArgValue;
-    if (!I->use_empty())
-      ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN,
-                             DAG.getSrcValue(NULL));
-    else {
-      if (MVT::isInteger(ObjectVT))
-        ArgValue = DAG.getConstant(0, ObjectVT);
-      else
-        ArgValue = DAG.getConstantFP(0, ObjectVT);
-    }
-    ArgValues.push_back(ArgValue);
-
+    SDOperand ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN,
+                                     DAG.getSrcValue(NULL));
+    FormalArgs.push_back(ArgValue);
     ArgOffset += ArgIncrement;   // Move on to the next argument...
   }
-
-  // If the function takes variable number of arguments, make a frame index for
-  // the start of the first vararg value... for expansion of llvm.va_start.
-  if (F.isVarArg())
-    VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset);
-  ReturnAddrIndex = 0;     // No return address slot generated yet.
-  BytesToPopOnReturn = 0;  // Callee pops nothing.
-  BytesCallerReserves = ArgOffset;
-  return ArgValues;
 }
 
 std::pair<SDOperand, SDOperand>
@@ -697,10 +715,103 @@
 static unsigned FASTCC_NUM_INT_ARGS_INREGS = 0;
 
 
-std::vector<SDOperand>
-X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
-  std::vector<SDOperand> ArgValues;
+void
+X86TargetLowering::PreprocessFastCCArguments(SDOperand Op, Function &F,
+                                             SelectionDAG &DAG) {
+  unsigned NumArgs = Op.Val->getNumValues();
+  MachineFunction &MF = DAG.getMachineFunction();
+  MachineFrameInfo *MFI = MF.getFrameInfo();
+
+  unsigned ArgOffset = 0;   // Frame mechanisms handle retaddr slot
+
+  // Keep track of the number of integer regs passed so far.  This can be either
+  // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both
+  // used).
+  unsigned NumIntRegs = 0;
+  
+  for (unsigned i = 0; i < NumArgs; ++i) {
+    MVT::ValueType ObjectVT = Op.Val->getValueType(i);
+    unsigned ArgIncrement = 4;
+    unsigned ObjSize = 0;
+    SDOperand ArgValue;
 
+    switch (ObjectVT) {
+    default: assert(0 && "Unhandled argument type!");
+    case MVT::i1:
+    case MVT::i8:
+      if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS) {
+        ++NumIntRegs;
+        break;
+      }
+
+      ObjSize = 1;
+      break;
+    case MVT::i16:
+      if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS) {
+        ++NumIntRegs;
+        break;
+      }
+      ObjSize = 2;
+      break;
+    case MVT::i32:
+      if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS) {
+        ++NumIntRegs;
+        break;
+      }
+      ObjSize = 4;
+      break;
+    case MVT::i64:
+      if (NumIntRegs+2 <= FASTCC_NUM_INT_ARGS_INREGS) {
+        NumIntRegs += 2;
+        break;
+      } else if (NumIntRegs+1 <= FASTCC_NUM_INT_ARGS_INREGS) {
+        ArgOffset += 4;
+        NumIntRegs = FASTCC_NUM_INT_ARGS_INREGS;
+        break;
+      }
+      ObjSize = ArgIncrement = 8;
+      break;
+    case MVT::f32: ObjSize = 4;                break;
+    case MVT::f64: ObjSize = ArgIncrement = 8; break;
+    }
+
+    if (ObjSize)
+      ArgOffset += ArgIncrement;   // Move on to the next argument.
+  }
+
+  // Make sure the instruction takes 8n+4 bytes to make sure the start of the
+  // arguments and the arguments after the retaddr has been pushed are aligned.
+  if ((ArgOffset & 7) == 0)
+    ArgOffset += 4;
+
+  VarArgsFrameIndex = 0xAAAAAAA;   // fastcc functions can't have varargs.
+  ReturnAddrIndex = 0;             // No return address slot generated yet.
+  BytesToPopOnReturn = ArgOffset;  // Callee pops all stack arguments.
+  BytesCallerReserves = 0;
+
+  // Finally, inform the code generator which regs we return values in.
+  switch (getValueType(F.getReturnType())) {
+  default: assert(0 && "Unknown type!");
+  case MVT::isVoid: break;
+  case MVT::i1:
+  case MVT::i8:
+  case MVT::i16:
+  case MVT::i32:
+    MF.addLiveOut(X86::EAX);
+    break;
+  case MVT::i64:
+    MF.addLiveOut(X86::EAX);
+    MF.addLiveOut(X86::EDX);
+    break;
+  case MVT::f32:
+  case MVT::f64:
+    MF.addLiveOut(X86::ST0);
+    break;
+  }
+}
+void
+X86TargetLowering::LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG) {
+  unsigned NumArgs = Op.Val->getNumValues();
   MachineFunction &MF = DAG.getMachineFunction();
   MachineFrameInfo *MFI = MF.getFrameInfo();
 
@@ -718,18 +829,19 @@
   // used).
   unsigned NumIntRegs = 0;
   
-  for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
-    MVT::ValueType ObjectVT = getValueType(I->getType());
+  for (unsigned i = 0; i < NumArgs; ++i) {
+    MVT::ValueType ObjectVT = Op.Val->getValueType(i);
     unsigned ArgIncrement = 4;
     unsigned ObjSize = 0;
     SDOperand ArgValue;
+    bool hasUse = !Op.Val->hasNUsesOfValue(0, i);
 
     switch (ObjectVT) {
     default: assert(0 && "Unhandled argument type!");
     case MVT::i1:
     case MVT::i8:
       if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS) {
-        if (!I->use_empty()) {
+        if (hasUse) {
           unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DL : X86::AL,
                                     X86::R8RegisterClass);
           ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i8);
@@ -746,7 +858,7 @@
       break;
     case MVT::i16:
       if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS) {
-        if (!I->use_empty()) {
+        if (hasUse) {
           unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DX : X86::AX,
                                     X86::R16RegisterClass);
           ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i16);
@@ -759,7 +871,7 @@
       break;
     case MVT::i32:
       if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS) {
-        if (!I->use_empty()) {
+        if (hasUse) {
           unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::EDX : X86::EAX,
                                     X86::R32RegisterClass);
           ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
@@ -772,7 +884,7 @@
       break;
     case MVT::i64:
       if (NumIntRegs+2 <= FASTCC_NUM_INT_ARGS_INREGS) {
-        if (!I->use_empty()) {
+        if (hasUse) {
           unsigned BotReg = AddLiveIn(MF, X86::EAX, X86::R32RegisterClass);
           unsigned TopReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass);
 
@@ -785,7 +897,7 @@
         NumIntRegs += 2;
         break;
       } else if (NumIntRegs+1 <= FASTCC_NUM_INT_ARGS_INREGS) {
-        if (!I->use_empty()) {
+        if (hasUse) {
           unsigned BotReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass);
           SDOperand Low = DAG.getCopyFromReg(DAG.getRoot(), BotReg, MVT::i32);
           DAG.setRoot(Low.getValue(1));
@@ -808,9 +920,7 @@
     case MVT::f64: ObjSize = ArgIncrement = 8; break;
     }
 
-    // Don't codegen dead arguments.  FIXME: remove this check when we can nuke
-    // dead loads.
-    if (ObjSize && !I->use_empty()) {
+    if (ObjSize) {
       // Create the frame index object for this incoming parameter...
       int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
 
@@ -826,42 +936,8 @@
       else
         ArgValue = DAG.getConstantFP(0, ObjectVT);
     }
-    ArgValues.push_back(ArgValue);
-
-    if (ObjSize)
-      ArgOffset += ArgIncrement;   // Move on to the next argument.
-  }
-
-  // Make sure the instruction takes 8n+4 bytes to make sure the start of the
-  // arguments and the arguments after the retaddr has been pushed are aligned.
-  if ((ArgOffset & 7) == 0)
-    ArgOffset += 4;
-
-  VarArgsFrameIndex = 0xAAAAAAA;   // fastcc functions can't have varargs.
-  ReturnAddrIndex = 0;             // No return address slot generated yet.
-  BytesToPopOnReturn = ArgOffset;  // Callee pops all stack arguments.
-  BytesCallerReserves = 0;
-
-  // Finally, inform the code generator which regs we return values in.
-  switch (getValueType(F.getReturnType())) {
-  default: assert(0 && "Unknown type!");
-  case MVT::isVoid: break;
-  case MVT::i1:
-  case MVT::i8:
-  case MVT::i16:
-  case MVT::i32:
-    MF.addLiveOut(X86::EAX);
-    break;
-  case MVT::i64:
-    MF.addLiveOut(X86::EAX);
-    MF.addLiveOut(X86::EDX);
-    break;
-  case MVT::f32:
-  case MVT::f64:
-    MF.addLiveOut(X86::ST0);
-    break;
+    FormalArgs.push_back(ArgValue);
   }
-  return ArgValues;
 }
 
 std::pair<SDOperand, SDOperand>
@@ -3231,6 +3307,18 @@
                      Copy.getValue(1));
 }
 
+SDOperand
+X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
+  if (FormalArgs.size() == 0) {
+    unsigned CC = cast<ConstantSDNode>(Op.getOperand(0))->getValue();
+    if (CC == CallingConv::Fast && EnableFastCC)
+      LowerFastCCArguments(Op, DAG);
+    else
+      LowerCCCArguments(Op, DAG);
+  }
+  return FormalArgs[Op.ResNo];
+}
+
 SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) {
   SDOperand InFlag(0, 0);
   SDOperand Chain = Op.getOperand(0);
@@ -3645,6 +3733,7 @@
   case ISD::BRCOND:             return LowerBRCOND(Op, DAG);
   case ISD::JumpTable:          return LowerJumpTable(Op, DAG);
   case ISD::RET:                return LowerRET(Op, DAG);
+  case ISD::FORMAL_ARGUMENTS:   return LowerFORMAL_ARGUMENTS(Op, DAG);
   case ISD::MEMSET:             return LowerMEMSET(Op, DAG);
   case ISD::MEMCPY:             return LowerMEMCPY(Op, DAG);
   case ISD::READCYCLECOUNTER:   return LowerREADCYCLCECOUNTER(Op, DAG);


Index: llvm/lib/Target/X86/X86ISelLowering.h
diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.59 llvm/lib/Target/X86/X86ISelLowering.h:1.60
--- llvm/lib/Target/X86/X86ISelLowering.h:1.59	Tue Apr 25 15:13:52 2006
+++ llvm/lib/Target/X86/X86ISelLowering.h	Tue Apr 25 20:20:17 2006
@@ -346,15 +346,22 @@
     /// X86ScalarSSE - Select between SSE2 or x87 floating point ops.
     bool X86ScalarSSE;
 
+    /// Formal arguments lowered to load and CopyFromReg ops.
+    std::vector<SDOperand> FormalArgs;
+
     // C Calling Convention implementation.
-    std::vector<SDOperand> LowerCCCArguments(Function &F, SelectionDAG &DAG);
+    void PreprocessCCCArguments(SDOperand Op, Function &F, SelectionDAG &DAG);
+    void LowerCCCArguments(SDOperand Op, SelectionDAG &DAG);
     std::pair<SDOperand, SDOperand>
     LowerCCCCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
                    bool isTailCall,
                    SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
 
     // Fast Calling Convention implementation.
-    std::vector<SDOperand> LowerFastCCArguments(Function &F, SelectionDAG &DAG);
+    void
+    PreprocessFastCCArguments(SDOperand Op, Function &F, SelectionDAG &DAG);
+    void
+    LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG);
     std::pair<SDOperand, SDOperand>
     LowerFastCCCallTo(SDOperand Chain, const Type *RetTy, bool isTailCall,
                       SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
@@ -379,6 +386,7 @@
     SDOperand LowerMEMCPY(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerJumpTable(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG);
+    SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerREADCYCLCECOUNTER(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG &DAG);






More information about the llvm-commits mailing list