aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/ARM/ARMSubtarget.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/ARMSubtarget.cpp
parenteb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff)
Notes
Diffstat (limited to 'lib/Target/ARM/ARMSubtarget.cpp')
-rw-r--r--lib/Target/ARM/ARMSubtarget.cpp108
1 files changed, 32 insertions, 76 deletions
diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp
index 2c42a1336166..4d4a88126ce6 100644
--- a/lib/Target/ARM/ARMSubtarget.cpp
+++ b/lib/Target/ARM/ARMSubtarget.cpp
@@ -13,11 +13,9 @@
#include "ARM.h"
-#ifdef LLVM_BUILD_GLOBAL_ISEL
#include "ARMCallLowering.h"
#include "ARMLegalizerInfo.h"
#include "ARMRegisterBankInfo.h"
-#endif
#include "ARMSubtarget.h"
#include "ARMFrameLowering.h"
#include "ARMInstrInfo.h"
@@ -30,13 +28,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
-#ifdef LLVM_BUILD_GLOBAL_ISEL
-#include "llvm/CodeGen/GlobalISel/GISelAccessor.h"
-#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
-#include "llvm/CodeGen/GlobalISel/Legalizer.h"
-#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
-#endif
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
@@ -46,8 +38,6 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/TargetParser.h"
#include "llvm/Target/TargetOptions.h"
-#include <cassert>
-#include <string>
using namespace llvm;
@@ -101,35 +91,6 @@ ARMFrameLowering *ARMSubtarget::initializeFrameLowering(StringRef CPU,
return new ARMFrameLowering(STI);
}
-#ifdef LLVM_BUILD_GLOBAL_ISEL
-namespace {
-
-struct ARMGISelActualAccessor : public GISelAccessor {
- std::unique_ptr<CallLowering> CallLoweringInfo;
- std::unique_ptr<InstructionSelector> InstSelector;
- std::unique_ptr<LegalizerInfo> Legalizer;
- std::unique_ptr<RegisterBankInfo> RegBankInfo;
-
- const CallLowering *getCallLowering() const override {
- return CallLoweringInfo.get();
- }
-
- const InstructionSelector *getInstructionSelector() const override {
- return InstSelector.get();
- }
-
- const LegalizerInfo *getLegalizerInfo() const override {
- return Legalizer.get();
- }
-
- const RegisterBankInfo *getRegBankInfo() const override {
- return RegBankInfo.get();
- }
-};
-
-} // end anonymous namespace
-#endif
-
ARMSubtarget::ARMSubtarget(const Triple &TT, const std::string &CPU,
const std::string &FS,
const ARMBaseTargetMachine &TM, bool IsLittle)
@@ -144,47 +105,35 @@ ARMSubtarget::ARMSubtarget(const Triple &TT, const std::string &CPU,
? (ARMBaseInstrInfo *)new ARMInstrInfo(*this)
: (ARMBaseInstrInfo *)new Thumb2InstrInfo(*this)),
TLInfo(TM, *this) {
- assert((isThumb() || hasARMOps()) &&
- "Target must either be thumb or support ARM operations!");
-#ifndef LLVM_BUILD_GLOBAL_ISEL
- GISelAccessor *GISel = new GISelAccessor();
-#else
- ARMGISelActualAccessor *GISel = new ARMGISelActualAccessor();
- GISel->CallLoweringInfo.reset(new ARMCallLowering(*getTargetLowering()));
- GISel->Legalizer.reset(new ARMLegalizerInfo(*this));
+ CallLoweringInfo.reset(new ARMCallLowering(*getTargetLowering()));
+ Legalizer.reset(new ARMLegalizerInfo(*this));
auto *RBI = new ARMRegisterBankInfo(*getRegisterInfo());
// FIXME: At this point, we can't rely on Subtarget having RBI.
// It's awkward to mix passing RBI and the Subtarget; should we pass
// TII/TRI as well?
- GISel->InstSelector.reset(createARMInstructionSelector(
+ InstSelector.reset(createARMInstructionSelector(
*static_cast<const ARMBaseTargetMachine *>(&TM), *this, *RBI));
- GISel->RegBankInfo.reset(RBI);
-#endif
- setGISelAccessor(*GISel);
+ RegBankInfo.reset(RBI);
}
const CallLowering *ARMSubtarget::getCallLowering() const {
- assert(GISel && "Access to GlobalISel APIs not set");
- return GISel->getCallLowering();
+ return CallLoweringInfo.get();
}
const InstructionSelector *ARMSubtarget::getInstructionSelector() const {
- assert(GISel && "Access to GlobalISel APIs not set");
- return GISel->getInstructionSelector();
+ return InstSelector.get();
}
const LegalizerInfo *ARMSubtarget::getLegalizerInfo() const {
- assert(GISel && "Access to GlobalISel APIs not set");
- return GISel->getLegalizerInfo();
+ return Legalizer.get();
}
const RegisterBankInfo *ARMSubtarget::getRegBankInfo() const {
- assert(GISel && "Access to GlobalISel APIs not set");
- return GISel->getRegBankInfo();
+ return RegBankInfo.get();
}
bool ARMSubtarget::isXRaySupported() const {
@@ -196,7 +145,9 @@ void ARMSubtarget::initializeEnvironment() {
// MCAsmInfo isn't always present (e.g. in opt) so we can't initialize this
// directly from it, but we can try to make sure they're consistent when both
// available.
- UseSjLjEH = isTargetDarwin() && !isTargetWatchABI();
+ UseSjLjEH = (isTargetDarwin() && !isTargetWatchABI() &&
+ Options.ExceptionModel == ExceptionHandling::None) ||
+ Options.ExceptionModel == ExceptionHandling::SjLj;
assert((!TM.getMCAsmInfo() ||
(TM.getMCAsmInfo()->getExceptionHandlingType() ==
ExceptionHandling::SjLj) == UseSjLjEH) &&
@@ -209,11 +160,11 @@ void ARMSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
if (isTargetDarwin()) {
StringRef ArchName = TargetTriple.getArchName();
- unsigned ArchKind = ARM::parseArch(ArchName);
- if (ArchKind == ARM::AK_ARMV7S)
+ ARM::ArchKind AK = ARM::parseArch(ArchName);
+ if (AK == ARM::ArchKind::ARMV7S)
// Default to the Swift CPU when targeting armv7s/thumbv7s.
CPUString = "swift";
- else if (ArchKind == ARM::AK_ARMV7K)
+ else if (AK == ARM::ArchKind::ARMV7K)
// Default to the Cortex-a7 CPU when targeting armv7k/thumbv7k.
// ARMv7k does not use SjLj exception handling.
CPUString = "cortex-a7";
@@ -265,8 +216,8 @@ void ARMSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
// baseline, since the LDM/POP instruction on Thumb doesn't take LR. This
// means if we need to reload LR, it takes extra instructions, which outweighs
// the value of the tail call; but here we don't know yet whether LR is going
- // to be used. We generate the tail call here and turn it back into CALL/RET
- // in emitEpilogue if LR is used.
+ // to be used. We take the optimistic approach of generating the tail call and
+ // perhaps taking a hit if we need to restore the LR.
// Thumb1 PIC calls to external symbols use BX, so they can be tail calls,
// but we need to make sure there are enough registers; the only valid
@@ -325,16 +276,18 @@ void ARMSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
case CortexA32:
case CortexA35:
case CortexA53:
+ case CortexA55:
case CortexA57:
case CortexA72:
case CortexA73:
+ case CortexA75:
case CortexR4:
case CortexR4F:
case CortexR5:
case CortexR7:
case CortexM3:
- case ExynosM1:
case CortexR52:
+ case ExynosM1:
case Kryo:
break;
case Krait:
@@ -386,6 +339,11 @@ bool ARMSubtarget::isGVIndirectSymbol(const GlobalValue *GV) const {
return false;
}
+bool ARMSubtarget::isGVInGOT(const GlobalValue *GV) const {
+ return isTargetELF() && TM.isPositionIndependent() &&
+ !TM.shouldAssumeDSOLocal(*GV->getParent(), GV);
+}
+
unsigned ARMSubtarget::getMispredictionPenalty() const {
return SchedModel.MispredictPenalty;
}
@@ -396,19 +354,17 @@ bool ARMSubtarget::hasSinCos() const {
}
bool ARMSubtarget::enableMachineScheduler() const {
- // Enable the MachineScheduler before register allocation for out-of-order
- // architectures where we do not use the PostRA scheduler anymore (for now
- // restricted to swift).
- return getSchedModel().isOutOfOrder() && isSwift();
+ // Enable the MachineScheduler before register allocation for subtargets
+ // with the use-misched feature.
+ return useMachineScheduler();
}
// This overrides the PostRAScheduler bit in the SchedModel for any CPU.
bool ARMSubtarget::enablePostRAScheduler() const {
- // No need for PostRA scheduling on out of order CPUs (for now restricted to
- // swift).
- if (getSchedModel().isOutOfOrder() && isSwift())
+ if (disablePostRAScheduler())
return false;
- return (!isThumb() || hasThumb2());
+ // Don't reschedule potential IT blocks.
+ return !isThumb1Only();
}
bool ARMSubtarget::enableAtomicExpand() const { return hasAnyDataBarrier(); }
@@ -417,7 +373,7 @@ bool ARMSubtarget::useStride4VFPs(const MachineFunction &MF) const {
// For general targets, the prologue can grow when VFPs are allocated with
// stride 4 (more vpush instructions). But WatchOS uses a compact unwind
// format which it's more important to get right.
- return isTargetWatchABI() || (isSwift() && !MF.getFunction()->optForMinSize());
+ return isTargetWatchABI() || (isSwift() && !MF.getFunction().optForMinSize());
}
bool ARMSubtarget::useMovt(const MachineFunction &MF) const {
@@ -425,7 +381,7 @@ bool ARMSubtarget::useMovt(const MachineFunction &MF) const {
// immediates as it is inherently position independent, and may be out of
// range otherwise.
return !NoMovt && hasV8MBaselineOps() &&
- (isTargetWindows() || !MF.getFunction()->optForMinSize() || genExecuteOnly());
+ (isTargetWindows() || !MF.getFunction().optForMinSize() || genExecuteOnly());
}
bool ARMSubtarget::useFastISel() const {