[llvm-commits] [llvm] r159804 - in /llvm/trunk: lib/Target/ARM/ARMFastISel.cpp test/CodeGen/ARM/fast-isel-call.ll

NAKAMURA Takumi geek4civic at gmail.com
Fri Jul 6 04:38:56 PDT 2012


Jush, I have reverted yours in r159817, due to breaking
CodeGen/Thumb2/large-call.ll on several hosts.

Lemme know if you could not reproduce the failure, thank you.

...Takumi

2012/7/6 Jush Lu <jush.msn at gmail.com>:
> Author: jush
> Date: Thu Jul  5 22:02:37 2012
> New Revision: 159804
>
> URL: http://llvm.org/viewvc/llvm-project?rev=159804&view=rev
> Log:
> [arm-fast-isel] Add support for vararg function calls.
>
> Modified:
>     llvm/trunk/lib/Target/ARM/ARMFastISel.cpp
>     llvm/trunk/test/CodeGen/ARM/fast-isel-call.ll
>
> Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=159804&r1=159803&r2=159804&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Thu Jul  5 22:02:37 2012
> @@ -193,18 +193,21 @@
>
>      // Call handling routines.
>    private:
> -    CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool Return);
> +    CCAssignFn *CCAssignFnForCall(CallingConv::ID CC,
> +                                  bool Return,
> +                                  bool isVarArg);
>      bool ProcessCallArgs(SmallVectorImpl<Value*> &Args,
>                           SmallVectorImpl<unsigned> &ArgRegs,
>                           SmallVectorImpl<MVT> &ArgVTs,
>                           SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
>                           SmallVectorImpl<unsigned> &RegArgs,
>                           CallingConv::ID CC,
> -                         unsigned &NumBytes);
> +                         unsigned &NumBytes,
> +                         bool isVarArg);
>      unsigned getLibcallReg(const Twine &Name);
>      bool FinishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs,
>                      const Instruction *I, CallingConv::ID CC,
> -                    unsigned &NumBytes);
> +                    unsigned &NumBytes, bool isVarArg);
>      bool ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call);
>
>      // OptionalDef handling routines.
> @@ -1810,7 +1813,9 @@
>  // 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) {
> +CCAssignFn *ARMFastISel::CCAssignFnForCall(CallingConv::ID CC,
> +                                           bool Return,
> +                                           bool isVarArg) {
>    switch (CC) {
>    default:
>      llvm_unreachable("Unsupported calling convention");
> @@ -1823,14 +1828,15 @@
>      // Use target triple & subtarget features to do actual dispatch.
>      if (Subtarget->isAAPCS_ABI()) {
>        if (Subtarget->hasVFP2() &&
> -          TM.Options.FloatABIType == FloatABI::Hard)
> +          TM.Options.FloatABIType == FloatABI::Hard && !isVarArg)
>          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:
> -    return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP);
> +    if (!isVarArg)
> +      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:
> @@ -1844,10 +1850,12 @@
>                                    SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
>                                    SmallVectorImpl<unsigned> &RegArgs,
>                                    CallingConv::ID CC,
> -                                  unsigned &NumBytes) {
> +                                  unsigned &NumBytes,
> +                                  bool isVarArg) {
>    SmallVector<CCValAssign, 16> ArgLocs;
> -  CCState CCInfo(CC, false, *FuncInfo.MF, TM, ArgLocs, *Context);
> -  CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags, CCAssignFnForCall(CC, false));
> +  CCState CCInfo(CC, isVarArg, *FuncInfo.MF, TM, ArgLocs, *Context);
> +  CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags,
> +                             CCAssignFnForCall(CC, false, isVarArg));
>
>    // Check that we can handle all of the arguments. If we can't, then bail out
>    // now before we add code to the MBB.
> @@ -1979,7 +1987,7 @@
>
>  bool ARMFastISel::FinishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs,
>                               const Instruction *I, CallingConv::ID CC,
> -                             unsigned &NumBytes) {
> +                             unsigned &NumBytes, bool isVarArg) {
>    // Issue CALLSEQ_END
>    unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
>    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
> @@ -1989,8 +1997,8 @@
>    // Now the return value.
>    if (RetVT != MVT::isVoid) {
>      SmallVector<CCValAssign, 16> RVLocs;
> -    CCState CCInfo(CC, false, *FuncInfo.MF, TM, RVLocs, *Context);
> -    CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true));
> +    CCState CCInfo(CC, isVarArg, *FuncInfo.MF, TM, RVLocs, *Context);
> +    CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true, isVarArg));
>
>      // Copy all of the result registers out of their specified physreg.
>      if (RVLocs.size() == 2 && RetVT == MVT::f64) {
> @@ -2039,9 +2047,6 @@
>    if (!FuncInfo.CanLowerReturn)
>      return false;
>
> -  if (F.isVarArg())
> -    return false;
> -
>    CallingConv::ID CC = F.getCallingConv();
>    if (Ret->getNumOperands() > 0) {
>      SmallVector<ISD::OutputArg, 4> Outs;
> @@ -2051,7 +2056,8 @@
>      // 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 */));
> +    CCInfo.AnalyzeReturn(Outs, CCAssignFnForCall(CC, true /* is Ret */,
> +                                                 F.isVarArg()));
>
>      const Value *RV = Ret->getOperand(0);
>      unsigned Reg = getRegForValue(RV);
> @@ -2143,7 +2149,7 @@
>    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));
> +    CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true, false));
>      if (RVLocs.size() >= 2 && RetVT != MVT::f64)
>        return false;
>    }
> @@ -2179,7 +2185,8 @@
>    // Handle the arguments now that we've gotten them.
>    SmallVector<unsigned, 4> RegArgs;
>    unsigned NumBytes;
> -  if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, RegArgs, CC, NumBytes))
> +  if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
> +                       RegArgs, CC, NumBytes, false))
>      return false;
>
>    unsigned CalleeReg = 0;
> @@ -2218,7 +2225,7 @@
>
>    // Finish off the call including any return values.
>    SmallVector<unsigned, 4> UsedRegs;
> -  if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes)) return false;
> +  if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes, false)) return false;
>
>    // Set all unused physreg defs as dead.
>    static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
> @@ -2240,11 +2247,9 @@
>
>    // TODO: Avoid some calling conventions?
>
> -  // Let SDISel handle vararg functions.
>    PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
>    FunctionType *FTy = cast<FunctionType>(PT->getElementType());
> -  if (FTy->isVarArg())
> -    return false;
> +  bool isVarArg = FTy->isVarArg();
>
>    // Handle *simple* calls for now.
>    Type *RetTy = I->getType();
> @@ -2259,8 +2264,8 @@
>    if (RetVT != MVT::isVoid && RetVT != MVT::i1 && RetVT != MVT::i8 &&
>        RetVT != MVT::i16 && RetVT != MVT::i32) {
>      SmallVector<CCValAssign, 16> RVLocs;
> -    CCState CCInfo(CC, false, *FuncInfo.MF, TM, RVLocs, *Context);
> -    CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true));
> +    CCState CCInfo(CC, isVarArg, *FuncInfo.MF, TM, RVLocs, *Context);
> +    CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true, isVarArg));
>      if (RVLocs.size() >= 2 && RetVT != MVT::f64)
>        return false;
>    }
> @@ -2318,7 +2323,8 @@
>    // Handle the arguments now that we've gotten them.
>    SmallVector<unsigned, 4> RegArgs;
>    unsigned NumBytes;
> -  if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, RegArgs, CC, NumBytes))
> +  if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
> +                       RegArgs, CC, NumBytes, isVarArg))
>      return false;
>
>    bool UseReg = false;
> @@ -2370,7 +2376,8 @@
>
>    // Finish off the call including any return values.
>    SmallVector<unsigned, 4> UsedRegs;
> -  if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes)) return false;
> +  if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes, isVarArg))
> +    return false;
>
>    // Set all unused physreg defs as dead.
>    static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
>
> Modified: llvm/trunk/test/CodeGen/ARM/fast-isel-call.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fast-isel-call.ll?rev=159804&r1=159803&r2=159804&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/ARM/fast-isel-call.ll (original)
> +++ llvm/trunk/test/CodeGen/ARM/fast-isel-call.ll Thu Jul  5 22:02:37 2012
> @@ -178,3 +178,46 @@
>          %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, ...)
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
-------------- next part --------------
A non-text attachment was scrubbed...
Name: large-call.ll.s.gz
Type: application/x-gzip
Size: 7868 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20120706/da7a9b20/attachment.bin>


More information about the llvm-commits mailing list