Support for byval parameters on ARM. Will be enabled by a forthcoming

patch to the front-end.  Radar 7662569.

llvm-svn: 126655
This commit is contained in:
Stuart Hastings 2011-02-28 17:17:53 +00:00
parent da20991a1b
commit 67c5c3e939
5 changed files with 53 additions and 9 deletions

View File

@ -39,6 +39,7 @@ namespace llvm {
class AllocaInst;
class APFloat;
class CallInst;
class CCState;
class Function;
class FastISel;
class FunctionLoweringInfo;
@ -1258,6 +1259,9 @@ public:
return SDValue(); // this is here to silence compiler errors
}
/// HandleByVal - Target-specific cleanup for formal ByVal parameters.
virtual void HandleByVal(CCState *) const {};
/// CanLowerReturn - This hook should be implemented to check whether the
/// return values described by the Outs array can fit into the return
/// registers. If false is returned, an sret-demotion is performed.

View File

@ -19,6 +19,7 @@
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetLowering.h"
using namespace llvm;
CCState::CCState(CallingConv::ID CC, bool isVarArg, const TargetMachine &tm,
@ -47,6 +48,7 @@ void CCState::HandleByVal(unsigned ValNo, MVT ValVT,
unsigned Offset = AllocateStack(Size, Align);
addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
TM.getTargetLowering()->HandleByVal(const_cast<CCState*>(this));
}
/// MarkAllocated - Mark a register and all of its aliases as allocated.

View File

@ -22,6 +22,9 @@ class CCIfAlign<string Align, CCAction A>:
//===----------------------------------------------------------------------===//
def CC_ARM_APCS : CallingConv<[
// Handles byval parameters.
CCIfByVal<CCPassByVal<8, 8>>,
CCIfType<[i8, i16], CCPromoteToType<i32>>,
// Handle all vector types as either f64 or v2f64.

View File

@ -1253,6 +1253,7 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
CCValAssign &VA = ArgLocs[i];
SDValue Arg = OutVals[realArgIdx];
ISD::ArgFlagsTy Flags = Outs[realArgIdx].Flags;
bool isByVal = Flags.isByVal();
// Promote the value if needed.
switch (VA.getLocInfo()) {
@ -1299,7 +1300,7 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
}
} else if (VA.isRegLoc()) {
RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
} else if (!IsSibCall) {
} else if (!IsSibCall || isByVal) {
assert(VA.isMemLoc());
MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, Arg,
@ -1492,6 +1493,17 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
dl, DAG, InVals);
}
/// HandleByVal - Every parameter *after* a byval parameter is passed
/// on the stack. Confiscate all the parameter registers to insure
/// this.
void
llvm::ARMTargetLowering::HandleByVal(CCState *State) const {
static const unsigned RegList1[] = {
ARM::R0, ARM::R1, ARM::R2, ARM::R3
};
do {} while (State->AllocateReg(RegList1, 4));
}
/// MatchingStackOffset - Return true if the given stack call argument is
/// already available in the same position (relatively) of the caller's
/// incoming argument stack.
@ -2280,7 +2292,9 @@ ARMTargetLowering::LowerFormalArguments(SDValue Chain,
isVarArg));
SmallVector<SDValue, 16> ArgValues;
int lastInsIndex = -1;
SDValue ArgValue;
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
CCValAssign &VA = ArgLocs[i];
@ -2288,7 +2302,6 @@ ARMTargetLowering::LowerFormalArguments(SDValue Chain,
if (VA.isRegLoc()) {
EVT RegVT = VA.getLocVT();
SDValue ArgValue;
if (VA.needsCustom()) {
// f64 and vector types are split up into multiple registers or
// combinations of registers and stack slots.
@ -2364,14 +2377,33 @@ ARMTargetLowering::LowerFormalArguments(SDValue Chain,
assert(VA.isMemLoc());
assert(VA.getValVT() != MVT::i64 && "i64 should already be lowered");
unsigned ArgSize = VA.getLocVT().getSizeInBits()/8;
int FI = MFI->CreateFixedObject(ArgSize, VA.getLocMemOffset(), true);
int index = ArgLocs[i].getValNo();
// Some Ins[] entries become multiple ArgLoc[] entries.
// Process them only once.
if (index != lastInsIndex)
{
ISD::ArgFlagsTy Flags = Ins[index].Flags;
// FIXME: For now, all byval parameter objects are marked mutable. This can be
// changed with more analysis.
// In case of tail call optimization mark all arguments mutable. Since they
// could be overwritten by lowering of arguments in case of a tail call.
if (Flags.isByVal()) {
int FI = MFI->CreateFixedObject(Flags.getByValSize(),
VA.getLocMemOffset(), false);
InVals.push_back(DAG.getFrameIndex(FI, getPointerTy()));
} else {
int FI = MFI->CreateFixedObject(VA.getLocVT().getSizeInBits()/8,
VA.getLocMemOffset(), true);
// Create load nodes to retrieve arguments from the stack.
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN,
MachinePointerInfo::getFixedStack(FI),
false, false, 0));
// Create load nodes to retrieve arguments from the stack.
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN,
MachinePointerInfo::getFixedStack(FI),
false, false, 0));
}
lastInsIndex = index;
}
}
}

View File

@ -435,6 +435,9 @@ namespace llvm {
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
/// HandleByVal - Target-specific cleanup for ByVal support.
virtual void HandleByVal(CCState *) const;
/// IsEligibleForTailCallOptimization - Check whether the call is eligible
/// for tail call optimization. Targets which want to do tail call
/// optimization should implement this function.