blob: a39c9457b3a40570682bf6a807f0ea023379b534 [file] [log] [blame]
Mehdi Amini1d396832016-06-10 18:37:21 +00001//=--- 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"
Matt Arsenault00459e42017-08-24 07:55:13 +000024#include "llvm/CodeGen/MachineFrameInfo.h"
Mehdi Amini1d396832016-06-10 18:37:21 +000025#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
37namespace llvm {
38void initializeRegUsageInfoPropagationPassPass(PassRegistry &);
39}
40
41using namespace llvm;
42
43#define DEBUG_TYPE "ip-regalloc"
44
45#define RUIP_NAME "Register Usage Information Propagation"
46
47namespace {
48class RegUsageInfoPropagationPass : public MachineFunctionPass {
49
50public:
51 RegUsageInfoPropagationPass() : MachineFunctionPass(ID) {
52 PassRegistry &Registry = *PassRegistry::getPassRegistry();
53 initializeRegUsageInfoPropagationPassPass(Registry);
54 }
55
Mehdi Amini117296c2016-10-01 02:56:57 +000056 StringRef getPassName() const override { return RUIP_NAME; }
Mehdi Amini1d396832016-06-10 18:37:21 +000057
58 bool runOnMachineFunction(MachineFunction &MF) override;
59
60 void getAnalysisUsage(AnalysisUsage &AU) const override;
61
62 static char ID;
63
64private:
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
73char RegUsageInfoPropagationPass::ID = 0;
74
75INITIALIZE_PASS_BEGIN(RegUsageInfoPropagationPass, "reg-usage-propagation",
76 RUIP_NAME, false, false)
77INITIALIZE_PASS_DEPENDENCY(PhysicalRegisterUsageInfo)
78INITIALIZE_PASS_END(RegUsageInfoPropagationPass, "reg-usage-propagation",
79 RUIP_NAME, false, false)
80
81FunctionPass *llvm::createRegUsageInfoPropPass() {
82 return new RegUsageInfoPropagationPass();
83}
84
85void RegUsageInfoPropagationPass::getAnalysisUsage(AnalysisUsage &AU) const {
86 AU.addRequired<PhysicalRegisterUsageInfo>();
87 AU.setPreservesAll();
88 MachineFunctionPass::getAnalysisUsage(AU);
89}
90
91bool 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
Matt Arsenault00459e42017-08-24 07:55:13 +000099 const MachineFrameInfo &MFI = MF.getFrameInfo();
100 if (!MFI.hasCalls() && !MFI.hasTailCall())
101 return false;
102
Mehdi Amini1d396832016-06-10 18:37:21 +0000103 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}