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 using namespace llvm; 38 39 #define DEBUG_TYPE "ip-regalloc" 40 41 #define RUIP_NAME "Register Usage Information Propagation" 42 43 namespace { 44 45 class RegUsageInfoPropagation : public MachineFunctionPass { 46 public: 47 RegUsageInfoPropagation() : MachineFunctionPass(ID) { 48 PassRegistry &Registry = *PassRegistry::getPassRegistry(); 49 initializeRegUsageInfoPropagationPass(Registry); 50 } 51 52 StringRef getPassName() const override { return RUIP_NAME; } 53 54 bool runOnMachineFunction(MachineFunction &MF) override; 55 56 void getAnalysisUsage(AnalysisUsage &AU) const override { 57 AU.addRequired<PhysicalRegisterUsageInfo>(); 58 AU.setPreservesAll(); 59 MachineFunctionPass::getAnalysisUsage(AU); 60 } 61 62 static char ID; 63 64 private: 65 static void setRegMask(MachineInstr &MI, ArrayRef<uint32_t> RegMask) { 66 assert(RegMask.size() == 67 MachineOperand::getRegMaskSize(MI.getParent()->getParent() 68 ->getRegInfo().getTargetRegisterInfo() 69 ->getNumRegs()) 70 && "expected register mask size"); 71 for (MachineOperand &MO : MI.operands()) { 72 if (MO.isRegMask()) 73 MO.setRegMask(RegMask.data()); 74 } 75 } 76 }; 77 78 } // end of anonymous namespace 79 80 INITIALIZE_PASS_BEGIN(RegUsageInfoPropagation, "reg-usage-propagation", 81 RUIP_NAME, false, false) 82 INITIALIZE_PASS_DEPENDENCY(PhysicalRegisterUsageInfo) 83 INITIALIZE_PASS_END(RegUsageInfoPropagation, "reg-usage-propagation", 84 RUIP_NAME, false, false) 85 86 char RegUsageInfoPropagation::ID = 0; 87 88 // Assumes call instructions have a single reference to a function. 89 static const Function *findCalledFunction(const Module &M, 90 const MachineInstr &MI) { 91 for (const MachineOperand &MO : MI.operands()) { 92 if (MO.isGlobal()) 93 return dyn_cast<const Function>(MO.getGlobal()); 94 95 if (MO.isSymbol()) 96 return M.getFunction(MO.getSymbolName()); 97 } 98 99 return nullptr; 100 } 101 102 bool RegUsageInfoPropagation::runOnMachineFunction(MachineFunction &MF) { 103 const Module &M = *MF.getFunction().getParent(); 104 PhysicalRegisterUsageInfo *PRUI = &getAnalysis<PhysicalRegisterUsageInfo>(); 105 106 LLVM_DEBUG(dbgs() << " ++++++++++++++++++++ " << getPassName() 107 << " ++++++++++++++++++++ \n"); 108 LLVM_DEBUG(dbgs() << "MachineFunction : " << MF.getName() << "\n"); 109 110 const MachineFrameInfo &MFI = MF.getFrameInfo(); 111 if (!MFI.hasCalls() && !MFI.hasTailCall()) 112 return false; 113 114 bool Changed = false; 115 116 for (MachineBasicBlock &MBB : MF) { 117 for (MachineInstr &MI : MBB) { 118 if (!MI.isCall()) 119 continue; 120 LLVM_DEBUG( 121 dbgs() 122 << "Call Instruction Before Register Usage Info Propagation : \n"); 123 LLVM_DEBUG(dbgs() << MI << "\n"); 124 125 auto UpdateRegMask = [&](const Function &F) { 126 const ArrayRef<uint32_t> RegMask = PRUI->getRegUsageInfo(F); 127 if (RegMask.empty()) 128 return; 129 setRegMask(MI, RegMask); 130 Changed = true; 131 }; 132 133 if (const Function *F = findCalledFunction(M, MI)) { 134 UpdateRegMask(*F); 135 } else { 136 LLVM_DEBUG(dbgs() << "Failed to find call target function\n"); 137 } 138 139 LLVM_DEBUG( 140 dbgs() << "Call Instruction After Register Usage Info Propagation : " 141 << MI << '\n'); 142 } 143 } 144 145 LLVM_DEBUG( 146 dbgs() << " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" 147 "++++++ \n"); 148 return Changed; 149 } 150 151 FunctionPass *llvm::createRegUsageInfoPropPass() { 152 return new RegUsageInfoPropagation(); 153 } 154