Handle direct aggregate type arguments.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69665 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sanjiv Gupta 2009-04-21 05:54:51 +00:00
parent 4ee29af754
commit e16178b75f
2 changed files with 36 additions and 51 deletions

View File

@ -527,9 +527,6 @@ PIC16TargetLowering::LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG,
MachineFrameInfo *MFI = MF.getFrameInfo(); MachineFrameInfo *MFI = MF.getFrameInfo();
const std::string Name = Func->getName(); const std::string Name = Func->getName();
char *tmpName = new char [strlen(Name.c_str()) + 8];
sprintf(tmpName, "%s.frame", Name.c_str());
ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
FrameIndexSDNode *FR = dyn_cast<FrameIndexSDNode>(Op); FrameIndexSDNode *FR = dyn_cast<FrameIndexSDNode>(Op);
// FrameIndices are not stack offsets. But they represent the request // FrameIndices are not stack offsets. But they represent the request
@ -538,9 +535,19 @@ PIC16TargetLowering::LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG,
// with, we need to traverse all the FrameIndices available earlier in // with, we need to traverse all the FrameIndices available earlier in
// the list and add their requested size. // the list and add their requested size.
unsigned FIndex = FR->getIndex(); unsigned FIndex = FR->getIndex();
Offset = 0; char *tmpName = new char [strlen(Name.c_str()) + 8];
for (unsigned i=0; i<FIndex ; ++i) { if (FIndex < ReservedFrameCount) {
Offset += MFI->getObjectSize(i); sprintf(tmpName, "%s.frame", Name.c_str());
ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
Offset = 0;
for (unsigned i=0; i<FIndex ; ++i) {
Offset += MFI->getObjectSize(i);
}
} else {
// FrameIndex has been made for some temporary storage
sprintf(tmpName, "%s.tmp", Name.c_str());
ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
Offset = GetTmpOffsetForFI(FIndex, MFI->getObjectSize(FIndex));
} }
return; return;
@ -891,12 +898,7 @@ LowerIndirectCallArguments(SDValue Op, SDValue Chain, SDValue InFlag,
for (unsigned i = 0, ArgOffset = RetVals; i < NumOps; i++) { for (unsigned i = 0, ArgOffset = RetVals; i < NumOps; i++) {
// Get the arguments // Get the arguments
Arg = TheCall->getArg(i); Arg = TheCall->getArg(i);
// If argument is FrameIndex then map it with temporary
if (Arg.getOpcode() == PIC16ISD::Lo || Arg.getOpcode() == PIC16ISD::Hi) {
if (Arg.getOperand(0).getOpcode() == ISD::TargetFrameIndex) {
Arg = LegalizeFrameArgument(Arg, dl, DAG);
}
}
Ops.clear(); Ops.clear();
Ops.push_back(Chain); Ops.push_back(Chain);
Ops.push_back(Arg); Ops.push_back(Arg);
@ -914,36 +916,6 @@ LowerIndirectCallArguments(SDValue Op, SDValue Chain, SDValue InFlag,
return Chain; return Chain;
} }
SDValue PIC16TargetLowering::
LegalizeFrameArgument(SDValue Arg, DebugLoc dl, SelectionDAG &DAG) {
MachineFunction &MF = DAG.getMachineFunction();
const Function *Func = MF.getFunction();
MachineFrameInfo *MFI = MF.getFrameInfo();
const std::string Name = Func->getName();
// Caller creates the stack storage to pass the aggregate type
// as argument. So it should be relative to tmp variable.
SDValue FI = Arg.getOperand(0);
char *tmpName = new char [strlen(Name.c_str()) + 8];
sprintf(tmpName, "%s.tmp", Name.c_str());
SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
FrameIndexSDNode *FR = dyn_cast<FrameIndexSDNode>(FI);
unsigned FIndex = FR->getIndex();
// Reserve space in tmp variable for the aggregate type
int FrameOffset = GetTmpOffsetForFI(FIndex, MFI->getObjectSize(FIndex));
if (Arg.getOpcode() == PIC16ISD::Lo) {
// Lo part of frame index
SDValue FrameConst = DAG.getConstant(FrameOffset, MVT::i8);
return DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, ES, FrameConst);
} else {
// Hi part of frame index
SDValue FrameConst = DAG.getConstant(FrameOffset + 1, MVT::i8);
return DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, ES, FrameConst);
}
}
SDValue PIC16TargetLowering:: SDValue PIC16TargetLowering::
LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue ArgLabel, LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue ArgLabel,
SDValue InFlag, SelectionDAG &DAG) { SDValue InFlag, SelectionDAG &DAG) {
@ -975,12 +947,6 @@ LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue ArgLabel,
for (unsigned i=ArgCount, Offset = 0; i<NumOps; i++) { for (unsigned i=ArgCount, Offset = 0; i<NumOps; i++) {
// Get the argument // Get the argument
Arg = TheCall->getArg(i); Arg = TheCall->getArg(i);
// If argument is FrameIndex then map it with temporary
if (Arg.getOpcode() == PIC16ISD::Lo || Arg.getOpcode() == PIC16ISD::Hi) {
if (Arg.getOperand(0).getOpcode() == ISD::TargetFrameIndex) {
Arg = LegalizeFrameArgument(Arg, dl, DAG);
}
}
StoreOffset = (Offset + AddressOffset); StoreOffset = (Offset + AddressOffset);
// Store the argument on frame // Store the argument on frame
@ -1455,6 +1421,17 @@ SDValue PIC16TargetLowering::LowerSUB(SDValue Op, SelectionDAG &DAG) {
return DAG.getNode(Op.getOpcode(), dl, Tys, NewVal, Op.getOperand(1)); return DAG.getNode(Op.getOpcode(), dl, Tys, NewVal, Op.getOperand(1));
} }
void PIC16TargetLowering::InitReservedFrameCount(const Function *F) {
unsigned NumArgs = F->arg_size();
bool isVoidFunc = (F->getReturnType()->getTypeID() == Type::VoidTyID);
if (isVoidFunc)
ReservedFrameCount = NumArgs;
else
ReservedFrameCount = NumArgs + 1;
}
// LowerFORMAL_ARGUMENTS - Argument values are loaded from the // LowerFORMAL_ARGUMENTS - Argument values are loaded from the
// <fname>.args + offset. All arguments are already broken to leaglized // <fname>.args + offset. All arguments are already broken to leaglized
// types, so the offset just runs from 0 to NumArgVals - 1. // types, so the offset just runs from 0 to NumArgVals - 1.
@ -1467,13 +1444,16 @@ SDValue PIC16TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op,
SDValue Chain = Op.getOperand(0); // Formal arguments' chain SDValue Chain = Op.getOperand(0); // Formal arguments' chain
// Reset the map of FI and TmpOffset
ResetTmpOffsetMap();
// Get the callee's name to create the <fname>.args label to pass args. // Get the callee's name to create the <fname>.args label to pass args.
MachineFunction &MF = DAG.getMachineFunction(); MachineFunction &MF = DAG.getMachineFunction();
const Function *F = MF.getFunction(); const Function *F = MF.getFunction();
std::string FuncName = F->getName(); std::string FuncName = F->getName();
// Reset the map of FI and TmpOffset
ResetTmpOffsetMap();
// Initialize the ReserveFrameCount
InitReservedFrameCount(F);
// Create the <fname>.args external symbol. // Create the <fname>.args external symbol.
char *tmpName = new char [strlen(FuncName.c_str()) + 6]; char *tmpName = new char [strlen(FuncName.c_str()) + 6];
sprintf(tmpName, "%s.args", FuncName.c_str()); sprintf(tmpName, "%s.args", FuncName.c_str());

View File

@ -139,6 +139,7 @@ namespace llvm {
// new offset and returns. // new offset and returns.
unsigned GetTmpOffsetForFI(unsigned FI, unsigned slot_size); unsigned GetTmpOffsetForFI(unsigned FI, unsigned slot_size);
void ResetTmpOffsetMap() { FiTmpOffsetMap.clear(); SetTmpSize(0); } void ResetTmpOffsetMap() { FiTmpOffsetMap.clear(); SetTmpSize(0); }
void InitReservedFrameCount(const Function *F);
// Return the size of Tmp variable // Return the size of Tmp variable
unsigned GetTmpSize() { return TmpSize; } unsigned GetTmpSize() { return TmpSize; }
@ -168,7 +169,6 @@ namespace llvm {
void LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG, SDValue &ES, void LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG, SDValue &ES,
int &Offset); int &Offset);
SDValue LegalizeFrameArgument(SDValue Arg, DebugLoc dl, SelectionDAG &DAG);
// CALL node should have all legal operands only. Legalize all non-legal // CALL node should have all legal operands only. Legalize all non-legal
// operands of CALL node and then return the new call will all operands // operands of CALL node and then return the new call will all operands
@ -216,6 +216,11 @@ namespace llvm {
// This maps maintain zero based indexes for these FIs. // This maps maintain zero based indexes for these FIs.
std::map<unsigned, unsigned> FiTmpOffsetMap; std::map<unsigned, unsigned> FiTmpOffsetMap;
unsigned TmpSize; unsigned TmpSize;
// These are the frames for return value and argument passing
// These FrameIndices will be expanded to foo.frame external symbol
// and all others will be expanded to foo.tmp external symbol.
unsigned ReservedFrameCount;
}; };
} // namespace llvm } // namespace llvm