llvm.org GIT mirror llvm / fa6bc2e
[ARM] Pass a callback to FunctionPass constructors to enable skipping execution on a per-function basis. Previously some of the passes were conditionally added to ARM's pass pipeline based on the target machine's subtarget. This patch makes changes to add those passes unconditionally and execute them conditonally based on the predicate functor passed to the pass constructors. This enables running different sets of passes for different functions in the module. rdar://problem/20542263 Differential Revision: http://reviews.llvm.org/D8717 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239325 91177308-0d34-0410-b5e6-96231b3b80d8 Akira Hatanaka 5 years ago
9 changed file(s) with 100 addition(s) and 29 deletion(s). Raw diff Collapse all Expand all
2020
2121 namespace llvm {
2222
23 class FunctionPass;
2423 class MachineFunctionPass;
2524 class PassConfigImpl;
2625 class PassInfo;
518517 /// IfConverter - This pass performs machine code if conversion.
519518 extern char &IfConverterID;
520519
520 FunctionPass *createIfConverter(std::function Ftor);
521
521522 /// MachineBlockPlacement - This pass places basic blocks based on branch
522523 /// probabilities.
523524 extern char &MachineBlockPlacementID;
611612
612613 /// UnpackMachineBundles - This pass unpack machine instruction bundles.
613614 extern char &UnpackMachineBundlesID;
615
616 FunctionPass *
617 createUnpackMachineBundles(std::function Ftor);
614618
615619 /// FinalizeMachineBundles - This pass finalize machine instruction
616620 /// bundles (created earlier, e.g. during pre-RA scheduling).
1515 #define LLVM_TRANSFORMS_SCALAR_H
1616
1717 #include "llvm/ADT/StringRef.h"
18 #include
1819
1920 namespace llvm {
2021
2122 class BasicBlockPass;
23 class Function;
2224 class FunctionPass;
2325 class ModulePass;
2426 class Pass;
244246 // CFGSimplification - Merge basic blocks, eliminate unreachable blocks,
245247 // simplify terminator instructions, etc...
246248 //
247 FunctionPass *createCFGSimplificationPass(int Threshold = -1);
249 FunctionPass *createCFGSimplificationPass(
250 int Threshold = -1, std::function Ftor = nullptr);
248251
249252 //===----------------------------------------------------------------------===//
250253 //
169169 bool PreRegAlloc;
170170 bool MadeChange;
171171 int FnNum;
172 std::function PredicateFtor;
173
172174 public:
173175 static char ID;
174 IfConverter() : MachineFunctionPass(ID), FnNum(-1) {
176 IfConverter(std::function Ftor = nullptr)
177 : MachineFunctionPass(ID), FnNum(-1), PredicateFtor(Ftor) {
175178 initializeIfConverterPass(*PassRegistry::getPassRegistry());
176179 }
177180
269272 INITIALIZE_PASS_END(IfConverter, "if-converter", "If Converter", false, false)
270273
271274 bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
275 if (PredicateFtor && !PredicateFtor(*MF.getFunction()))
276 return false;
277
272278 const TargetSubtargetInfo &ST = MF.getSubtarget();
273279 TLI = ST.getTargetLowering();
274280 TII = ST.getInstrInfo();
16901696 ToBBI.IsAnalyzed = false;
16911697 FromBBI.IsAnalyzed = false;
16921698 }
1699
1700 FunctionPass *
1701 llvm::createIfConverter(std::function Ftor) {
1702 return new IfConverter(Ftor);
1703 }
2222 class UnpackMachineBundles : public MachineFunctionPass {
2323 public:
2424 static char ID; // Pass identification
25 UnpackMachineBundles() : MachineFunctionPass(ID) {
25 UnpackMachineBundles(std::function Ftor = nullptr)
26 : MachineFunctionPass(ID), PredicateFtor(Ftor) {
2627 initializeUnpackMachineBundlesPass(*PassRegistry::getPassRegistry());
2728 }
2829
2930 bool runOnMachineFunction(MachineFunction &MF) override;
31
32 private:
33 std::function PredicateFtor;
3034 };
3135 } // end anonymous namespace
3236
3640 "Unpack machine instruction bundles", false, false)
3741
3842 bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) {
43 if (PredicateFtor && !PredicateFtor(*MF.getFunction()))
44 return false;
45
3946 bool Changed = false;
4047 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
4148 MachineBasicBlock *MBB = &*I;
6875 return Changed;
6976 }
7077
78 FunctionPass *
79 llvm::createUnpackMachineBundles(std::function Ftor) {
80 return new UnpackMachineBundles(Ftor);
81 }
7182
7283 namespace {
7384 class FinalizeMachineBundles : public MachineFunctionPass {
1515 #define LLVM_LIB_TARGET_ARM_ARM_H
1616
1717 #include "llvm/Support/CodeGen.h"
18 #include
1819
1920 namespace llvm {
2021
2122 class ARMAsmPrinter;
2223 class ARMBaseTargetMachine;
24 class Function;
2325 class FunctionPass;
2426 class ImmutablePass;
2527 class MachineInstr;
3739 FunctionPass *createMLxExpansionPass();
3840 FunctionPass *createThumb2ITBlockPass();
3941 FunctionPass *createARMOptimizeBarriersPass();
40 FunctionPass *createThumb2SizeReductionPass();
42 FunctionPass *createThumb2SizeReductionPass(
43 std::function Ftor = nullptr);
4144
4245 void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
4346 ARMAsmPrinter &AP);
303303 return getTM();
304304 }
305305
306 const ARMSubtarget &getARMSubtarget() const {
307 return *getARMTargetMachine().getSubtargetImpl();
308 }
309
310306 void addIRPasses() override;
311307 bool addPreISel() override;
312308 bool addInstSelector() override;
329325 // Cmpxchg instructions are often used with a subsequent comparison to
330326 // determine whether it succeeded. We can exploit existing control-flow in
331327 // ldrex/strex loops to simplify this, but it needs tidying up.
332 const ARMSubtarget *Subtarget = &getARMSubtarget();
333 if (Subtarget->hasAnyDataBarrier() && !Subtarget->isThumb1Only())
334 if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy)
335 addPass(createCFGSimplificationPass());
328 if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy)
329 addPass(createCFGSimplificationPass(-1, [this](const Function &F) {
330 const auto &ST = this->TM->getSubtarget(F);
331 return ST.hasAnyDataBarrier() && !ST.isThumb1Only();
332 }));
336333
337334 TargetPassConfig::addIRPasses();
338335 }
389386
390387 if (getOptLevel() != CodeGenOpt::None) {
391388 // in v8, IfConversion depends on Thumb instruction widths
392 if (getARMSubtarget().restrictIT())
393 addPass(createThumb2SizeReductionPass());
394 if (!getARMSubtarget().isThumb1Only())
395 addPass(&IfConverterID);
389 addPass(createThumb2SizeReductionPass([this](const Function &F) {
390 return this->TM->getSubtarget(F).restrictIT();
391 }));
392
393 addPass(createIfConverter([this](const Function &F) {
394 return !this->TM->getSubtarget(F).isThumb1Only();
395 }));
396396 }
397397 addPass(createThumb2ITBlockPass());
398398 }
401401 addPass(createThumb2SizeReductionPass());
402402
403403 // Constant island pass work on unbundled instructions.
404 if (getARMSubtarget().isThumb2())
405 addPass(&UnpackMachineBundlesID);
404 addPass(createUnpackMachineBundles([this](const Function &F) {
405 return this->TM->getSubtarget(F).isThumb2();
406 }));
406407
407408 // Don't optimize barriers at -O0.
408409 if (getOptLevel() != CodeGenOpt::None)
132132 class Thumb2SizeReduce : public MachineFunctionPass {
133133 public:
134134 static char ID;
135 Thumb2SizeReduce();
135 Thumb2SizeReduce(std::function Ftor);
136136
137137 const Thumb2InstrInfo *TII;
138138 const ARMSubtarget *STI;
197197 };
198198
199199 SmallVector BlockInfo;
200
201 std::function PredicateFtor;
200202 };
201203 char Thumb2SizeReduce::ID = 0;
202204 }
203205
204 Thumb2SizeReduce::Thumb2SizeReduce() : MachineFunctionPass(ID) {
206 Thumb2SizeReduce::Thumb2SizeReduce(std::function Ftor)
207 : MachineFunctionPass(ID), PredicateFtor(Ftor) {
205208 OptimizeSize = MinimizeSize = false;
206209 for (unsigned i = 0, e = array_lengthof(ReduceTable); i != e; ++i) {
207210 unsigned FromOpc = ReduceTable[i].WideOpc;
9991002 }
10001003
10011004 bool Thumb2SizeReduce::runOnMachineFunction(MachineFunction &MF) {
1005 if (PredicateFtor && !PredicateFtor(*MF.getFunction()))
1006 return false;
1007
10021008 STI = &static_cast(MF.getSubtarget());
10031009 if (STI->isThumb1Only() || STI->prefers32BitThumb())
10041010 return false;
10241030
10251031 /// createThumb2SizeReductionPass - Returns an instance of the Thumb2 size
10261032 /// reduction pass.
1027 FunctionPass *llvm::createThumb2SizeReductionPass() {
1028 return new Thumb2SizeReduce();
1029 }
1033 FunctionPass *llvm::createThumb2SizeReductionPass(
1034 std::function Ftor) {
1035 return new Thumb2SizeReduce(Ftor);
1036 }
192192 struct CFGSimplifyPass : public FunctionPass {
193193 static char ID; // Pass identification, replacement for typeid
194194 unsigned BonusInstThreshold;
195 CFGSimplifyPass(int T = -1) : FunctionPass(ID) {
195 std::function PredicateFtor;
196
197 CFGSimplifyPass(int T = -1,
198 std::function Ftor = nullptr)
199 : FunctionPass(ID), PredicateFtor(Ftor) {
196200 BonusInstThreshold = (T == -1) ? UserBonusInstThreshold : unsigned(T);
197201 initializeCFGSimplifyPassPass(*PassRegistry::getPassRegistry());
198202 }
199203 bool runOnFunction(Function &F) override {
204 if (PredicateFtor && !PredicateFtor(F))
205 return false;
206
200207 if (skipOptnoneFunction(F))
201208 return false;
202209
223230 false)
224231
225232 // Public interface to the CFGSimplification pass
226 FunctionPass *llvm::createCFGSimplificationPass(int Threshold) {
227 return new CFGSimplifyPass(Threshold);
228 }
229
233 FunctionPass *
234 llvm::createCFGSimplificationPass(int Threshold,
235 std::function Ftor) {
236 return new CFGSimplifyPass(Threshold, Ftor);
237 }
238
0 ; RUN: llc -march thumb %s -o - | FileCheck %s
1
2 ; This test checks that if-conversion pass is unconditionally added to the pass
3 ; pipeline and is conditionally executed based on the per-function targert-cpu
4 ; attribute.
5
6 ; CHECK: ite eq
7
8 define i32 @test_ifcvt(i32 %a, i32 %b) #0 {
9 %tmp2 = icmp eq i32 %a, 0
10 br i1 %tmp2, label %cond_false, label %cond_true
11
12 cond_true:
13 %tmp5 = add i32 %b, 1
14 ret i32 %tmp5
15
16 cond_false:
17 %tmp7 = add i32 %b, -1
18 ret i32 %tmp7
19 }
20
21 attributes #0 = { "target-cpu"="cortex-a8" }