diff options
author | Tim Northover <tnorthover@apple.com> | 2014-05-26 17:21:53 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2014-05-26 17:21:53 +0000 |
commit | 4146695fb264a617a272f3dfd05b99b342e2b037 (patch) | |
tree | 3bd76fa7d4a3ea5cdf3f5ecd7eb38bbfbcaa7c82 | |
parent | 90e79a50bb0d198edb226cccc338fe4333466b5e (diff) | |
download | llvm-4146695fb264a617a272f3dfd05b99b342e2b037.tar.gz llvm-4146695fb264a617a272f3dfd05b99b342e2b037.tar.bz2 llvm-4146695fb264a617a272f3dfd05b99b342e2b037.tar.xz |
AArch64: simplify calling conventions slightly.
We can eliminate the custom C++ code in favour of some TableGen to
check the same things. Functionality should be identical, except for a
buffer overrun that was present in the C++ code and meant webkit
failed if any small argument needed to be passed on the stack.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209636 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/AArch64/AArch64CallingConv.h | 94 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64CallingConvention.td | 12 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64FastISel.cpp | 1 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64ISelLowering.cpp | 57 | ||||
-rw-r--r-- | test/CodeGen/AArch64/arm64-patchpoint.ll | 8 |
5 files changed, 44 insertions, 128 deletions
diff --git a/lib/Target/AArch64/AArch64CallingConv.h b/lib/Target/AArch64/AArch64CallingConv.h deleted file mode 100644 index 1fe426ed68..0000000000 --- a/lib/Target/AArch64/AArch64CallingConv.h +++ /dev/null @@ -1,94 +0,0 @@ -//=== AArch64CallingConv.h - Custom Calling Convention Routines -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the custom routines for the AArch64 Calling Convention that -// aren't done by tablegen. -// -//===----------------------------------------------------------------------===// - -#ifndef AArch64CALLINGCONV_H -#define AArch64CALLINGCONV_H - -#include "AArch64InstrInfo.h" -#include "llvm/IR/CallingConv.h" -#include "llvm/CodeGen/CallingConvLower.h" -#include "llvm/Target/TargetInstrInfo.h" - -namespace llvm { - -/// CC_AArch64_Custom_i1i8i16_Reg - customized handling of passing i1/i8/i16 via -/// register. Here, ValVT can be i1/i8/i16 or i32 depending on whether the -/// argument is already promoted and LocVT is i1/i8/i16. We only promote the -/// argument to i32 if we are sure this argument will be passed in register. -static bool CC_AArch64_Custom_i1i8i16_Reg(unsigned ValNo, MVT ValVT, MVT LocVT, - CCValAssign::LocInfo LocInfo, - ISD::ArgFlagsTy ArgFlags, - CCState &State, - bool IsWebKitJS = false) { - static const MCPhysReg RegList1[] = { AArch64::W0, AArch64::W1, AArch64::W2, - AArch64::W3, AArch64::W4, AArch64::W5, - AArch64::W6, AArch64::W7 }; - static const MCPhysReg RegList2[] = { AArch64::X0, AArch64::X1, AArch64::X2, - AArch64::X3, AArch64::X4, AArch64::X5, - AArch64::X6, AArch64::X7 }; - static const MCPhysReg WebKitRegList1[] = { AArch64::W0 }; - static const MCPhysReg WebKitRegList2[] = { AArch64::X0 }; - - const MCPhysReg *List1 = IsWebKitJS ? WebKitRegList1 : RegList1; - const MCPhysReg *List2 = IsWebKitJS ? WebKitRegList2 : RegList2; - - if (unsigned Reg = State.AllocateReg(List1, List2, 8)) { - // Customized extra section for handling i1/i8/i16: - // We need to promote the argument to i32 if it is not done already. - if (ValVT != MVT::i32) { - if (ArgFlags.isSExt()) - LocInfo = CCValAssign::SExt; - else if (ArgFlags.isZExt()) - LocInfo = CCValAssign::ZExt; - else - LocInfo = CCValAssign::AExt; - ValVT = MVT::i32; - } - // Set LocVT to i32 as well if passing via register. - LocVT = MVT::i32; - State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); - return true; - } - return false; -} - -/// CC_AArch64_WebKit_JS_i1i8i16_Reg - customized handling of passing i1/i8/i16 -/// via register. This behaves the same as CC_AArch64_Custom_i1i8i16_Reg, but only -/// uses the first register. -static bool CC_AArch64_WebKit_JS_i1i8i16_Reg(unsigned ValNo, MVT ValVT, MVT LocVT, - CCValAssign::LocInfo LocInfo, - ISD::ArgFlagsTy ArgFlags, - CCState &State) { - return CC_AArch64_Custom_i1i8i16_Reg(ValNo, ValVT, LocVT, LocInfo, ArgFlags, - State, true); -} - -/// CC_AArch64_Custom_i1i8i16_Stack: customized handling of passing i1/i8/i16 on -/// stack. Here, ValVT can be i1/i8/i16 or i32 depending on whether the argument -/// is already promoted and LocVT is i1/i8/i16. If ValVT is already promoted, -/// it will be truncated back to i1/i8/i16. -static bool CC_AArch64_Custom_i1i8i16_Stack(unsigned ValNo, MVT ValVT, MVT LocVT, - CCValAssign::LocInfo LocInfo, - ISD::ArgFlagsTy ArgFlags, - CCState &State) { - unsigned Space = ((LocVT == MVT::i1 || LocVT == MVT::i8) ? 1 : 2); - unsigned Offset12 = State.AllocateStack(Space, Space); - ValVT = LocVT; - State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset12, LocVT, LocInfo)); - return true; -} - -} // End llvm namespace - -#endif diff --git a/lib/Target/AArch64/AArch64CallingConvention.td b/lib/Target/AArch64/AArch64CallingConvention.td index c263d14dcc..ded2e17c54 100644 --- a/lib/Target/AArch64/AArch64CallingConvention.td +++ b/lib/Target/AArch64/AArch64CallingConvention.td @@ -18,6 +18,9 @@ class CCIfAlign<string Align, CCAction A> : class CCIfBigEndian<CCAction A> : CCIf<"State.getTarget().getDataLayout()->isBigEndian()", A>; +class CCIfUnallocated<string Reg, CCAction A> : + CCIf<"!State.isAllocated(AArch64::" # Reg # ")", A>; + //===----------------------------------------------------------------------===// // ARM AAPCS64 Calling Convention //===----------------------------------------------------------------------===// @@ -42,7 +45,7 @@ def CC_AArch64_AAPCS : CallingConv<[ // Handle i1, i8, i16, i32, i64, f32, f64 and v2f64 by passing in registers, // up to eight each of GPR and FPR. - CCIfType<[i1, i8, i16], CCCustom<"CC_AArch64_Custom_i1i8i16_Reg">>, + CCIfType<[i1, i8, i16], CCIfUnallocated<"X7", CCPromoteToType<i32>>>, CCIfType<[i32], CCAssignToRegWithShadow<[W0, W1, W2, W3, W4, W5, W6, W7], [X0, X1, X2, X3, X4, X5, X6, X7]>>, // i128 is split to two i64s, we can't fit half to register X7. @@ -117,7 +120,7 @@ def CC_AArch64_DarwinPCS : CallingConv<[ // Handle i1, i8, i16, i32, i64, f32, f64 and v2f64 by passing in registers, // up to eight each of GPR and FPR. - CCIfType<[i1, i8, i16], CCCustom<"CC_AArch64_Custom_i1i8i16_Reg">>, + CCIfType<[i1, i8, i16], CCIfUnallocated<"X7", CCPromoteToType<i32>>>, CCIfType<[i32], CCAssignToRegWithShadow<[W0, W1, W2, W3, W4, W5, W6, W7], [X0, X1, X2, X3, X4, X5, X6, X7]>>, // i128 is split to two i64s, we can't fit half to register X7. @@ -140,7 +143,8 @@ def CC_AArch64_DarwinPCS : CallingConv<[ CCAssignToReg<[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>, // If more than will fit in registers, pass them on the stack instead. - CCIfType<[i1, i8, i16], CCCustom<"CC_AArch64_Custom_i1i8i16_Stack">>, + CCIfType<[i1, i8], CCAssignToStack<1, 1>>, + CCIfType<[i16], CCAssignToStack<2, 2>>, CCIfType<[i32, f32], CCAssignToStack<4, 4>>, CCIfType<[i64, f64, v1f64, v2f32, v1i64, v2i32, v4i16, v8i8], CCAssignToStack<8, 8>>, @@ -168,7 +172,7 @@ def CC_AArch64_DarwinPCS_VarArg : CallingConv<[ // 32bit quantity as undef. def CC_AArch64_WebKit_JS : CallingConv<[ // Handle i1, i8, i16, i32, and i64 passing in register X0 (W0). - CCIfType<[i1, i8, i16], CCCustom<"CC_AArch64_WebKit_JS_i1i8i16_Reg">>, + CCIfType<[i1, i8, i16], CCIfUnallocated<"X0", CCPromoteToType<i32>>>, CCIfType<[i32], CCAssignToRegWithShadow<[W0], [X0]>>, CCIfType<[i64], CCAssignToRegWithShadow<[X0], [W0]>>, diff --git a/lib/Target/AArch64/AArch64FastISel.cpp b/lib/Target/AArch64/AArch64FastISel.cpp index 8cc0f8a273..c3b53692fb 100644 --- a/lib/Target/AArch64/AArch64FastISel.cpp +++ b/lib/Target/AArch64/AArch64FastISel.cpp @@ -16,7 +16,6 @@ #include "AArch64.h" #include "AArch64TargetMachine.h" #include "AArch64Subtarget.h" -#include "AArch64CallingConv.h" #include "MCTargetDesc/AArch64AddressingModes.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/FastISel.h" diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index 4ddba00733..5c504d1e6c 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -14,7 +14,6 @@ #include "AArch64ISelLowering.h" #include "AArch64PerfectShuffle.h" #include "AArch64Subtarget.h" -#include "AArch64CallingConv.h" #include "AArch64MachineFunctionInfo.h" #include "AArch64TargetMachine.h" #include "AArch64TargetObjectFile.h" @@ -1681,15 +1680,14 @@ SDValue AArch64TargetLowering::LowerFormalArguments( EVT ActualVT = getValueType(CurOrigArg->getType(), /*AllowUnknown*/ true); MVT ActualMVT = ActualVT.isSimple() ? ActualVT.getSimpleVT() : MVT::Other; // If ActualMVT is i1/i8/i16, we should set LocVT to i8/i8/i16. - MVT LocVT = ValVT; if (ActualMVT == MVT::i1 || ActualMVT == MVT::i8) - LocVT = MVT::i8; + ValVT = MVT::i8; else if (ActualMVT == MVT::i16) - LocVT = MVT::i16; + ValVT = MVT::i16; CCAssignFn *AssignFn = CCAssignFnForCall(CallConv, /*IsVarArg=*/false); bool Res = - AssignFn(i, ValVT, LocVT, CCValAssign::Full, Ins[i].Flags, CCInfo); + AssignFn(i, ValVT, ValVT, CCValAssign::Full, Ins[i].Flags, CCInfo); assert(!Res && "Call operand has unhandled type"); (void)Res; } @@ -1748,15 +1746,12 @@ SDValue AArch64TargetLowering::LowerFormalArguments( case CCValAssign::BCvt: ArgValue = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), ArgValue); break; + case CCValAssign::AExt: case CCValAssign::SExt: - ArgValue = DAG.getNode(ISD::AssertSext, DL, RegVT, ArgValue, - DAG.getValueType(VA.getValVT())); - ArgValue = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), ArgValue); - break; case CCValAssign::ZExt: - ArgValue = DAG.getNode(ISD::AssertZext, DL, RegVT, ArgValue, - DAG.getValueType(VA.getValVT())); - ArgValue = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), ArgValue); + // SelectionDAGBuilder will insert appropriate AssertZExt & AssertSExt + // nodes after our lowering. + assert(RegVT == Ins[i].VT && "incorrect register location selected"); break; } @@ -1777,21 +1772,26 @@ SDValue AArch64TargetLowering::LowerFormalArguments( SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); SDValue ArgValue; - // If the loc type and val type are not the same, create an anyext load. - if (VA.getLocVT().getSizeInBits() != VA.getValVT().getSizeInBits()) { - // We should only get here if this is a pure integer. - assert(!VA.getValVT().isVector() && VA.getValVT().isInteger() && - "Only integer extension supported!"); - ArgValue = DAG.getExtLoad(ISD::EXTLOAD, DL, VA.getValVT(), Chain, FIN, - MachinePointerInfo::getFixedStack(FI), - VA.getLocVT(), - false, false, false, 0); - } else { - ArgValue = DAG.getLoad(VA.getValVT(), DL, Chain, FIN, - MachinePointerInfo::getFixedStack(FI), false, - false, false, 0); + ISD::LoadExtType ExtType = ISD::NON_EXTLOAD; + switch (VA.getLocInfo()) { + default: + break; + case CCValAssign::SExt: + ExtType = ISD::SEXTLOAD; + break; + case CCValAssign::ZExt: + ExtType = ISD::ZEXTLOAD; + break; + case CCValAssign::AExt: + ExtType = ISD::EXTLOAD; + break; } + ArgValue = DAG.getExtLoad(ExtType, DL, VA.getValVT(), Chain, FIN, + MachinePointerInfo::getFixedStack(FI), + VA.getLocVT(), + false, false, false, 0); + InVals.push_back(ArgValue); } } @@ -2184,14 +2184,13 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI, MVT ActualMVT = ActualVT.isSimple() ? ActualVT.getSimpleVT() : ValVT; ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; // If ActualMVT is i1/i8/i16, we should set LocVT to i8/i8/i16. - MVT LocVT = ValVT; if (ActualMVT == MVT::i1 || ActualMVT == MVT::i8) - LocVT = MVT::i8; + ValVT = MVT::i8; else if (ActualMVT == MVT::i16) - LocVT = MVT::i16; + ValVT = MVT::i16; CCAssignFn *AssignFn = CCAssignFnForCall(CallConv, /*IsVarArg=*/false); - bool Res = AssignFn(i, ValVT, LocVT, CCValAssign::Full, ArgFlags, CCInfo); + bool Res = AssignFn(i, ValVT, ValVT, CCValAssign::Full, ArgFlags, CCInfo); assert(!Res && "Call operand has unhandled type"); (void)Res; } diff --git a/test/CodeGen/AArch64/arm64-patchpoint.ll b/test/CodeGen/AArch64/arm64-patchpoint.ll index 9ef1d778a3..039cdfcc38 100644 --- a/test/CodeGen/AArch64/arm64-patchpoint.ll +++ b/test/CodeGen/AArch64/arm64-patchpoint.ll @@ -161,3 +161,11 @@ define void @clobberScratch(i32* %p) { declare void @llvm.experimental.stackmap(i64, i32, ...) declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...) declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...) + +; CHECK-LABEL: test_i16: +; CHECK: ldrh [[BREG:w[0-9]+]], [sp] +; CHECK: add w0, w0, [[BREG]] +define webkit_jscc i16 @test_i16(i16 zeroext %a, i16 zeroext %b) { + %sum = add i16 %a, %b + ret i16 %sum +} |