1 //=--- RegUsageInfoPropagate.cpp - Register Usage Informartion Propagation --=//
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
7 //===----------------------------------------------------------------------===//
9 /// This pass is required to take advantage of the interprocedural register
10 /// allocation infrastructure.
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.
19 //===----------------------------------------------------------------------===//
21 #include "llvm/CodeGen/MachineBasicBlock.h"
22 #include "llvm/CodeGen/MachineFunctionPass.h"
23 #include "llvm/CodeGen/MachineFrameInfo.h"
24 #include "llvm/CodeGen/MachineInstr.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #include "llvm/CodeGen/Passes.h"
27 #include "llvm/CodeGen/RegisterUsageInfo.h"
28 #include "llvm/IR/Module.h"
29 #include "llvm/PassAnalysisSupport.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/raw_ostream.h"
32 #include "llvm/Target/TargetMachine.h"
38 #define DEBUG_TYPE "ip-regalloc"
40 #define RUIP_NAME "Register Usage Information Propagation"
44 class RegUsageInfoPropagation
: public MachineFunctionPass
{
46 RegUsageInfoPropagation() : MachineFunctionPass(ID
) {
47 PassRegistry
&Registry
= *PassRegistry::getPassRegistry();
48 initializeRegUsageInfoPropagationPass(Registry
);
51 StringRef
getPassName() const override
{ return RUIP_NAME
; }
53 bool runOnMachineFunction(MachineFunction
&MF
) override
;
55 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
56 AU
.addRequired
<PhysicalRegisterUsageInfo
>();
58 MachineFunctionPass::getAnalysisUsage(AU
);
64 static void setRegMask(MachineInstr
&MI
, ArrayRef
<uint32_t> RegMask
) {
65 assert(RegMask
.size() ==
66 MachineOperand::getRegMaskSize(MI
.getParent()->getParent()
67 ->getRegInfo().getTargetRegisterInfo()
69 && "expected register mask size");
70 for (MachineOperand
&MO
: MI
.operands()) {
72 MO
.setRegMask(RegMask
.data());
77 } // end of anonymous namespace
79 INITIALIZE_PASS_BEGIN(RegUsageInfoPropagation
, "reg-usage-propagation",
80 RUIP_NAME
, false, false)
81 INITIALIZE_PASS_DEPENDENCY(PhysicalRegisterUsageInfo
)
82 INITIALIZE_PASS_END(RegUsageInfoPropagation
, "reg-usage-propagation",
83 RUIP_NAME
, false, false)
85 char RegUsageInfoPropagation::ID
= 0;
87 // Assumes call instructions have a single reference to a function.
88 static const Function
*findCalledFunction(const Module
&M
,
89 const MachineInstr
&MI
) {
90 for (const MachineOperand
&MO
: MI
.operands()) {
92 return dyn_cast
<const Function
>(MO
.getGlobal());
95 return M
.getFunction(MO
.getSymbolName());
101 bool RegUsageInfoPropagation::runOnMachineFunction(MachineFunction
&MF
) {
102 const Module
&M
= *MF
.getFunction().getParent();
103 PhysicalRegisterUsageInfo
*PRUI
= &getAnalysis
<PhysicalRegisterUsageInfo
>();
105 LLVM_DEBUG(dbgs() << " ++++++++++++++++++++ " << getPassName()
106 << " ++++++++++++++++++++ \n");
107 LLVM_DEBUG(dbgs() << "MachineFunction : " << MF
.getName() << "\n");
109 const MachineFrameInfo
&MFI
= MF
.getFrameInfo();
110 if (!MFI
.hasCalls() && !MFI
.hasTailCall())
113 bool Changed
= false;
115 for (MachineBasicBlock
&MBB
: MF
) {
116 for (MachineInstr
&MI
: MBB
) {
121 << "Call Instruction Before Register Usage Info Propagation : \n");
122 LLVM_DEBUG(dbgs() << MI
<< "\n");
124 auto UpdateRegMask
= [&](const Function
&F
) {
125 const ArrayRef
<uint32_t> RegMask
= PRUI
->getRegUsageInfo(F
);
128 setRegMask(MI
, RegMask
);
132 if (const Function
*F
= findCalledFunction(M
, MI
)) {
133 if (F
->isDefinitionExact()) {
136 LLVM_DEBUG(dbgs() << "Function definition is not exact\n");
139 LLVM_DEBUG(dbgs() << "Failed to find call target function\n");
143 dbgs() << "Call Instruction After Register Usage Info Propagation : "
149 dbgs() << " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
154 FunctionPass
*llvm::createRegUsageInfoPropPass() {
155 return new RegUsageInfoPropagation();