1 //=--- RegUsageInfoPropagate.cpp - Register Usage Informartion Propagation --=// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// This pass is required to take advantage of the interprocedural register 11 /// allocation infrastructure. 12 /// 13 /// This pass iterates through MachineInstrs in a given MachineFunction and at 14 /// each callsite queries RegisterUsageInfo for RegMask (calculated based on 15 /// actual register allocation) of the callee function, if the RegMask detail 16 /// is available then this pass will update the RegMask of the call instruction. 17 /// This updated RegMask will be used by the register allocator while allocating 18 /// the current MachineFunction. 19 /// 20 //===----------------------------------------------------------------------===// 21 22 #include "llvm/CodeGen/MachineBasicBlock.h" 23 #include "llvm/CodeGen/MachineFunctionPass.h" 24 #include "llvm/CodeGen/MachineFrameInfo.h" 25 #include "llvm/CodeGen/MachineInstr.h" 26 #include "llvm/CodeGen/MachineRegisterInfo.h" 27 #include "llvm/CodeGen/Passes.h" 28 #include "llvm/CodeGen/RegisterUsageInfo.h" 29 #include "llvm/IR/Module.h" 30 #include "llvm/PassAnalysisSupport.h" 31 #include "llvm/Support/Debug.h" 32 #include "llvm/Support/raw_ostream.h" 33 #include "llvm/Target/TargetMachine.h" 34 #include <map> 35 #include <string> 36 37 namespace llvm { 38 void initializeRegUsageInfoPropagationPassPass(PassRegistry &); 39 } 40 41 using namespace llvm; 42 43 #define DEBUG_TYPE "ip-regalloc" 44 45 #define RUIP_NAME "Register Usage Information Propagation" 46 47 namespace { 48 class RegUsageInfoPropagationPass : public MachineFunctionPass { 49 50 public: 51 RegUsageInfoPropagationPass() : MachineFunctionPass(ID) { 52 PassRegistry &Registry = *PassRegistry::getPassRegistry(); 53 initializeRegUsageInfoPropagationPassPass(Registry); 54 } 55 56 StringRef getPassName() const override { return RUIP_NAME; } 57 58 bool runOnMachineFunction(MachineFunction &MF) override; 59 60 void getAnalysisUsage(AnalysisUsage &AU) const override; 61 62 static char ID; 63 64 private: 65 static void setRegMask(MachineInstr &MI, const uint32_t *RegMask) { 66 for (MachineOperand &MO : MI.operands()) { 67 if (MO.isRegMask()) 68 MO.setRegMask(RegMask); 69 } 70 } 71 }; 72 } // end of anonymous namespace 73 char RegUsageInfoPropagationPass::ID = 0; 74 75 INITIALIZE_PASS_BEGIN(RegUsageInfoPropagationPass, "reg-usage-propagation", 76 RUIP_NAME, false, false) 77 INITIALIZE_PASS_DEPENDENCY(PhysicalRegisterUsageInfo) 78 INITIALIZE_PASS_END(RegUsageInfoPropagationPass, "reg-usage-propagation", 79 RUIP_NAME, false, false) 80 81 FunctionPass *llvm::createRegUsageInfoPropPass() { 82 return new RegUsageInfoPropagationPass(); 83 } 84 85 void RegUsageInfoPropagationPass::getAnalysisUsage(AnalysisUsage &AU) const { 86 AU.addRequired<PhysicalRegisterUsageInfo>(); 87 AU.setPreservesAll(); 88 MachineFunctionPass::getAnalysisUsage(AU); 89 } 90 91 // Assumes call instructions have a single reference to a function. 92 static const Function *findCalledFunction(const Module &M, MachineInstr &MI) { 93 for (MachineOperand &MO : MI.operands()) { 94 if (MO.isGlobal()) 95 return dyn_cast<Function>(MO.getGlobal()); 96 97 if (MO.isSymbol()) 98 return M.getFunction(MO.getSymbolName()); 99 } 100 101 return nullptr; 102 } 103 104 bool RegUsageInfoPropagationPass::runOnMachineFunction(MachineFunction &MF) { 105 const Module *M = MF.getFunction().getParent(); 106 PhysicalRegisterUsageInfo *PRUI = &getAnalysis<PhysicalRegisterUsageInfo>(); 107 108 DEBUG(dbgs() << " ++++++++++++++++++++ " << getPassName() 109 << " ++++++++++++++++++++ \n"); 110 DEBUG(dbgs() << "MachineFunction : " << MF.getName() << "\n"); 111 112 const MachineFrameInfo &MFI = MF.getFrameInfo(); 113 if (!MFI.hasCalls() && !MFI.hasTailCall()) 114 return false; 115 116 bool Changed = false; 117 118 for (MachineBasicBlock &MBB : MF) { 119 for (MachineInstr &MI : MBB) { 120 if (!MI.isCall()) 121 continue; 122 DEBUG(dbgs() 123 << "Call Instruction Before Register Usage Info Propagation : \n"); 124 DEBUG(dbgs() << MI << "\n"); 125 126 auto UpdateRegMask = [&](const Function *F) { 127 const auto *RegMask = PRUI->getRegUsageInfo(F); 128 if (!RegMask) 129 return; 130 setRegMask(MI, &(*RegMask)[0]); 131 Changed = true; 132 }; 133 134 if (const Function *F = findCalledFunction(*M, MI)) { 135 UpdateRegMask(F); 136 } else { 137 DEBUG(dbgs() << "Failed to find call target function\n"); 138 } 139 140 DEBUG(dbgs() << "Call Instruction After Register Usage Info Propagation : " 141 << MI << '\n'); 142 } 143 } 144 145 DEBUG(dbgs() << " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" 146 "++++++ \n"); 147 return Changed; 148 } 149