diff options
Diffstat (limited to 'lib/Target/ARM/ARMTargetMachine.cpp')
-rw-r--r-- | lib/Target/ARM/ARMTargetMachine.cpp | 137 |
1 files changed, 115 insertions, 22 deletions
diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp index d85194b75ecb..7a8181b7528f 100644 --- a/lib/Target/ARM/ARMTargetMachine.cpp +++ b/lib/Target/ARM/ARMTargetMachine.cpp @@ -11,9 +11,11 @@ //===----------------------------------------------------------------------===// #include "ARM.h" -#include "ARMTargetMachine.h" #include "ARMFrameLowering.h" +#include "ARMTargetMachine.h" +#include "ARMTargetObjectFile.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/IR/Function.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" @@ -42,6 +44,65 @@ extern "C" void LLVMInitializeARMTarget() { RegisterTargetMachine<ThumbBETargetMachine> B(TheThumbBETarget); } +static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) { + if (TT.isOSBinFormatMachO()) + return make_unique<TargetLoweringObjectFileMachO>(); + if (TT.isOSWindows()) + return make_unique<TargetLoweringObjectFileCOFF>(); + return make_unique<ARMElfTargetObjectFile>(); +} + +static ARMBaseTargetMachine::ARMABI +computeTargetABI(const Triple &TT, StringRef CPU, + const TargetOptions &Options) { + if (Options.MCOptions.getABIName().startswith("aapcs")) + return ARMBaseTargetMachine::ARM_ABI_AAPCS; + else if (Options.MCOptions.getABIName().startswith("apcs")) + return ARMBaseTargetMachine::ARM_ABI_APCS; + + assert(Options.MCOptions.getABIName().empty() && + "Unknown target-abi option!"); + + ARMBaseTargetMachine::ARMABI TargetABI = + ARMBaseTargetMachine::ARM_ABI_UNKNOWN; + + // FIXME: This is duplicated code from the front end and should be unified. + if (TT.isOSBinFormatMachO()) { + if (TT.getEnvironment() == llvm::Triple::EABI || + (TT.getOS() == llvm::Triple::UnknownOS && + TT.getObjectFormat() == llvm::Triple::MachO) || + CPU.startswith("cortex-m")) { + TargetABI = ARMBaseTargetMachine::ARM_ABI_AAPCS; + } else { + TargetABI = ARMBaseTargetMachine::ARM_ABI_APCS; + } + } else if (TT.isOSWindows()) { + // FIXME: this is invalid for WindowsCE + TargetABI = ARMBaseTargetMachine::ARM_ABI_AAPCS; + } else { + // Select the default based on the platform. + switch (TT.getEnvironment()) { + case llvm::Triple::Android: + case llvm::Triple::GNUEABI: + case llvm::Triple::GNUEABIHF: + case llvm::Triple::EABIHF: + case llvm::Triple::EABI: + TargetABI = ARMBaseTargetMachine::ARM_ABI_AAPCS; + break; + case llvm::Triple::GNU: + TargetABI = ARMBaseTargetMachine::ARM_ABI_APCS; + break; + default: + if (TT.getOS() == llvm::Triple::NetBSD) + TargetABI = ARMBaseTargetMachine::ARM_ABI_APCS; + else + TargetABI = ARMBaseTargetMachine::ARM_ABI_AAPCS; + break; + } + } + + return TargetABI; +} /// TargetMachine ctor - Create an ARM architecture model. /// @@ -51,7 +112,9 @@ ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, StringRef TT, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL, bool isLittle) : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), - Subtarget(TT, CPU, FS, *this, isLittle, Options) { + TargetABI(computeTargetABI(Triple(TT), CPU, Options)), + TLOF(createTLOF(Triple(getTargetTriple()))), + Subtarget(TT, CPU, FS, *this, isLittle), isLittle(isLittle) { // Default to triple-appropriate float ABI if (Options.FloatABIType == FloatABI::Default) @@ -59,6 +122,46 @@ ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, StringRef TT, Subtarget.isTargetHardFloat() ? FloatABI::Hard : FloatABI::Soft; } +ARMBaseTargetMachine::~ARMBaseTargetMachine() {} + +const ARMSubtarget * +ARMBaseTargetMachine::getSubtargetImpl(const Function &F) const { + AttributeSet FnAttrs = F.getAttributes(); + Attribute CPUAttr = + FnAttrs.getAttribute(AttributeSet::FunctionIndex, "target-cpu"); + Attribute FSAttr = + FnAttrs.getAttribute(AttributeSet::FunctionIndex, "target-features"); + + std::string CPU = !CPUAttr.hasAttribute(Attribute::None) + ? CPUAttr.getValueAsString().str() + : TargetCPU; + std::string FS = !FSAttr.hasAttribute(Attribute::None) + ? FSAttr.getValueAsString().str() + : TargetFS; + + // FIXME: This is related to the code below to reset the target options, + // we need to know whether or not the soft float flag is set on the + // function before we can generate a subtarget. We also need to use + // it as a key for the subtarget since that can be the only difference + // between two functions. + Attribute SFAttr = + FnAttrs.getAttribute(AttributeSet::FunctionIndex, "use-soft-float"); + bool SoftFloat = !SFAttr.hasAttribute(Attribute::None) + ? SFAttr.getValueAsString() == "true" + : Options.UseSoftFloat; + + auto &I = SubtargetMap[CPU + FS + (SoftFloat ? "use-soft-float=true" + : "use-soft-float=false")]; + if (!I) { + // This needs to be done before we create a new subtarget since any + // creation will depend on the TM and the code generation flags on the + // function that reside in TargetOptions. + resetTargetOptions(F); + I = llvm::make_unique<ARMSubtarget>(TargetTriple, CPU, FS, *this, isLittle); + } + return I.get(); +} + void ARMBaseTargetMachine::addAnalysisPasses(PassManagerBase &PM) { // Add first the target-independent BasicTTI pass, then our ARM pass. This // allows the ARM pass to delegate to the target independent layer when @@ -147,9 +250,9 @@ public: void addIRPasses() override; bool addPreISel() override; bool addInstSelector() override; - bool addPreRegAlloc() override; - bool addPreSched2() override; - bool addPreEmitPass() override; + void addPreRegAlloc() override; + void addPreSched2() override; + void addPreEmitPass() override; }; } // namespace @@ -158,7 +261,10 @@ TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) { } void ARMPassConfig::addIRPasses() { - addPass(createAtomicExpandLoadLinkedPass(TM)); + if (TM->Options.ThreadModel == ThreadModel::Single) + addPass(createLowerAtomicPass()); + else + addPass(createAtomicExpandPass(TM)); // Cmpxchg instructions are often used with a subsequent comparison to // determine whether it succeeded. We can exploit existing control-flow in @@ -188,7 +294,7 @@ bool ARMPassConfig::addInstSelector() { return false; } -bool ARMPassConfig::addPreRegAlloc() { +void ARMPassConfig::addPreRegAlloc() { if (getOptLevel() != CodeGenOpt::None) addPass(createARMLoadStoreOptimizationPass(true)); if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA9()) @@ -199,13 +305,11 @@ bool ARMPassConfig::addPreRegAlloc() { getARMSubtarget().hasNEON() && !DisableA15SDOptimization) { addPass(createA15SDOptimizerPass()); } - return true; } -bool ARMPassConfig::addPreSched2() { +void ARMPassConfig::addPreSched2() { if (getOptLevel() != CodeGenOpt::None) { addPass(createARMLoadStoreOptimizationPass()); - printAndVerify("After ARM load / store optimizer"); if (getARMSubtarget().hasNEON()) addPass(createExecutionDependencyFixPass(&ARM::DPRRegClass)); @@ -226,11 +330,9 @@ bool ARMPassConfig::addPreSched2() { } if (getARMSubtarget().isThumb2()) addPass(createThumb2ITBlockPass()); - - return true; } -bool ARMPassConfig::addPreEmitPass() { +void ARMPassConfig::addPreEmitPass() { if (getARMSubtarget().isThumb2()) { if (!getARMSubtarget().prefers32BitThumb()) addPass(createThumb2SizeReductionPass()); @@ -241,13 +343,4 @@ bool ARMPassConfig::addPreEmitPass() { addPass(createARMOptimizeBarriersPass()); addPass(createARMConstantIslandPass()); - - return true; -} - -bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM, - JITCodeEmitter &JCE) { - // Machine code emitter pass for ARM. - PM.add(createARMJITCodeEmitterPass(*this, JCE)); - return false; } |