diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMSubtarget.cpp | 29 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMSubtarget.h | 6 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMTargetMachine.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/Thumb2ITBlockPass.cpp | 9 |
5 files changed, 42 insertions, 6 deletions
diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp index 7187d6a665b..b76ef9671bb 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -525,7 +525,7 @@ bool ARMBaseInstrInfo::isPredicable(MachineInstr *MI) const { MI->getParent()->getParent()->getInfo<ARMFunctionInfo>(); if (AFI->isThumb2Function()) { - if (getSubtarget().hasV8Ops()) + if (getSubtarget().restrictIT()) return isV8EligibleForIT(MI); } else { // non-Thumb if ((MI->getDesc().TSFlags & ARMII::DomainMask) == ARMII::DomainNEON) diff --git a/llvm/lib/Target/ARM/ARMSubtarget.cpp b/llvm/lib/Target/ARM/ARMSubtarget.cpp index f59e522195c..a11629852ad 100644 --- a/llvm/lib/Target/ARM/ARMSubtarget.cpp +++ b/llvm/lib/Target/ARM/ARMSubtarget.cpp @@ -57,6 +57,23 @@ Align(cl::desc("Load/store alignment support"), "Allow unaligned memory accesses"), clEnumValEnd)); +enum ITMode { + DefaultIT, + RestrictedIT, + NoRestrictedIT +}; + +static cl::opt<ITMode> +IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), + cl::ZeroOrMore, + cl::values(clEnumValN(DefaultIT, "arm-default-it", + "Generate IT block based on arch"), + clEnumValN(RestrictedIT, "arm-restrict-it", + "Disallow deprecated IT based on ARMv8"), + clEnumValN(NoRestrictedIT, "arm-no-restrict-it", + "Allow IT blocks based on ARMv7"), + clEnumValEnd)); + ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU, const std::string &FS, const TargetOptions &Options) : ARMGenSubtargetInfo(TT, CPU, FS) @@ -217,6 +234,18 @@ void ARMSubtarget::resetSubtargetFeatures(StringRef CPU, StringRef FS) { break; } + switch (IT) { + case DefaultIT: + RestrictIT = hasV8Ops() ? true : false; + break; + case RestrictedIT: + RestrictIT = true; + break; + case NoRestrictedIT: + RestrictIT = false; + break; + } + // NEON f32 ops are non-IEEE 754 compliant. Darwin is ok with it by default. uint64_t Bits = getFeatureBits(); if ((Bits & ARM::ProcA5 || Bits & ARM::ProcA8) && // Where this matters diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h index aab93f1d6c0..5276901bbb9 100644 --- a/llvm/lib/Target/ARM/ARMSubtarget.h +++ b/llvm/lib/Target/ARM/ARMSubtarget.h @@ -177,6 +177,10 @@ protected: /// ARMTargetLowering::allowsUnalignedMemoryAccesses(). bool AllowsUnalignedMem; + /// RestrictIT - If true, the subtarget disallows generation of deprecated IT + /// blocks to conform to ARMv8 rule. + bool RestrictIT; + /// Thumb2DSP - If true, the subtarget supports the v7 DSP (saturating arith /// and such) instructions in Thumb2 code. bool Thumb2DSP; @@ -327,6 +331,8 @@ public: bool allowsUnalignedMem() const { return AllowsUnalignedMem; } + bool restrictIT() const { return RestrictIT; } + const std::string & getCPUString() const { return CPUString; } unsigned getMispredictionPenalty() const; diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp index c78db54d8b0..c2bf7887787 100644 --- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp +++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp @@ -198,7 +198,7 @@ bool ARMPassConfig::addPreSched2() { if (getOptLevel() != CodeGenOpt::None) { if (!getARMSubtarget().isThumb1Only()) { // in v8, IfConversion depends on Thumb instruction widths - if (getARMSubtarget().hasV8Ops() && + if (getARMSubtarget().restrictIT() && !getARMSubtarget().prefers32BitThumb()) addPass(createThumb2SizeReductionPass()); addPass(&IfConverterID); diff --git a/llvm/lib/Target/ARM/Thumb2ITBlockPass.cpp b/llvm/lib/Target/ARM/Thumb2ITBlockPass.cpp index 8f1ae2eaf8f..0b7d3bb7754 100644 --- a/llvm/lib/Target/ARM/Thumb2ITBlockPass.cpp +++ b/llvm/lib/Target/ARM/Thumb2ITBlockPass.cpp @@ -28,7 +28,7 @@ namespace { static char ID; Thumb2ITBlockPass() : MachineFunctionPass(ID) {} - bool hasV8Ops; + bool restrictIT; const Thumb2InstrInfo *TII; const TargetRegisterInfo *TRI; ARMFunctionInfo *AFI; @@ -194,8 +194,9 @@ bool Thumb2ITBlockPass::InsertITInstructions(MachineBasicBlock &MBB) { ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC); unsigned Mask = 0, Pos = 3; - // v8 IT blocks are limited to one conditional op: skip the loop - if (!hasV8Ops) { + // v8 IT blocks are limited to one conditional op unless -arm-no-restrict-it + // is set: skip the loop + if (!restrictIT) { // Branches, including tricky ones like LDM_RET, need to end an IT // block so check the instruction we just put in the block. for (; MBBI != E && Pos && @@ -255,7 +256,7 @@ bool Thumb2ITBlockPass::runOnMachineFunction(MachineFunction &Fn) { AFI = Fn.getInfo<ARMFunctionInfo>(); TII = static_cast<const Thumb2InstrInfo*>(TM.getInstrInfo()); TRI = TM.getRegisterInfo(); - hasV8Ops = TM.getSubtarget<ARMSubtarget>().hasV8Ops(); + restrictIT = TM.getSubtarget<ARMSubtarget>().restrictIT(); if (!AFI->isThumbFunction()) return false; |