8 Passes
More details in LLVM’s Analysis and Transform Passes and Writing an LLVM Pass. There are three kinds of pass, Analysis passes, Transformation passes, Utility passes. IR Functions to Machinefunction Map.
8.1 MachineFunctionPass::runOnFunction(Function &F)
bool MachineFunctionPass::runOnFunction(Function &F) { if (F.hasAvailableExternallyLinkage()) return false; MachineModuleInfo &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); MachineFunction &MF = MMI.getOrCreateMachineFunction(F); MachineFunctionProperties &MFProps = MF.getProperties(); bool RV = runOnMachineFunction(MF); MFProps.set(SetProperties); MFProps.reset(ClearedProperties); return RV; }
8.2 There 107 distinct Passes for our example:
No. | Pass Name | Implementation | Usage |
---|---|---|---|
1 | Target Library Information | TargetLibraryInfoWrapperPass:ImmutablePass | Provide Target library information |
2 | Target Pass Configuration | TargetPassConfig:ImmutablePass | Expose TargetPassConfig for later pass to use |
3 | Machine Module Information | MachineModuleInfoWrapperPass:ImmutablePass | Expose meta information specific to a module |
4 | Target Transform Information | TargetTransformInfoWrapperPass:ImmutablePass | Provide access to the codegen interfaces |
5 | TypeBased Alias Analysis | TypeBasedAAWrapperPass:ImmutablePass | A simple AA result that uses TBAA metadata to answer queries |
6 | Scoped NoAlias Alias Analysis | ScopedNoAliasAAWrapperPass:ImmutablePass | A simple AA result which uses scoped-noalias metadata to answer queries. |
7 | Assumption Cache Tracker | AssumptionCacheTracker:ImmutablePass | tracks lazily created AssumptionCache objects. |
8 | Profile summary info | ProfileSummaryInfoWrapperPass:ImmutablePass | An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo. |
9 | Create Garbage Collector Module Metadata | GCModuleInfo:ImmutablePass | caches information about the entire Module. |
10 | Machine Branch Probability Analysis | MachineBranchProbabilityInfo:ImmutablePass | Calculate the branch probability between two MBB |
11 | ModulePass Manager | MPPassManager:Pass,PMDataManager | Manage module pass to run them in order |
12 | PreISel Intrinsic Lowering | PreISelIntrinsicLoweringLegacyPass:ModulePass:Pass | Lower some intrinsics into IR, particular for objc |
13 | FunctionPass Manager | FPPassManager:ModulePass,PMDataManager | Manage function pass to run them in order |
14 | Expand Atomic instructions | AtomicExpand:FunctionPass:Pass | Expand atomic IR instruction if TargetLowering support |
15 | Module Verifier | VerifierLegacyPass:FunctionPass | Verify the whole IR module |
16 | Dominator Tree Construction | DominatorTreeWrapperPass:FunctionPass | Construct Dominator tree for a function |
17 | Basic Alias Analysis (stateless AA impl) | BasicAAWrapperPass:FunctionPass | Do basic alias analyis on a function to determine if a storage location may be accessed in more than one way. Wiki |
18 | Natural Loop Information | LoopInfoWrapperPass:FunctionPass | The natural loop of the back edge is defined to be the smallest set of nodes that includes the back edge and has no predecessors outside the set except for the predecessor of the header. Natural Loops |
19 | Canonicalize natural loops | LoopSimplify:FunctionPass | Simplify natural loops |
20 | Scalar Evolution Analysis | ScalarEvolutionWrapperPass:FunctionPass | Scalar Evolution is an LLVM analysis that is used to analyse, categorize and simplify expressions in loops. Many optimizations such as - generalized loop-strength-reduction, parallelisation by induction variable (vectorization), and loop-invariant expression elimination - rely on SCEV analysis. Scalar Evolution Demystified |
21 | Loop Pass Manager | LPPassManager:FunctionPass,PMDataManager | Manage loop pass to run them in order |
22 | Canonicalize Freeze Instructions in Loops | CanonicalizeFreezeInLoops:LoopPass | |
23 | Induction Variable Users | IVUsersWrapperPass:LoopPass | Wiki Induction Variable |
24 | Loop Strength Reduction | LoopStrengthReduce:LoopPass | Strength Reduction |
25 | Function Alias Analysis Results | AAResultsWrapperPass:FunctionPass | Alias Analysis |
26 | Merge contiguous icmps into a memcmp | MergeICmpsLegacyPass:FunctionPass | Merge contiguous icmps into a memcmp |
27 | Lazy Branch Probability Analysis | LazyBranchProbabilityInfoPass:FunctionPass | |
28 | Lazy Block Frequency Analysis | LazyBlockFrequencyInfoPass:FunctionPass | |
29 | Expand memcmp() to load/stores | ExpandMemCmpPass:FunctionPass | Expand memcmp() to load/stores |
30 | Lower Garbage Collection Instructions | LowerIntrinsics:FunctionPass | GC in LLVM |
31 | Shadow Stack GC Lowering | ShadowStackGCLowering:FunctionPass | GC in LLVM |
32 | Lower constant intrinsics | LowerConstantIntrinsics:FunctionPass | Lower constant intrinsics |
33 | Remove unreachable blocks from the CFG | UnreachableBlockElimLegacyPass:FunctionPass | Remove unreachable blocks from the CFG |
34 | PostDominator Tree Construction | PostDominatorTreeWrapperPass:FunctionPass | |
35 | Branch Probability Analysis | BranchProbabilityInfoWrapperPass:FunctionPass | |
36 | Block Frequency Analysis | BlockFrequencyInfoWrapperPass:FunctionPass | |
37 | Constant Hoisting | ConstantHoistingLegacyPass:FunctionPass | |
38 | Partially inline calls to library functions | PartiallyInlineLibCallsLegacyPass:FunctionPass | |
39 | Instrument function entry/exit with calls | EntryExitInstrumenter:FunctionPass | |
40 | Scalarize Masked Memory Intrinsics | ScalarizeMaskedMemIntrin:FunctionPass | |
41 | Expand reduction intrinsics | ExpandReductions:FunctionPass | |
42 | CodeGen Prepare | CodeGenPrepare:FunctionPass | do some cleanup and preparation for codegen |
43 | Rewrite Symbols | RewriteSymbolsLegacyPass:ModulePass | Symbol rewrite |
44 | Exception handling preparation | DwarfEHPrepare:FunctionPass | Exception Handling in LLVM |
45 | Safe Stack instrumentation pass | SafeStackLegacyPass:FunctionPass | SafeStack |
46 | Insert stack protectors | StackProtector:FunctionPass | Buffer overflow protection |
47+ | RISCV DAG->DAG Pattern Instruction Selection | RISCVDAGToDAGISel:SelctionDAGISel:MachineFUnctionPass | More information in DAG-Based ISel, IR –> MachineInstr. Instruction selection and scheduling |
48 | Finalize ISel and expand pseudoinstructions | FinalizeISel:MachineFunctionPass | |
49 | Lazy Machine Block Frequency Analysis | LazyMachineBlockFrequencyInfoPass:MachineFunctionPass | |
50 | Early Tail Duplication | EarlyTailDuplicate:TailDuplicateBase:MachineFunctionPass | Tail Duplication with LLVM |
51 | Optimize machine instruction PHIs | OptimizePHIs:MachineFunctionPass | |
52 | Slot index numbering | SlotIndexes:MachineFunctionPass | |
53 | Merge disjoint stack slots | StackColoring:MachineFunctionPass | |
54 | Local Stack Slot Allocation | LocalStackSlotPass:MachineFunctionPass | |
55 | Remove dead machine instructions | DeadMachineInstructionElim:MachineFunctionPass | |
56 | MachineDominator Tree Construction | MachineDominatorTree:MachineFunctionPass | |
57 | Machine Natural Loop Construction | MachineLoopInfo:MachineFunctionPass | |
58 | Early Machine Loop Invariant Code Motion | EarlyMachineLICM:MachineLICMBase:MachineFunctionPass | This pass performs loop invariant code motion, attempting to remove as much code from the body of a loop as possible. |
59 | Machine Block Frequency Analysis | MachineBlockFrequencyInfo:MachineFunctionPass | |
60 | Machine Common Subexpression Elimination | MachineCSE:MachineFunctionPass | |
61 | MachinePostDominator Tree Construction | MachinePostDominatorTree:MachineFunctionPass | |
62 | Machine code sinking | MachineSinking:MachineFunctionPass | |
63 | Peephole Optimizations | PeepholeOptimizer:MachineFunctionPass | |
64 | RISCV Merge Base Offset | RISCVMergeBaseOffsetOpt:MachineFunctionPass | |
65 | Detect Dead Lanes | DetectDeadLanes:MachineFunctionPass | |
66 | Process Implicit Definitions | ProcessImplicitDefs:MachineFunctionPass | |
67 | Remove unreachable machine basic blocks | UnreachableMachineBlockElim:MachineFunctionPass | |
68 | Live Variable Analysis | LiveVariables:MachineFunctionPass | |
69 | Eliminate PHI nodes for register allocation | PHIElimination:MachineFunctionPass | |
70 | TwoAddress instruction pass | TwoAddressInstructionPass:MachineFunctionPass | |
71 | Live Interval Analysis | LiveIntervals:MachineFunctionPass | |
72 | Simple Register Coalescing | RegisterCoalescer:MachineFunctionPass,LiveRangeEdit::Delegate | |
73 | Rename Disconnected Subregister Components | RenameIndependentSubregs:MachineFunctionPass | |
74 | Machine Instruction Scheduler | MachineScheduler:MachineSchedulerBase:MachineSchedContext,MachineFunctionPass | |
75 | Debug Variable Analysis | LiveDebugVariables:MachineFunctionPass | |
76 | Live Stack Slot Analysis | LiveStack:MachineFunctionPass | |
77 | Virtual Register Map | VirtRegMap:MachineFunctionPass | |
78 | Live Register Matrix | LiveRegMatrix:MachineFunctionPass | |
79 | Bundle Machine CFG Edges | EdgeBundles:MachineFunctionPass | |
80 | Spill Code Placement Analysis | SpillPlacement:MachineFunctionPass | |
81 | Machine Optimization Remark Emitter | MachineOptimizationRemarkEmitterPass:MachineFunctionPass | |
82+ | Greedy Register Allocator | RAGreedy:MachineFunctionPass,RegAllocBase,LiveRangeEdit::Delegate | Register allocation and assignment |
83+ | Virtual Register Rewriter | VirtRegRewriter:MachineFunctionPass | Register allocation and assignment |
84 | Stack Slot Coloring | StackSlotColoring:MachineFunctionPass | |
85 | Machine Copy Propagation Pass | MachineCopyPropagation:MachineFunctionPass | |
86 | Machine Loop Invariant Code Motion | MachineLICM:MachineLICMBase:MachineFunctionPass | This pass performs loop invariant code motion, attempting to remove as much code from the body of a loop as possible. |
87 | Fixup Statepoint Caller Saved | FixupStatepointCallerSaved:MachineFunctionPass | |
88 | PostRA Machine Sink | PostRAMachineSinking:MachineFunctionPass | |
89 | Shrink Wrapping analysis | ShrinkWrap:MachineFunctionPass | |
90+ | Prologue/Epilogue Insertion & Frame Finalization | PEI:MachineFunctionPass | Prologue and epilogue insertion |
91 | Control Flow Optimizer | BranchFolderPass:MachineFunctionPass | |
92 | Tail Duplication | TailDuplicate:TailDuplicateBase:MachineFunctionPass | |
93 | PostRA pseudo instruction expansion pass | ExpandPostRA:MachineFunctionPass | |
94+ | Post RA topdown list latency scheduler | PostRAScheduler:MachineFunctionPass | post ra scheduling |
95 | Analyze Machine Code For Garbage Collection | GCMachineCodeAnalysis:MachineFunctionPass | |
96 | Branch Probability Basic Block Placement | MachineBlockPlacement:MachineFunctionPass | |
97 | Insert fentry calls | FEntryInserter:MachineFunctionPass | |
98 | Insert XRay ops | XRayInstrumentation:MachineFunctionPass | |
99 | Implement the 'patchablefunction' attribute | PatchableFunction:MachineFunctionPass | |
100 | Branch relaxation pass | BranchRelaxation:MachineFunctionPass | |
101 | Contiguously Lay Out Funclets | FuncletLayout:MachineFunctionPass | |
102 | StackMap Liveness Analysis | StackMapLiveness:MachineFunctionPass | analysis |
103 | Live DEBUGVALUE analysis | LiveDebugValues:MachineFunctionPass | analysis |
104 | RISCV pseudo instruction expansion pass | RISCVExpandPseudo:MachineFunctionPass | pseudo instruction expansion |
105 | RISCV atomic pseudo instruction expansion pass | RISCVExpandAtomicPseudo:MachineFunctionPass | atomic pseudo instruction expansion |
106+ | RISCV Assembly Printer | RISCVAsmPrinter:AsmPrinter:MachineFunctionPass | Output Asembly text |
107 | Free MachineFunction | FreeMachineFunction:FunctionPass | Clean up machine function |
Notes:
- ImmutablePass:ModulePass is used to provide information that does not need to be run.
- ModulePass:Pass is used to implement unstructured interprocedural optimizations and analyses.
- FunctionPass:Pass is used to implement most global optimizations.
- MachineFunctionPass:FunctionPass adapts the FunctionPass interface to allow convenient creation of passes that operate on the MachineFunction representation.
- Each pass can provide information for later pass as analysis, if a pass need another pass,
it should require that pass in
getAnalysisUsage()
function to ensure that pass is run before it.
8.3 How a Pass is added to a PassManager:PassManagerBase:
- call PassManager::add(Pass *p) with an instance of particular Pass.
- Use an instance of TargetPassConfig:ImmutablePass to TargetPassConfig::addPass(AnalysisID, bool, bool) or TargetPassConfig::addPass(Pass*, bool, bool), but eventually, it will calls PassManager::add(Pass *p).
8.4 How PassManager:PassManagerBase runs:
Every pass will get the chance to doInitialization()
, doFinalization()
and run()
if it is runable.
/// run - Execute all of the passes scheduled for execution. Keep track of /// whether any of the passes modifies the module, and if so, return true. bool PassManagerImpl::run(Module &M) { bool Changed = false; for (ImmutablePass *ImPass : getImmutablePasses()) Changed |= ImPass->doInitialization(M); initializeAllAnalysisInfo(); for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) { Changed |= getContainedManager(Index)->runOnModule(M); M.getContext().yield(); } for (ImmutablePass *ImPass : getImmutablePasses()) Changed |= ImPass->doFinalization(M); return Changed; }
8.5 How a Pass requires/provides information from/to other Passes.
/// getAnalysisUsage - This function should be overriden by passes that need /// analysis information to do their job. If a pass specifies that it uses a /// particular analysis result to this function, it can then use the /// getAnalysis<AnalysisType>() function, below. virtual void getAnalysisUsage(AnalysisUsage &) const; /// getAnalysis<AnalysisType>() - This function is used by subclasses to get /// to the analysis information that they claim to use by overriding the /// getAnalysisUsage function. template<typename AnalysisType> AnalysisType &getAnalysis() const; // Defined in PassAnalysisSupport.h
Example from SelectionDAGISel:MachineFunctionPass:
/// Pass Manager itself does not invalidate any analysis info. void MPPassManager::getAnalysisUsage(AnalysisUsage &Info) const override { /// Set by analyses that do not transform their input at all Info.setPreservesAll(); } void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { if (OptLevel != CodeGenOpt::None) AU.addRequired<AAResultsWrapperPass>(); AU.addRequired<GCModuleInfo>(); AU.addRequired<StackProtector>(); AU.addPreserved<GCModuleInfo>(); AU.addRequired<TargetLibraryInfoWrapperPass>(); AU.addRequired<TargetTransformInfoWrapperPass>(); if (UseMBPI && OptLevel != CodeGenOpt::None) AU.addRequired<BranchProbabilityInfoWrapperPass>(); AU.addRequired<ProfileSummaryInfoWrapperPass>(); if (OptLevel != CodeGenOpt::None) LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU); MachineFunctionPass::getAnalysisUsage(AU); } bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { // ... LibInfo = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(Fn); //... GFI = Fn.hasGC() ? &getAnalysis<GCModuleInfo>().getFunctionInfo(Fn) : nullptr; //... auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>(); auto *LIWP = getAnalysisIfAvailable<LoopInfoWrapperPass>(); auto *PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI(); //... BlockFrequencyInfo *BFI = nullptr; if (PSI && PSI->hasProfileSummary() && OptLevel != CodeGenOpt::None) BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI(); //... CurDAG->init(*MF, *ORE, this, LibInfo, getAnalysisIfAvailable<LegacyDivergenceAnalysis>(), PSI, BFI); if (UseMBPI && OptLevel != CodeGenOpt::None) FuncInfo->BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI(); else FuncInfo->BPI = nullptr; //... if (OptLevel != CodeGenOpt::None) AA = &getAnalysis<AAResultsWrapperPass>().getAAResults(); else AA = nullptr;// ... }