diff --git a/lib/Target/ARM/ARMInstrInfo.cpp b/lib/Target/ARM/ARMInstrInfo.cpp index 3f501a68ae1..de9ea48b265 100644 --- a/lib/Target/ARM/ARMInstrInfo.cpp +++ b/lib/Target/ARM/ARMInstrInfo.cpp @@ -423,6 +423,28 @@ ReverseBranchCondition(std::vector &Cond) const { return false; } +bool ARMInstrInfo::isPredicatable(MachineInstr *MI) const { + const TargetInstrDescriptor *TID = MI->getInstrDescriptor(); + if (TID->Flags & M_PREDICATED) + return true; + + unsigned Opc = MI->getOpcode(); + return Opc == ARM::B || Opc == ARM::tB; +} + +void ARMInstrInfo::PredicateInstruction(MachineInstr *MI, + std::vector &Cond) const { + unsigned Opc = MI->getOpcode(); + if (Opc == ARM::B || Opc == ARM::tB) { + MI->setInstrDescriptor(get(Opc == ARM::B ? ARM::Bcc : ARM::tBcc)); + MI->addImmOperand(Cond[0].getImmedValue()); + return; + } + + MachineOperand *PMO = MI->findFirstPredOperand(); + PMO->setImm(Cond[0].getImmedValue()); +} + /// FIXME: Works around a gcc miscompilation with -fstrict-aliasing static unsigned getNumJTEntries(const std::vector &JT, diff --git a/lib/Target/ARM/ARMInstrInfo.h b/lib/Target/ARM/ARMInstrInfo.h index ebec9e5a79b..d51b9bd74be 100644 --- a/lib/Target/ARM/ARMInstrInfo.h +++ b/lib/Target/ARM/ARMInstrInfo.h @@ -102,6 +102,11 @@ public: const std::vector &Cond) const; virtual bool BlockHasNoFallThrough(MachineBasicBlock &MBB) const; virtual bool ReverseBranchCondition(std::vector &Cond) const; + + // Predication support. + virtual bool isPredicatable(MachineInstr *MI) const; + virtual void PredicateInstruction(MachineInstr *MI, + std::vector &Cond) const; }; // Utility routines diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp index 3815875b22a..57b644026db 100644 --- a/lib/Target/ARM/ARMTargetMachine.cpp +++ b/lib/Target/ARM/ARMTargetMachine.cpp @@ -17,6 +17,7 @@ #include "ARM.h" #include "llvm/Module.h" #include "llvm/PassManager.h" +#include "llvm/CodeGen/Passes.h" #include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetMachineRegistry.h" #include "llvm/Target/TargetOptions.h" @@ -24,6 +25,8 @@ using namespace llvm; static cl::opt DisableLdStOpti("disable-arm-loadstore-opti", cl::Hidden, cl::desc("Disable load store optimization pass")); +static cl::opt EnableIfConversion("enable-arm-if-conversion", cl::Hidden, + cl::desc("Enable if-conversion pass")); namespace { // Register the target. @@ -85,6 +88,14 @@ bool ARMTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) { return false; } +bool ARMTargetMachine::addPostRegAlloc(FunctionPassManager &PM, bool Fast) { + if (Fast || !EnableIfConversion || Subtarget.isThumb()) + return false; + + PM.add(createIfConverterPass()); + return true; +} + bool ARMTargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) { // FIXME: temporarily disabling load / store optimization pass for Thumb mode. if (!Fast && !DisableLdStOpti && !Subtarget.isThumb()) diff --git a/lib/Target/ARM/ARMTargetMachine.h b/lib/Target/ARM/ARMTargetMachine.h index a50275c675f..dcdd1285f54 100644 --- a/lib/Target/ARM/ARMTargetMachine.h +++ b/lib/Target/ARM/ARMTargetMachine.h @@ -53,6 +53,7 @@ public: // Pass Pipeline Configuration virtual bool addInstSelector(FunctionPassManager &PM, bool Fast); + virtual bool addPostRegAlloc(FunctionPassManager &PM, bool Fast); virtual bool addPreEmitPass(FunctionPassManager &PM, bool Fast); virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast, std::ostream &Out);