1*7330f729Sjoerg //===-- MachineFunctionPass.cpp -------------------------------------------===// 2*7330f729Sjoerg // 3*7330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*7330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information. 5*7330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*7330f729Sjoerg // 7*7330f729Sjoerg //===----------------------------------------------------------------------===// 8*7330f729Sjoerg // 9*7330f729Sjoerg // This file contains the definitions of the MachineFunctionPass members. 10*7330f729Sjoerg // 11*7330f729Sjoerg //===----------------------------------------------------------------------===// 12*7330f729Sjoerg 13*7330f729Sjoerg #include "llvm/CodeGen/MachineFunctionPass.h" 14*7330f729Sjoerg #include "llvm/Analysis/AliasAnalysis.h" 15*7330f729Sjoerg #include "llvm/Analysis/BasicAliasAnalysis.h" 16*7330f729Sjoerg #include "llvm/Analysis/DominanceFrontier.h" 17*7330f729Sjoerg #include "llvm/Analysis/GlobalsModRef.h" 18*7330f729Sjoerg #include "llvm/Analysis/IVUsers.h" 19*7330f729Sjoerg #include "llvm/Analysis/LoopInfo.h" 20*7330f729Sjoerg #include "llvm/Analysis/MemoryDependenceAnalysis.h" 21*7330f729Sjoerg #include "llvm/Analysis/ScalarEvolution.h" 22*7330f729Sjoerg #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" 23*7330f729Sjoerg #include "llvm/CodeGen/MachineFunction.h" 24*7330f729Sjoerg #include "llvm/CodeGen/MachineModuleInfo.h" 25*7330f729Sjoerg #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" 26*7330f729Sjoerg #include "llvm/CodeGen/Passes.h" 27*7330f729Sjoerg #include "llvm/IR/Dominators.h" 28*7330f729Sjoerg #include "llvm/IR/Function.h" 29*7330f729Sjoerg 30*7330f729Sjoerg using namespace llvm; 31*7330f729Sjoerg using namespace ore; 32*7330f729Sjoerg 33*7330f729Sjoerg Pass *MachineFunctionPass::createPrinterPass(raw_ostream &O, 34*7330f729Sjoerg const std::string &Banner) const { 35*7330f729Sjoerg return createMachineFunctionPrinterPass(O, Banner); 36*7330f729Sjoerg } 37*7330f729Sjoerg 38*7330f729Sjoerg bool MachineFunctionPass::runOnFunction(Function &F) { 39*7330f729Sjoerg // Do not codegen any 'available_externally' functions at all, they have 40*7330f729Sjoerg // definitions outside the translation unit. 41*7330f729Sjoerg if (F.hasAvailableExternallyLinkage()) 42*7330f729Sjoerg return false; 43*7330f729Sjoerg 44*7330f729Sjoerg MachineModuleInfo &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); 45*7330f729Sjoerg MachineFunction &MF = MMI.getOrCreateMachineFunction(F); 46*7330f729Sjoerg 47*7330f729Sjoerg MachineFunctionProperties &MFProps = MF.getProperties(); 48*7330f729Sjoerg 49*7330f729Sjoerg #ifndef NDEBUG 50*7330f729Sjoerg if (!MFProps.verifyRequiredProperties(RequiredProperties)) { 51*7330f729Sjoerg errs() << "MachineFunctionProperties required by " << getPassName() 52*7330f729Sjoerg << " pass are not met by function " << F.getName() << ".\n" 53*7330f729Sjoerg << "Required properties: "; 54*7330f729Sjoerg RequiredProperties.print(errs()); 55*7330f729Sjoerg errs() << "\nCurrent properties: "; 56*7330f729Sjoerg MFProps.print(errs()); 57*7330f729Sjoerg errs() << "\n"; 58*7330f729Sjoerg llvm_unreachable("MachineFunctionProperties check failed"); 59*7330f729Sjoerg } 60*7330f729Sjoerg #endif 61*7330f729Sjoerg // Collect the MI count of the function before the pass. 62*7330f729Sjoerg unsigned CountBefore, CountAfter; 63*7330f729Sjoerg 64*7330f729Sjoerg // Check if the user asked for size remarks. 65*7330f729Sjoerg bool ShouldEmitSizeRemarks = 66*7330f729Sjoerg F.getParent()->shouldEmitInstrCountChangedRemark(); 67*7330f729Sjoerg 68*7330f729Sjoerg // If we want size remarks, collect the number of MachineInstrs in our 69*7330f729Sjoerg // MachineFunction before the pass runs. 70*7330f729Sjoerg if (ShouldEmitSizeRemarks) 71*7330f729Sjoerg CountBefore = MF.getInstructionCount(); 72*7330f729Sjoerg 73*7330f729Sjoerg bool RV = runOnMachineFunction(MF); 74*7330f729Sjoerg 75*7330f729Sjoerg if (ShouldEmitSizeRemarks) { 76*7330f729Sjoerg // We wanted size remarks. Check if there was a change to the number of 77*7330f729Sjoerg // MachineInstrs in the module. Emit a remark if there was a change. 78*7330f729Sjoerg CountAfter = MF.getInstructionCount(); 79*7330f729Sjoerg if (CountBefore != CountAfter) { 80*7330f729Sjoerg MachineOptimizationRemarkEmitter MORE(MF, nullptr); 81*7330f729Sjoerg MORE.emit([&]() { 82*7330f729Sjoerg int64_t Delta = static_cast<int64_t>(CountAfter) - 83*7330f729Sjoerg static_cast<int64_t>(CountBefore); 84*7330f729Sjoerg MachineOptimizationRemarkAnalysis R("size-info", "FunctionMISizeChange", 85*7330f729Sjoerg MF.getFunction().getSubprogram(), 86*7330f729Sjoerg &MF.front()); 87*7330f729Sjoerg R << NV("Pass", getPassName()) 88*7330f729Sjoerg << ": Function: " << NV("Function", F.getName()) << ": " 89*7330f729Sjoerg << "MI Instruction count changed from " 90*7330f729Sjoerg << NV("MIInstrsBefore", CountBefore) << " to " 91*7330f729Sjoerg << NV("MIInstrsAfter", CountAfter) 92*7330f729Sjoerg << "; Delta: " << NV("Delta", Delta); 93*7330f729Sjoerg return R; 94*7330f729Sjoerg }); 95*7330f729Sjoerg } 96*7330f729Sjoerg } 97*7330f729Sjoerg 98*7330f729Sjoerg MFProps.set(SetProperties); 99*7330f729Sjoerg MFProps.reset(ClearedProperties); 100*7330f729Sjoerg return RV; 101*7330f729Sjoerg } 102*7330f729Sjoerg 103*7330f729Sjoerg void MachineFunctionPass::getAnalysisUsage(AnalysisUsage &AU) const { 104*7330f729Sjoerg AU.addRequired<MachineModuleInfoWrapperPass>(); 105*7330f729Sjoerg AU.addPreserved<MachineModuleInfoWrapperPass>(); 106*7330f729Sjoerg 107*7330f729Sjoerg // MachineFunctionPass preserves all LLVM IR passes, but there's no 108*7330f729Sjoerg // high-level way to express this. Instead, just list a bunch of 109*7330f729Sjoerg // passes explicitly. This does not include setPreservesCFG, 110*7330f729Sjoerg // because CodeGen overloads that to mean preserving the MachineBasicBlock 111*7330f729Sjoerg // CFG in addition to the LLVM IR CFG. 112*7330f729Sjoerg AU.addPreserved<BasicAAWrapperPass>(); 113*7330f729Sjoerg AU.addPreserved<DominanceFrontierWrapperPass>(); 114*7330f729Sjoerg AU.addPreserved<DominatorTreeWrapperPass>(); 115*7330f729Sjoerg AU.addPreserved<AAResultsWrapperPass>(); 116*7330f729Sjoerg AU.addPreserved<GlobalsAAWrapperPass>(); 117*7330f729Sjoerg AU.addPreserved<IVUsersWrapperPass>(); 118*7330f729Sjoerg AU.addPreserved<LoopInfoWrapperPass>(); 119*7330f729Sjoerg AU.addPreserved<MemoryDependenceWrapperPass>(); 120*7330f729Sjoerg AU.addPreserved<ScalarEvolutionWrapperPass>(); 121*7330f729Sjoerg AU.addPreserved<SCEVAAWrapperPass>(); 122*7330f729Sjoerg 123*7330f729Sjoerg FunctionPass::getAnalysisUsage(AU); 124*7330f729Sjoerg } 125