aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2006-04-26 01:20:17 +0000
committerEvan Cheng <evan.cheng@apple.com>2006-04-26 01:20:17 +0000
commit1bc7804e4c8747fd99b119e8f88686c9610c5d4e (patch)
tree11660c2dfdb307392636d484c1484403c1bd8b4a
parent3b0d286d0085fbf8314d9f5510c2f78558ab5dea (diff)
downloadexternal_llvm-1bc7804e4c8747fd99b119e8f88686c9610c5d4e.zip
external_llvm-1bc7804e4c8747fd99b119e8f88686c9610c5d4e.tar.gz
external_llvm-1bc7804e4c8747fd99b119e8f88686c9610c5d4e.tar.bz2
Switching over FORMAL_ARGUMENTS mechanism to lower call arguments.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27975 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp245
-rw-r--r--lib/Target/X86/X86ISelLowering.h12
2 files changed, 177 insertions, 80 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index d1accd3..787436d 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -363,9 +363,16 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
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 @@ X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
// 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 @@ X86TargetLowering::LowerCCCArguments(Function &F, SelectionDAG &DAG) {
// ...
//
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 @@ X86TargetLowering::LowerCCCArguments(Function &F, SelectionDAG &DAG) {
// 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 AddLiveIn(MachineFunction &MF, unsigned PReg,
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 @@ X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
// 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 @@ X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
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 @@ X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
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 @@ X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
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 @@ X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
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 @@ X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
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 @@ X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
else
ArgValue = DAG.getConstantFP(0, ObjectVT);
}
- ArgValues.push_back(ArgValue);
-
- if (ObjSize)
- ArgOffset += ArgIncrement; // Move on to the next argument.
+ FormalArgs.push_back(ArgValue);
}
-
- // 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;
- }
- return ArgValues;
}
std::pair<SDOperand, SDOperand>
@@ -3231,6 +3307,18 @@ SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) {
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 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
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);
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index 690af9b..57847db 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -346,15 +346,22 @@ namespace llvm {
/// 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 @@ namespace llvm {
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);