RegUsageInfoPropagate.cpp 5.0 KB

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