mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
[ARM] Define a subtarget feature and use it to decide whether long calls should
be emitted. This is needed to enable ARM long calls for LTO and enable and disable it on a per-function basis. Out-of-tree projects currently using EnableARMLongCalls to emit long calls should start passing "+long-calls" to the feature string (see the changes made to clang in r241565). rdar://problem/21529937 Differential Revision: http://reviews.llvm.org/D9364 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241566 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6304789dde
commit
a744879a65
@ -150,6 +150,10 @@ def FeatureAClass : SubtargetFeature<"aclass", "ARMProcClass", "AClass",
|
||||
def FeatureNaClTrap : SubtargetFeature<"nacl-trap", "UseNaClTrap", "true",
|
||||
"NaCl trap">;
|
||||
|
||||
def FeatureLongCalls : SubtargetFeature<"long-calls", "GenLongCalls", "true",
|
||||
"Generate calls via indirect call "
|
||||
"instructions">;
|
||||
|
||||
// ARM ISAs.
|
||||
def HasV4TOps : SubtargetFeature<"v4t", "HasV4TOps", "true",
|
||||
"Support ARM v4T instructions">;
|
||||
|
@ -49,8 +49,6 @@
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
using namespace llvm;
|
||||
|
||||
extern cl::opt<bool> EnableARMLongCalls;
|
||||
|
||||
namespace {
|
||||
|
||||
// All possible address modes, plus some.
|
||||
@ -2246,19 +2244,19 @@ bool ARMFastISel::ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call) {
|
||||
return false;
|
||||
|
||||
unsigned CalleeReg = 0;
|
||||
if (EnableARMLongCalls) {
|
||||
if (Subtarget->genLongCalls()) {
|
||||
CalleeReg = getLibcallReg(TLI.getLibcallName(Call));
|
||||
if (CalleeReg == 0) return false;
|
||||
}
|
||||
|
||||
// Issue the call.
|
||||
unsigned CallOpc = ARMSelectCallOp(EnableARMLongCalls);
|
||||
unsigned CallOpc = ARMSelectCallOp(Subtarget->genLongCalls());
|
||||
MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
|
||||
DbgLoc, TII.get(CallOpc));
|
||||
// BL / BLX don't take a predicate, but tBL / tBLX do.
|
||||
if (isThumb2)
|
||||
AddDefaultPred(MIB);
|
||||
if (EnableARMLongCalls)
|
||||
if (Subtarget->genLongCalls())
|
||||
MIB.addReg(CalleeReg);
|
||||
else
|
||||
MIB.addExternalSymbol(TLI.getLibcallName(Call));
|
||||
@ -2380,7 +2378,7 @@ bool ARMFastISel::SelectCall(const Instruction *I,
|
||||
|
||||
bool UseReg = false;
|
||||
const GlobalValue *GV = dyn_cast<GlobalValue>(Callee);
|
||||
if (!GV || EnableARMLongCalls) UseReg = true;
|
||||
if (!GV || Subtarget->genLongCalls()) UseReg = true;
|
||||
|
||||
unsigned CalleeReg = 0;
|
||||
if (UseReg) {
|
||||
|
@ -60,11 +60,6 @@ STATISTIC(NumTailCalls, "Number of tail calls");
|
||||
STATISTIC(NumMovwMovt, "Number of GAs materialized with movw + movt");
|
||||
STATISTIC(NumLoopByVals, "Number of loops generated for byval arguments");
|
||||
|
||||
cl::opt<bool>
|
||||
EnableARMLongCalls("arm-long-calls", cl::Hidden,
|
||||
cl::desc("Generate calls via indirect call instructions"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool>
|
||||
ARMInterworking("arm-interworking", cl::Hidden,
|
||||
cl::desc("Enable / disable ARM interworking (for debugging only)"),
|
||||
@ -1694,7 +1689,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
bool isLocalARMFunc = false;
|
||||
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
||||
|
||||
if (EnableARMLongCalls) {
|
||||
if (Subtarget->genLongCalls()) {
|
||||
assert((Subtarget->isTargetWindows() ||
|
||||
getTargetMachine().getRelocationModel() == Reloc::Static) &&
|
||||
"long-calls with non-static relocation model!");
|
||||
|
@ -172,6 +172,7 @@ void ARMSubtarget::initializeEnvironment() {
|
||||
AllowsUnalignedMem = false;
|
||||
Thumb2DSP = false;
|
||||
UseNaClTrap = false;
|
||||
GenLongCalls = false;
|
||||
UnsafeFPMath = false;
|
||||
}
|
||||
|
||||
|
@ -206,6 +206,9 @@ protected:
|
||||
/// NaCl TRAP instruction is generated instead of the regular TRAP.
|
||||
bool UseNaClTrap;
|
||||
|
||||
/// Generate calls via indirect call instructions.
|
||||
bool GenLongCalls;
|
||||
|
||||
/// Target machine allowed unsafe FP math (such as use of NEON fp)
|
||||
bool UnsafeFPMath;
|
||||
|
||||
@ -342,6 +345,7 @@ public:
|
||||
bool hasMPExtension() const { return HasMPExtension; }
|
||||
bool hasThumb2DSP() const { return Thumb2DSP; }
|
||||
bool useNaClTrap() const { return UseNaClTrap; }
|
||||
bool genLongCalls() const { return GenLongCalls; }
|
||||
|
||||
bool hasFP16() const { return HasFP16; }
|
||||
bool hasD16() const { return HasD16; }
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -arm-long-calls -o - %s \
|
||||
; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -mattr=+long-calls -o - %s \
|
||||
; RUN: | FileCheck %s
|
||||
|
||||
declare arm_aapcs_vfpcc void @callee()
|
||||
|
@ -1,9 +1,9 @@
|
||||
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=ARM
|
||||
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi | FileCheck %s --check-prefix=ARM
|
||||
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=THUMB
|
||||
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -arm-long-calls | FileCheck %s --check-prefix=ARM-LONG
|
||||
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -arm-long-calls | FileCheck %s --check-prefix=ARM-LONG
|
||||
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -arm-long-calls | FileCheck %s --check-prefix=THUMB-LONG
|
||||
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -mattr=+long-calls | FileCheck %s --check-prefix=ARM-LONG
|
||||
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -mattr=+long-calls | FileCheck %s --check-prefix=ARM-LONG
|
||||
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -mattr=+long-calls | FileCheck %s --check-prefix=THUMB-LONG
|
||||
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -mattr=-vfp2 | FileCheck %s --check-prefix=ARM-NOVFP
|
||||
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -mattr=-vfp2 | FileCheck %s --check-prefix=ARM-NOVFP
|
||||
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -mattr=-vfp2 | FileCheck %s --check-prefix=THUMB-NOVFP
|
||||
|
@ -1,9 +1,9 @@
|
||||
; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=ARM
|
||||
; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -verify-machineinstrs | FileCheck %s --check-prefix=ARM
|
||||
; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=THUMB
|
||||
; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -arm-long-calls -verify-machineinstrs | FileCheck %s --check-prefix=ARM-LONG
|
||||
; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -arm-long-calls -verify-machineinstrs | FileCheck %s --check-prefix=ARM-LONG
|
||||
; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -arm-long-calls -verify-machineinstrs | FileCheck %s --check-prefix=THUMB-LONG
|
||||
; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -mattr=+long-calls -verify-machineinstrs | FileCheck %s --check-prefix=ARM-LONG
|
||||
; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -mattr=+long-calls -verify-machineinstrs | FileCheck %s --check-prefix=ARM-LONG
|
||||
; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -mattr=+long-calls -verify-machineinstrs | FileCheck %s --check-prefix=THUMB-LONG
|
||||
|
||||
; Note that some of these tests assume that relocations are either
|
||||
; movw/movt or constant pool loads. Different platforms will select
|
||||
|
@ -1,5 +1,5 @@
|
||||
; RUN: llc < %s -mtriple=thumbv7-apple-ios -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=static -arm-long-calls | FileCheck -check-prefix=CHECK-LONG %s
|
||||
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=static -arm-long-calls | FileCheck -check-prefix=CHECK-LONG %s
|
||||
; RUN: llc < %s -mtriple=thumbv7-apple-ios -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=static -mattr=+long-calls | FileCheck -check-prefix=CHECK-LONG %s
|
||||
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=static -mattr=+long-calls | FileCheck -check-prefix=CHECK-LONG %s
|
||||
; RUN: llc < %s -mtriple=thumbv7-apple-ios -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=static | FileCheck -check-prefix=CHECK-NORM %s
|
||||
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=static | FileCheck -check-prefix=CHECK-NORM %s
|
||||
|
||||
|
40
test/CodeGen/ARM/subtarget-features-long-calls.ll
Normal file
40
test/CodeGen/ARM/subtarget-features-long-calls.ll
Normal file
@ -0,0 +1,40 @@
|
||||
; RUN: llc -march arm -mcpu cortex-a8 -relocation-model=static %s -o - | FileCheck -check-prefix=NO-OPTION %s
|
||||
; RUN: llc -march arm -mcpu cortex-a8 -relocation-model=static %s -o - -mattr=+long-calls | FileCheck -check-prefix=LONGCALL %s
|
||||
; RUN: llc -march arm -mcpu cortex-a8 -relocation-model=static %s -o - -mattr=-long-calls | FileCheck -check-prefix=NO-LONGCALL %s
|
||||
; RUN: llc -march arm -mcpu cortex-a8 -relocation-model=static %s -o - -O0 | FileCheck -check-prefix=NO-OPTION %s
|
||||
; RUN: llc -march arm -mcpu cortex-a8 -relocation-model=static %s -o - -O0 -mattr=+long-calls | FileCheck -check-prefix=LONGCALL %s
|
||||
; RUN: llc -march arm -mcpu cortex-a8 -relocation-model=static %s -o - -O0 -mattr=-long-calls | FileCheck -check-prefix=NO-LONGCALL %s
|
||||
|
||||
; NO-OPTION-LABEL: {{_?}}caller0
|
||||
; NO-OPTION: blx {{r[0-9]+}}
|
||||
|
||||
; LONGCALL-LABEL: {{_?}}caller0
|
||||
; LONGCALL: blx {{r[0-9]+}}
|
||||
|
||||
; NO-LONGCALL-LABEL: {{_?}}caller0
|
||||
; NO-LONGCALL: bl {{_?}}callee0
|
||||
|
||||
define i32 @caller0() #0 {
|
||||
entry:
|
||||
tail call void @callee0()
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
; NO-OPTION-LABEL: {{_?}}caller1
|
||||
; NO-OPTION: bl {{_?}}callee0
|
||||
|
||||
; LONGCALL-LABEL: {{_?}}caller1
|
||||
; LONGCALL: blx {{r[0-9]+}}
|
||||
|
||||
; NO-LONGCALL-LABEL: {{_?}}caller1
|
||||
; NO-LONGCALL: bl {{_?}}callee0
|
||||
|
||||
define i32 @caller1() {
|
||||
entry:
|
||||
tail call void @callee0()
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
declare void @callee0()
|
||||
|
||||
attributes #0 = { "target-features"="+long-calls" }
|
Loading…
Reference in New Issue
Block a user