Home | History | Annotate | Download | only in CodeGen
      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