blob: 5b12d00e126fd9412cbb397d70d778f0dc56fb4f [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
Matt Arsenaultd6643152017-08-24 07:55:15 +000091// Assumes call instructions have a single reference to a function.
92static const Function *findCalledFunction(const Module &M, MachineInstr &MI) {
93 for (MachineOperand &MO : MI.operands()) {
94 if (MO.isGlobal())
95 return dyn_cast<Function>(MO.getGlobal());
96
97 if (MO.isSymbol())
98 return M.getFunction(MO.getSymbolName());
99 }
100
101 return nullptr;
102}
103
Mehdi Amini1d396832016-06-10 18:37:21 +0000104bool RegUsageInfoPropagationPass::runOnMachineFunction(MachineFunction &MF) {
Matthias Braunf1caa282017-12-15 22:22:58 +0000105 const Module *M = MF.getFunction().getParent();
Mehdi Amini1d396832016-06-10 18:37:21 +0000106 PhysicalRegisterUsageInfo *PRUI = &getAnalysis<PhysicalRegisterUsageInfo>();
107
108 DEBUG(dbgs() << " ++++++++++++++++++++ " << getPassName()
109 << " ++++++++++++++++++++ \n");
110 DEBUG(dbgs() << "MachineFunction : " << MF.getName() << "\n");
111
Matt Arsenault00459e42017-08-24 07:55:13 +0000112 const MachineFrameInfo &MFI = MF.getFrameInfo();
113 if (!MFI.hasCalls() && !MFI.hasTailCall())
114 return false;
115
Mehdi Amini1d396832016-06-10 18:37:21 +0000116 bool Changed = false;
117
118 for (MachineBasicBlock &MBB : MF) {
119 for (MachineInstr &MI : MBB) {
120 if (!MI.isCall())
121 continue;
122 DEBUG(dbgs()
123 << "Call Instruction Before Register Usage Info Propagation : \n");
124 DEBUG(dbgs() << MI << "\n");
125
126 auto UpdateRegMask = [&](const Function *F) {
127 const auto *RegMask = PRUI->getRegUsageInfo(F);
128 if (!RegMask)
129 return;
130 setRegMask(MI, &(*RegMask)[0]);
131 Changed = true;
132 };
133
Matt Arsenaultd6643152017-08-24 07:55:15 +0000134 if (const Function *F = findCalledFunction(*M, MI)) {
135 UpdateRegMask(F);
136 } else {
137 DEBUG(dbgs() << "Failed to find call target function\n");
138 }
Mehdi Amini1d396832016-06-10 18:37:21 +0000139
Matt Arsenaultd6643152017-08-24 07:55:15 +0000140 DEBUG(dbgs() << "Call Instruction After Register Usage Info Propagation : "
141 << MI << '\n');
Mehdi Amini1d396832016-06-10 18:37:21 +0000142 }
143 }
144
145 DEBUG(dbgs() << " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
146 "++++++ \n");
147 return Changed;
148}