diff options
-rw-r--r-- | lib/Target/ARM/ARMFastISel.cpp | 59 | ||||
-rw-r--r-- | test/CodeGen/ARM/fast-isel-call.ll | 43 |
2 files changed, 26 insertions, 76 deletions
diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index 617c996..53bbc5d 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -193,21 +193,18 @@ class ARMFastISel : public FastISel { // Call handling routines. private: - CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, - bool Return, - bool isVarArg); + CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool Return); bool ProcessCallArgs(SmallVectorImpl<Value*> &Args, SmallVectorImpl<unsigned> &ArgRegs, SmallVectorImpl<MVT> &ArgVTs, SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags, SmallVectorImpl<unsigned> &RegArgs, CallingConv::ID CC, - unsigned &NumBytes, - bool isVarArg); + unsigned &NumBytes); unsigned getLibcallReg(const Twine &Name); bool FinishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs, const Instruction *I, CallingConv::ID CC, - unsigned &NumBytes, bool isVarArg); + unsigned &NumBytes); bool ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call); // OptionalDef handling routines. @@ -1813,9 +1810,7 @@ bool ARMFastISel::SelectBinaryFPOp(const Instruction *I, unsigned ISDOpcode) { // This is largely taken directly from CCAssignFnForNode - we don't support // varargs in FastISel so that part has been removed. // TODO: We may not support all of this. -CCAssignFn *ARMFastISel::CCAssignFnForCall(CallingConv::ID CC, - bool Return, - bool isVarArg) { +CCAssignFn *ARMFastISel::CCAssignFnForCall(CallingConv::ID CC, bool Return) { switch (CC) { default: llvm_unreachable("Unsupported calling convention"); @@ -1828,15 +1823,14 @@ CCAssignFn *ARMFastISel::CCAssignFnForCall(CallingConv::ID CC, // Use target triple & subtarget features to do actual dispatch. if (Subtarget->isAAPCS_ABI()) { if (Subtarget->hasVFP2() && - TM.Options.FloatABIType == FloatABI::Hard && !isVarArg) + TM.Options.FloatABIType == FloatABI::Hard) return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP); else return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS); } else return (Return ? RetCC_ARM_APCS: CC_ARM_APCS); case CallingConv::ARM_AAPCS_VFP: - if (!isVarArg) - return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP); + return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP); case CallingConv::ARM_AAPCS: return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS); case CallingConv::ARM_APCS: @@ -1850,12 +1844,10 @@ bool ARMFastISel::ProcessCallArgs(SmallVectorImpl<Value*> &Args, SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags, SmallVectorImpl<unsigned> &RegArgs, CallingConv::ID CC, - unsigned &NumBytes, - bool isVarArg) { + unsigned &NumBytes) { SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, *FuncInfo.MF, TM, ArgLocs, *Context); - CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags, - CCAssignFnForCall(CC, false, isVarArg)); + CCState CCInfo(CC, false, *FuncInfo.MF, TM, ArgLocs, *Context); + CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags, CCAssignFnForCall(CC, false)); // Check that we can handle all of the arguments. If we can't, then bail out // now before we add code to the MBB. @@ -1987,7 +1979,7 @@ bool ARMFastISel::ProcessCallArgs(SmallVectorImpl<Value*> &Args, bool ARMFastISel::FinishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs, const Instruction *I, CallingConv::ID CC, - unsigned &NumBytes, bool isVarArg) { + unsigned &NumBytes) { // Issue CALLSEQ_END unsigned AdjStackUp = TII.getCallFrameDestroyOpcode(); AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, @@ -1997,8 +1989,8 @@ bool ARMFastISel::FinishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs, // Now the return value. if (RetVT != MVT::isVoid) { SmallVector<CCValAssign, 16> RVLocs; - CCState CCInfo(CC, isVarArg, *FuncInfo.MF, TM, RVLocs, *Context); - CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true, isVarArg)); + CCState CCInfo(CC, false, *FuncInfo.MF, TM, RVLocs, *Context); + CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true)); // Copy all of the result registers out of their specified physreg. if (RVLocs.size() == 2 && RetVT == MVT::f64) { @@ -2047,6 +2039,9 @@ bool ARMFastISel::SelectRet(const Instruction *I) { if (!FuncInfo.CanLowerReturn) return false; + if (F.isVarArg()) + return false; + CallingConv::ID CC = F.getCallingConv(); if (Ret->getNumOperands() > 0) { SmallVector<ISD::OutputArg, 4> Outs; @@ -2056,8 +2051,7 @@ bool ARMFastISel::SelectRet(const Instruction *I) { // Analyze operands of the call, assigning locations to each operand. SmallVector<CCValAssign, 16> ValLocs; CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, TM, ValLocs,I->getContext()); - CCInfo.AnalyzeReturn(Outs, CCAssignFnForCall(CC, true /* is Ret */, - F.isVarArg())); + CCInfo.AnalyzeReturn(Outs, CCAssignFnForCall(CC, true /* is Ret */)); const Value *RV = Ret->getOperand(0); unsigned Reg = getRegForValue(RV); @@ -2149,7 +2143,7 @@ bool ARMFastISel::ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call) { if (RetVT != MVT::isVoid && RetVT != MVT::i32) { SmallVector<CCValAssign, 16> RVLocs; CCState CCInfo(CC, false, *FuncInfo.MF, TM, RVLocs, *Context); - CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true, false)); + CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true)); if (RVLocs.size() >= 2 && RetVT != MVT::f64) return false; } @@ -2185,8 +2179,7 @@ bool ARMFastISel::ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call) { // Handle the arguments now that we've gotten them. SmallVector<unsigned, 4> RegArgs; unsigned NumBytes; - if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, - RegArgs, CC, NumBytes, false)) + if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, RegArgs, CC, NumBytes)) return false; unsigned CalleeReg = 0; @@ -2225,7 +2218,7 @@ bool ARMFastISel::ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call) { // Finish off the call including any return values. SmallVector<unsigned, 4> UsedRegs; - if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes, false)) return false; + if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes)) return false; // Set all unused physreg defs as dead. static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI); @@ -2247,9 +2240,11 @@ bool ARMFastISel::SelectCall(const Instruction *I, // TODO: Avoid some calling conventions? + // Let SDISel handle vararg functions. PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType()); FunctionType *FTy = cast<FunctionType>(PT->getElementType()); - bool isVarArg = FTy->isVarArg(); + if (FTy->isVarArg()) + return false; // Handle *simple* calls for now. Type *RetTy = I->getType(); @@ -2264,8 +2259,8 @@ bool ARMFastISel::SelectCall(const Instruction *I, if (RetVT != MVT::isVoid && RetVT != MVT::i1 && RetVT != MVT::i8 && RetVT != MVT::i16 && RetVT != MVT::i32) { SmallVector<CCValAssign, 16> RVLocs; - CCState CCInfo(CC, isVarArg, *FuncInfo.MF, TM, RVLocs, *Context); - CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true, isVarArg)); + CCState CCInfo(CC, false, *FuncInfo.MF, TM, RVLocs, *Context); + CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true)); if (RVLocs.size() >= 2 && RetVT != MVT::f64) return false; } @@ -2323,8 +2318,7 @@ bool ARMFastISel::SelectCall(const Instruction *I, // Handle the arguments now that we've gotten them. SmallVector<unsigned, 4> RegArgs; unsigned NumBytes; - if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, - RegArgs, CC, NumBytes, isVarArg)) + if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, RegArgs, CC, NumBytes)) return false; bool UseReg = false; @@ -2376,8 +2370,7 @@ bool ARMFastISel::SelectCall(const Instruction *I, // Finish off the call including any return values. SmallVector<unsigned, 4> UsedRegs; - if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes, isVarArg)) - return false; + if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes)) return false; // Set all unused physreg defs as dead. static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI); diff --git a/test/CodeGen/ARM/fast-isel-call.ll b/test/CodeGen/ARM/fast-isel-call.ll index edc805a..0f24756 100644 --- a/test/CodeGen/ARM/fast-isel-call.ll +++ b/test/CodeGen/ARM/fast-isel-call.ll @@ -178,46 +178,3 @@ entry: %tmp1 = udiv i32 %a, %b ; <i32> [#uses=1] ret i32 %tmp1 } - -define i32 @VarArg() nounwind { -entry: - %i = alloca i32, align 4 - %j = alloca i32, align 4 - %k = alloca i32, align 4 - %m = alloca i32, align 4 - %n = alloca i32, align 4 - %tmp = alloca i32, align 4 - %0 = load i32* %i, align 4 - %1 = load i32* %j, align 4 - %2 = load i32* %k, align 4 - %3 = load i32* %m, align 4 - %4 = load i32* %n, align 4 -; ARM: VarArg -; ARM: mov r7, sp -; ARM: movw r0, #5 -; ARM: ldr r1, [r7, #-4] -; ARM: ldr r2, [r7, #-8] -; ARM: ldr r3, [r7, #-12] -; ARM: ldr r9, [sp, #16] -; ARM: ldr r12, [sp, #12] -; ARM: str r9, [sp] -; ARM: str r12, [sp, #4] -; ARM: bl _CallVariadic -; THUMB: mov r7, sp -; THUMB: movs r0, #5 -; THUMB: movt r0, #0 -; THUMB: ldr r1, [sp, #28] -; THUMB: ldr r2, [sp, #24] -; THUMB: ldr r3, [sp, #20] -; THUMB: ldr.w r9, [sp, #16] -; THUMB: ldr.w r12, [sp, #12] -; THUMB: str.w r9, [sp] -; THUMB: str.w r12, [sp, #4] -; THUMB: bl _CallVariadic - %call = call i32 (i32, ...)* @CallVariadic(i32 5, i32 %0, i32 %1, i32 %2, i32 %3, i32 %4) - store i32 %call, i32* %tmp, align 4 - %5 = load i32* %tmp, align 4 - ret i32 %5 -} - -declare i32 @CallVariadic(i32, ...) |