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 bool RegUsageInfoPropagationPass::runOnMachineFunction(MachineFunction &MF) { 92 const Module *M = MF.getFunction()->getParent(); 93 PhysicalRegisterUsageInfo *PRUI = &getAnalysis<PhysicalRegisterUsageInfo>(); 94 95 DEBUG(dbgs() << " ++++++++++++++++++++ " << getPassName() 96 << " ++++++++++++++++++++ \n"); 97 DEBUG(dbgs() << "MachineFunction : " << MF.getName() << "\n"); 98 99 const MachineFrameInfo &MFI = MF.getFrameInfo(); 100 if (!MFI.hasCalls() && !MFI.hasTailCall()) 101 return false; 102 103 bool Changed = false; 104 105 for (MachineBasicBlock &MBB : MF) { 106 for (MachineInstr &MI : MBB) { 107 if (!MI.isCall()) 108 continue; 109 DEBUG(dbgs() 110 << "Call Instruction Before Register Usage Info Propagation : \n"); 111 DEBUG(dbgs() << MI << "\n"); 112 113 auto UpdateRegMask = [&](const Function *F) { 114 const auto *RegMask = PRUI->getRegUsageInfo(F); 115 if (!RegMask) 116 return; 117 setRegMask(MI, &(*RegMask)[0]); 118 Changed = true; 119 }; 120 121 MachineOperand &Operand = MI.getOperand(0); 122 if (Operand.isGlobal()) 123 UpdateRegMask(cast<Function>(Operand.getGlobal())); 124 else if (Operand.isSymbol()) 125 UpdateRegMask(M->getFunction(Operand.getSymbolName())); 126 127 DEBUG(dbgs() 128 << "Call Instruction After Register Usage Info Propagation : \n"); 129 DEBUG(dbgs() << MI << "\n"); 130 } 131 } 132 133 DEBUG(dbgs() << " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" 134 "++++++ \n"); 135 return Changed; 136 } 137