Index: include/llvm/CodeGen/Passes.h =================================================================== --- include/llvm/CodeGen/Passes.h +++ include/llvm/CodeGen/Passes.h @@ -21,7 +21,6 @@ namespace llvm { -class FunctionPass; class MachineFunctionPass; class PassConfigImpl; class PassInfo; @@ -501,6 +500,8 @@ /// IfConverter - This pass performs machine code if conversion. extern char &IfConverterID; + FunctionPass *createIfConverter(FunctionPass::PredicateFtorTy Ftor); + /// MachineBlockPlacement - This pass places basic blocks based on branch /// probabilities. extern char &MachineBlockPlacementID; @@ -595,6 +596,8 @@ /// UnpackMachineBundles - This pass unpack machine instruction bundles. extern char &UnpackMachineBundlesID; + FunctionPass *createUnpackMachineBundles(FunctionPass::PredicateFtorTy Ftor); + /// FinalizeMachineBundles - This pass finalize machine instruction /// bundles (created earlier, e.g. during pre-RA scheduling). extern char &FinalizeMachineBundlesID; Index: include/llvm/Pass.h =================================================================== --- include/llvm/Pass.h +++ include/llvm/Pass.h @@ -30,6 +30,7 @@ #define LLVM_PASS_H #include "llvm/Support/Compiler.h" +#include #include namespace llvm { @@ -309,6 +310,8 @@ /// Return what kind of Pass Manager can manage this pass. PassManagerType getPotentialPassManagerType() const override; + typedef std::function PredicateFtorTy; + protected: /// skipOptnoneFunction - This function has Attribute::OptimizeNone /// and most transformation passes should skip it. Index: include/llvm/Transforms/Scalar.h =================================================================== --- include/llvm/Transforms/Scalar.h +++ include/llvm/Transforms/Scalar.h @@ -15,12 +15,12 @@ #ifndef LLVM_TRANSFORMS_SCALAR_H #define LLVM_TRANSFORMS_SCALAR_H +#include "llvm/Pass.h" #include "llvm/ADT/StringRef.h" namespace llvm { class BasicBlockPass; -class FunctionPass; class ModulePass; class Pass; class GetElementPtrInst; @@ -238,7 +238,9 @@ // CFGSimplification - Merge basic blocks, eliminate unreachable blocks, // simplify terminator instructions, etc... // -FunctionPass *createCFGSimplificationPass(int Threshold = -1); +FunctionPass * +createCFGSimplificationPass(int Threshold = -1, + FunctionPass::PredicateFtorTy Ftor = nullptr); //===----------------------------------------------------------------------===// // Index: lib/CodeGen/IfConversion.cpp =================================================================== --- lib/CodeGen/IfConversion.cpp +++ lib/CodeGen/IfConversion.cpp @@ -171,9 +171,12 @@ bool PreRegAlloc; bool MadeChange; int FnNum; + FunctionPass::PredicateFtorTy PredicateFtor; + public: static char ID; - IfConverter() : MachineFunctionPass(ID), FnNum(-1) { + IfConverter(FunctionPass::PredicateFtorTy Ftor = nullptr) + : MachineFunctionPass(ID), FnNum(-1), PredicateFtor(Ftor) { initializeIfConverterPass(*PassRegistry::getPassRegistry()); } @@ -271,6 +274,9 @@ INITIALIZE_PASS_END(IfConverter, "if-converter", "If Converter", false, false) bool IfConverter::runOnMachineFunction(MachineFunction &MF) { + if (PredicateFtor && !PredicateFtor(*MF.getFunction())) + return false; + const TargetSubtargetInfo &ST = MF.getSubtarget(); TLI = ST.getTargetLowering(); TII = ST.getInstrInfo(); @@ -1681,3 +1687,7 @@ ToBBI.IsAnalyzed = false; FromBBI.IsAnalyzed = false; } + +FunctionPass *llvm::createIfConverter(FunctionPass::PredicateFtorTy Ftor) { + return new IfConverter(Ftor); +} Index: lib/CodeGen/MachineInstrBundle.cpp =================================================================== --- lib/CodeGen/MachineInstrBundle.cpp +++ lib/CodeGen/MachineInstrBundle.cpp @@ -23,11 +23,15 @@ class UnpackMachineBundles : public MachineFunctionPass { public: static char ID; // Pass identification - UnpackMachineBundles() : MachineFunctionPass(ID) { + UnpackMachineBundles(FunctionPass::PredicateFtorTy Ftor = nullptr) + : MachineFunctionPass(ID), PredicateFtor(Ftor) { initializeUnpackMachineBundlesPass(*PassRegistry::getPassRegistry()); } bool runOnMachineFunction(MachineFunction &MF) override; + + private: + FunctionPass::PredicateFtorTy PredicateFtor; }; } // end anonymous namespace @@ -37,6 +41,9 @@ "Unpack machine instruction bundles", false, false) bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) { + if (PredicateFtor && !PredicateFtor(*MF.getFunction())) + return false; + bool Changed = false; for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { MachineBasicBlock *MBB = &*I; @@ -69,6 +76,10 @@ return Changed; } +FunctionPass * +llvm::createUnpackMachineBundles(FunctionPass::PredicateFtorTy Ftor) { + return new UnpackMachineBundles(Ftor); +} namespace { class FinalizeMachineBundles : public MachineFunctionPass { Index: lib/CodeGen/Passes.cpp =================================================================== --- lib/CodeGen/Passes.cpp +++ lib/CodeGen/Passes.cpp @@ -292,6 +292,24 @@ if (verifyAfter) addVerifyPass(Banner); } + + // Add the passes after the pass P if there is any. + for (SmallVectorImpl >::iterator + I = Impl->InsertedPasses.begin(), + E = Impl->InsertedPasses.end(); + I != E; ++I) { + if ((*I).first == PassID) { + assert((*I).second.isValid() && "Illegal Pass ID!"); + Pass *NP; + if ((*I).second.isInstance()) + NP = (*I).second.getInstance(); + else { + NP = Pass::createPass((*I).second.getID()); + assert(NP && "Pass ID not registered"); + } + addPass(NP, false, false); + } + } } else { delete P; } @@ -326,22 +344,6 @@ AnalysisID FinalID = P->getPassID(); addPass(P, verifyAfter, printAfter); // Ends the lifetime of P. - // Add the passes after the pass P if there is any. - for (SmallVectorImpl >::iterator - I = Impl->InsertedPasses.begin(), E = Impl->InsertedPasses.end(); - I != E; ++I) { - if ((*I).first == PassID) { - assert((*I).second.isValid() && "Illegal Pass ID!"); - Pass *NP; - if ((*I).second.isInstance()) - NP = (*I).second.getInstance(); - else { - NP = Pass::createPass((*I).second.getID()); - assert(NP && "Pass ID not registered"); - } - addPass(NP, false, false); - } - } return FinalID; } Index: lib/Target/ARM/ARM.h =================================================================== --- lib/Target/ARM/ARM.h +++ lib/Target/ARM/ARM.h @@ -15,13 +15,13 @@ #ifndef LLVM_LIB_TARGET_ARM_ARM_H #define LLVM_LIB_TARGET_ARM_ARM_H +#include "llvm/Pass.h" #include "llvm/Support/CodeGen.h" namespace llvm { class ARMAsmPrinter; class ARMBaseTargetMachine; -class FunctionPass; class ImmutablePass; class MachineInstr; class MCInst; @@ -38,7 +38,8 @@ FunctionPass *createMLxExpansionPass(); FunctionPass *createThumb2ITBlockPass(); FunctionPass *createARMOptimizeBarriersPass(); -FunctionPass *createThumb2SizeReductionPass(); +FunctionPass * +createThumb2SizeReductionPass(FunctionPass::PredicateFtorTy Ftor = nullptr); void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, ARMAsmPrinter &AP); Index: lib/Target/ARM/ARMTargetMachine.cpp =================================================================== --- lib/Target/ARM/ARMTargetMachine.cpp +++ lib/Target/ARM/ARMTargetMachine.cpp @@ -297,10 +297,6 @@ return getTM(); } - const ARMSubtarget &getARMSubtarget() const { - return *getARMTargetMachine().getSubtargetImpl(); - } - void addIRPasses() override; bool addPreISel() override; bool addInstSelector() override; @@ -323,10 +319,11 @@ // Cmpxchg instructions are often used with a subsequent comparison to // determine whether it succeeded. We can exploit existing control-flow in // ldrex/strex loops to simplify this, but it needs tidying up. - const ARMSubtarget *Subtarget = &getARMSubtarget(); - if (Subtarget->hasAnyDataBarrier() && !Subtarget->isThumb1Only()) - if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy) - addPass(createCFGSimplificationPass()); + if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy) + addPass(createCFGSimplificationPass(-1, [this](const Function &F) { + const auto &ST = this->TM->getSubtarget(F); + return ST.hasAnyDataBarrier() && !ST.isThumb1Only(); + })); TargetPassConfig::addIRPasses(); } @@ -378,10 +375,13 @@ if (getOptLevel() != CodeGenOpt::None) { // in v8, IfConversion depends on Thumb instruction widths - if (getARMSubtarget().restrictIT()) - addPass(createThumb2SizeReductionPass()); - if (!getARMSubtarget().isThumb1Only()) - addPass(&IfConverterID); + addPass(createThumb2SizeReductionPass([this](const Function &F) { + return this->TM->getSubtarget(F).restrictIT(); + })); + + addPass(createIfConverter([this](const Function &F) { + return !this->TM->getSubtarget(F).isThumb1Only(); + })); } addPass(createThumb2ITBlockPass()); } @@ -390,8 +390,9 @@ addPass(createThumb2SizeReductionPass()); // Constant island pass work on unbundled instructions. - if (getARMSubtarget().isThumb2()) - addPass(&UnpackMachineBundlesID); + addPass(createUnpackMachineBundles([this](const Function &F) { + return this->TM->getSubtarget(F).isThumb2(); + })); addPass(createARMOptimizeBarriersPass()); addPass(createARMConstantIslandPass()); Index: lib/Target/ARM/Thumb2SizeReduction.cpp =================================================================== --- lib/Target/ARM/Thumb2SizeReduction.cpp +++ lib/Target/ARM/Thumb2SizeReduction.cpp @@ -133,7 +133,7 @@ class Thumb2SizeReduce : public MachineFunctionPass { public: static char ID; - Thumb2SizeReduce(); + Thumb2SizeReduce(FunctionPass::PredicateFtorTy Ftor); const Thumb2InstrInfo *TII; const ARMSubtarget *STI; @@ -198,11 +198,14 @@ }; SmallVector BlockInfo; + + FunctionPass::PredicateFtorTy PredicateFtor; }; char Thumb2SizeReduce::ID = 0; } -Thumb2SizeReduce::Thumb2SizeReduce() : MachineFunctionPass(ID) { +Thumb2SizeReduce::Thumb2SizeReduce(FunctionPass::PredicateFtorTy Ftor) + : MachineFunctionPass(ID), PredicateFtor(Ftor) { OptimizeSize = MinimizeSize = false; for (unsigned i = 0, e = array_lengthof(ReduceTable); i != e; ++i) { unsigned FromOpc = ReduceTable[i].WideOpc; @@ -1002,6 +1005,9 @@ } bool Thumb2SizeReduce::runOnMachineFunction(MachineFunction &MF) { + if (PredicateFtor && !PredicateFtor(*MF.getFunction())) + return false; + STI = &static_cast(MF.getSubtarget()); if (STI->isThumb1Only() || STI->prefers32BitThumb()) return false; @@ -1027,6 +1033,7 @@ /// createThumb2SizeReductionPass - Returns an instance of the Thumb2 size /// reduction pass. -FunctionPass *llvm::createThumb2SizeReductionPass() { - return new Thumb2SizeReduce(); +FunctionPass * +llvm::createThumb2SizeReductionPass(FunctionPass::PredicateFtorTy Ftor) { + return new Thumb2SizeReduce(Ftor); } Index: lib/Transforms/Scalar/SimplifyCFGPass.cpp =================================================================== --- lib/Transforms/Scalar/SimplifyCFGPass.cpp +++ lib/Transforms/Scalar/SimplifyCFGPass.cpp @@ -193,11 +193,17 @@ struct CFGSimplifyPass : public FunctionPass { static char ID; // Pass identification, replacement for typeid unsigned BonusInstThreshold; - CFGSimplifyPass(int T = -1) : FunctionPass(ID) { + FunctionPass::PredicateFtorTy PredicateFtor; + + CFGSimplifyPass(int T = -1, FunctionPass::PredicateFtorTy Ftor = nullptr) + : FunctionPass(ID), PredicateFtor(Ftor) { BonusInstThreshold = (T == -1) ? UserBonusInstThreshold : unsigned(T); initializeCFGSimplifyPassPass(*PassRegistry::getPassRegistry()); } bool runOnFunction(Function &F) override { + if (PredicateFtor && !PredicateFtor(F)) + return false; + if (skipOptnoneFunction(F)) return false; @@ -224,7 +230,9 @@ false) // Public interface to the CFGSimplification pass -FunctionPass *llvm::createCFGSimplificationPass(int Threshold) { - return new CFGSimplifyPass(Threshold); +FunctionPass * +llvm::createCFGSimplificationPass(int Threshold, + FunctionPass::PredicateFtorTy Ftor) { + return new CFGSimplifyPass(Threshold, Ftor); }