summaryrefslogtreecommitdiff
path: root/lib/Target/ARM/ARMTargetMachine.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
commit044eb2f6afba375a914ac9d8024f8f5142bb912e (patch)
tree1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /lib/Target/ARM/ARMTargetMachine.cpp
parenteb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff)
Notes
Diffstat (limited to 'lib/Target/ARM/ARMTargetMachine.cpp')
-rw-r--r--lib/Target/ARM/ARMTargetMachine.cpp63
1 files changed, 39 insertions, 24 deletions
diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp
index c323a1d368de..51982b2dab14 100644
--- a/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/lib/Target/ARM/ARMTargetMachine.cpp
@@ -10,10 +10,10 @@
//
//===----------------------------------------------------------------------===//
+#include "ARMTargetMachine.h"
#include "ARM.h"
-#include "ARMSubtarget.h"
#include "ARMMacroFusion.h"
-#include "ARMTargetMachine.h"
+#include "ARMSubtarget.h"
#include "ARMTargetObjectFile.h"
#include "ARMTargetTransformInfo.h"
#include "MCTargetDesc/ARMMCTargetDesc.h"
@@ -34,6 +34,7 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineScheduler.h"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/TargetLoweringObjectFile.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/DataLayout.h"
@@ -44,7 +45,6 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetParser.h"
#include "llvm/Support/TargetRegistry.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/Scalar.h"
#include <cassert>
@@ -91,6 +91,7 @@ extern "C" void LLVMInitializeARMTarget() {
initializeARMPreAllocLoadStoreOptPass(Registry);
initializeARMConstantIslandsPass(Registry);
initializeARMExecutionDepsFixPass(Registry);
+ initializeARMExpandPseudoPass(Registry);
}
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
@@ -190,17 +191,23 @@ static Reloc::Model getEffectiveRelocModel(const Triple &TT,
return *RM;
}
+static CodeModel::Model getEffectiveCodeModel(Optional<CodeModel::Model> CM) {
+ if (CM)
+ return *CM;
+ return CodeModel::Small;
+}
+
/// Create an ARM architecture model.
///
ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple &TT,
StringRef CPU, StringRef FS,
const TargetOptions &Options,
Optional<Reloc::Model> RM,
- CodeModel::Model CM,
+ Optional<CodeModel::Model> CM,
CodeGenOpt::Level OL, bool isLittle)
: LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle), TT,
- CPU, FS, Options, getEffectiveRelocModel(TT, RM), CM,
- OL),
+ CPU, FS, Options, getEffectiveRelocModel(TT, RM),
+ getEffectiveCodeModel(CM), OL),
TargetABI(computeTargetABI(TT, CPU, Options)),
TLOF(createTLOF(getTargetTriple())), isLittle(isLittle) {
@@ -221,10 +228,10 @@ ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple &TT,
Options.EABIVersion == EABI::Unknown) {
// musl is compatible with glibc with regard to EABI version
if ((TargetTriple.getEnvironment() == Triple::GNUEABI ||
- TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
- TargetTriple.getEnvironment() == Triple::MuslEABI ||
- TargetTriple.getEnvironment() == Triple::MuslEABIHF) &&
- !(TargetTriple.isOSWindows() || TargetTriple.isOSDarwin()))
+ TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
+ TargetTriple.getEnvironment() == Triple::MuslEABI ||
+ TargetTriple.getEnvironment() == Triple::MuslEABIHF) &&
+ !(TargetTriple.isOSWindows() || TargetTriple.isOSDarwin()))
this->Options.EABIVersion = EABI::GNU;
else
this->Options.EABIVersion = EABI::EABI5;
@@ -266,7 +273,12 @@ ARMBaseTargetMachine::getSubtargetImpl(const Function &F) const {
// function that reside in TargetOptions.
resetTargetOptions(F);
I = llvm::make_unique<ARMSubtarget>(TargetTriple, CPU, FS, *this, isLittle);
+
+ if (!I->isThumb() && !I->hasARMOps())
+ F.getContext().emitError("Function '" + F.getName() + "' uses ARM "
+ "instructions, but the target does not support ARM mode execution.");
}
+
return I.get();
}
@@ -276,21 +288,20 @@ TargetIRAnalysis ARMBaseTargetMachine::getTargetIRAnalysis() {
});
}
-
ARMLETargetMachine::ARMLETargetMachine(const Target &T, const Triple &TT,
StringRef CPU, StringRef FS,
const TargetOptions &Options,
Optional<Reloc::Model> RM,
- CodeModel::Model CM,
- CodeGenOpt::Level OL)
+ Optional<CodeModel::Model> CM,
+ CodeGenOpt::Level OL, bool JIT)
: ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
ARMBETargetMachine::ARMBETargetMachine(const Target &T, const Triple &TT,
StringRef CPU, StringRef FS,
const TargetOptions &Options,
Optional<Reloc::Model> RM,
- CodeModel::Model CM,
- CodeGenOpt::Level OL)
+ Optional<CodeModel::Model> CM,
+ CodeGenOpt::Level OL, bool JIT)
: ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
namespace {
@@ -299,7 +310,14 @@ namespace {
class ARMPassConfig : public TargetPassConfig {
public:
ARMPassConfig(ARMBaseTargetMachine &TM, PassManagerBase &PM)
- : TargetPassConfig(TM, PM) {}
+ : TargetPassConfig(TM, PM) {
+ if (TM.getOptLevel() != CodeGenOpt::None) {
+ ARMGenSubtargetInfo STI(TM.getTargetTriple(), TM.getTargetCPU(),
+ TM.getTargetFeatureString());
+ if (STI.hasFeature(ARM::FeatureUseMISched))
+ substitutePass(&PostRASchedulerID, &PostMachineSchedulerID);
+ }
+ }
ARMBaseTargetMachine &getARMTargetMachine() const {
return getTM<ARMBaseTargetMachine>();
@@ -328,12 +346,10 @@ public:
void addIRPasses() override;
bool addPreISel() override;
bool addInstSelector() override;
-#ifdef LLVM_BUILD_GLOBAL_ISEL
bool addIRTranslator() override;
bool addLegalizeMachineIR() override;
bool addRegBankSelect() override;
bool addGlobalInstructionSelect() override;
-#endif
void addPreRegAlloc() override;
void addPreSched2() override;
void addPreEmitPass() override;
@@ -368,10 +384,11 @@ void ARMPassConfig::addIRPasses() {
// determine whether it succeeded. We can exploit existing control-flow in
// ldrex/strex loops to simplify this, but it needs tidying up.
if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy)
- addPass(createCFGSimplificationPass(-1, [this](const Function &F) {
- const auto &ST = this->TM->getSubtarget<ARMSubtarget>(F);
- return ST.hasAnyDataBarrier() && !ST.isThumb1Only();
- }));
+ addPass(createCFGSimplificationPass(
+ 1, false, false, true, true, [this](const Function &F) {
+ const auto &ST = this->TM->getSubtarget<ARMSubtarget>(F);
+ return ST.hasAnyDataBarrier() && !ST.isThumb1Only();
+ }));
TargetPassConfig::addIRPasses();
@@ -408,7 +425,6 @@ bool ARMPassConfig::addInstSelector() {
return false;
}
-#ifdef LLVM_BUILD_GLOBAL_ISEL
bool ARMPassConfig::addIRTranslator() {
addPass(new IRTranslator());
return false;
@@ -428,7 +444,6 @@ bool ARMPassConfig::addGlobalInstructionSelect() {
addPass(new InstructionSelect());
return false;
}
-#endif
void ARMPassConfig::addPreRegAlloc() {
if (getOptLevel() != CodeGenOpt::None) {