aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM/ARMSubtarget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/ARM/ARMSubtarget.cpp')
-rw-r--r--lib/Target/ARM/ARMSubtarget.cpp49
1 files changed, 34 insertions, 15 deletions
diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp
index e39c30e..1465984 100644
--- a/lib/Target/ARM/ARMSubtarget.cpp
+++ b/lib/Target/ARM/ARMSubtarget.cpp
@@ -13,6 +13,7 @@
#include "ARMSubtarget.h"
#include "ARMGenSubtarget.inc"
+#include "ARMBaseRegisterInfo.h"
#include "llvm/GlobalValue.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/CommandLine.h"
@@ -24,8 +25,7 @@ ReserveR9("arm-reserve-r9", cl::Hidden,
cl::desc("Reserve R9, making it unavailable as GPR"));
static cl::opt<bool>
-UseMOVT("arm-use-movt",
- cl::init(true), cl::Hidden);
+DarwinUseMOVT("arm-darwin-use-movt", cl::init(true), cl::Hidden);
static cl::opt<bool>
StrictAlign("arm-strict-align", cl::Hidden,
@@ -37,14 +37,14 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
, ARMProcFamily(Others)
, ARMFPUType(None)
, UseNEONForSinglePrecisionFP(false)
- , SlowVMLx(false)
+ , SlowFPVMLx(false)
, SlowFPBrcc(false)
, IsThumb(isT)
, ThumbMode(Thumb1)
, NoARM(false)
, PostRAScheduler(false)
, IsR9Reserved(ReserveR9)
- , UseMovt(UseMOVT)
+ , UseMovt(false)
, HasFP16(false)
, HasD16(false)
, HasHardwareDivide(false)
@@ -56,7 +56,7 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
, AllowsUnalignedMem(false)
, stackAlignment(4)
, CPUString("generic")
- , TargetType(isELF) // Default to ELF unless otherwise specified.
+ , TargetTriple(TT)
, TargetABI(ARM_ABI_APCS) {
// Default to soft float ABI
if (FloatABIType == FloatABI::Default)
@@ -118,12 +118,6 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
}
}
- if (Len >= 10) {
- if (TT.find("-darwin") != std::string::npos)
- // arm-darwin
- TargetType = isDarwin;
- }
-
if (TT.find("eabi") != std::string::npos)
TargetABI = ARM_ABI_AAPCS;
@@ -140,6 +134,9 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
FSWithArch = FS;
CPUString = ParseSubtargetFeatures(FSWithArch, CPUString);
+ // After parsing Itineraries, set ItinData.IssueWidth.
+ computeIssueWidth();
+
// Thumb2 implies at least V6T2.
if (ARMArchVersion >= V6T2)
ThumbMode = Thumb2;
@@ -149,8 +146,12 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
if (isAAPCS_ABI())
stackAlignment = 8;
- if (isTargetDarwin())
+ if (!isTargetDarwin())
+ UseMovt = hasV6T2Ops();
+ else {
IsR9Reserved = ReserveR9 | (ARMArchVersion < V6);
+ UseMovt = DarwinUseMOVT && hasV6T2Ops();
+ }
if (!isThumb() || hasThumb2())
PostRAScheduler = true;
@@ -170,7 +171,9 @@ ARMSubtarget::GVIsIndirectSymbol(const GlobalValue *GV,
// Materializable GVs (in JIT lazy compilation mode) do not require an extra
// load from stub.
- bool isDecl = GV->isDeclaration() && !GV->isMaterializable();
+ bool isDecl = GV->hasAvailableExternallyLinkage();
+ if (GV->isDeclaration() && !GV->isMaterializable())
+ isDecl = true;
if (!isTargetDarwin()) {
// Extra load is needed for all externally visible.
@@ -201,7 +204,7 @@ ARMSubtarget::GVIsIndirectSymbol(const GlobalValue *GV,
// through a stub.
if (!isDecl && !GV->isWeakForLinker())
return false;
-
+
// Unless we have a symbol with hidden visibility, we have to go through a
// normal $non_lazy_ptr stub because this symbol might be resolved late.
if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference.
@@ -219,11 +222,27 @@ unsigned ARMSubtarget::getMispredictionPenalty() const {
return 13;
else if (isCortexA9())
return 8;
-
+
// Otherwise, just return a sensible default.
return 10;
}
+void ARMSubtarget::computeIssueWidth() {
+ unsigned allStage1Units = 0;
+ for (const InstrItinerary *itin = InstrItins.Itineraries;
+ itin->FirstStage != ~0U; ++itin) {
+ const InstrStage *IS = InstrItins.Stages + itin->FirstStage;
+ allStage1Units |= IS->getUnits();
+ }
+ InstrItins.IssueWidth = 0;
+ while (allStage1Units) {
+ ++InstrItins.IssueWidth;
+ // clear the lowest bit
+ allStage1Units ^= allStage1Units & ~(allStage1Units - 1);
+ }
+ assert(InstrItins.IssueWidth <= 2 && "itinerary bug, too many stage 1 units");
+}
+
bool ARMSubtarget::enablePostRAScheduler(
CodeGenOpt::Level OptLevel,
TargetSubtarget::AntiDepBreakMode& Mode,