/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/CodeGen/RegUsageInfoPropagate.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | |
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" |
33 | | #include <map> |
34 | | #include <string> |
35 | | |
36 | | using namespace llvm; |
37 | | |
38 | | #define DEBUG_TYPE "ip-regalloc" |
39 | | |
40 | 27.6k | #define RUIP_NAME "Register Usage Information Propagation" |
41 | | |
42 | | namespace { |
43 | | |
44 | | class RegUsageInfoPropagation : public MachineFunctionPass { |
45 | | public: |
46 | 2.44k | RegUsageInfoPropagation() : MachineFunctionPass(ID) { |
47 | 2.44k | PassRegistry &Registry = *PassRegistry::getPassRegistry(); |
48 | 2.44k | initializeRegUsageInfoPropagationPass(Registry); |
49 | 2.44k | } |
50 | | |
51 | 27.6k | StringRef getPassName() const override { return RUIP_NAME; } |
52 | | |
53 | | bool runOnMachineFunction(MachineFunction &MF) override; |
54 | | |
55 | 2.41k | void getAnalysisUsage(AnalysisUsage &AU) const override { |
56 | 2.41k | AU.addRequired<PhysicalRegisterUsageInfo>(); |
57 | 2.41k | AU.setPreservesAll(); |
58 | 2.41k | MachineFunctionPass::getAnalysisUsage(AU); |
59 | 2.41k | } |
60 | | |
61 | | static char ID; |
62 | | |
63 | | private: |
64 | 82 | static void setRegMask(MachineInstr &MI, ArrayRef<uint32_t> RegMask) { |
65 | 82 | assert(RegMask.size() == |
66 | 82 | MachineOperand::getRegMaskSize(MI.getParent()->getParent() |
67 | 82 | ->getRegInfo().getTargetRegisterInfo() |
68 | 82 | ->getNumRegs()) |
69 | 82 | && "expected register mask size"); |
70 | 478 | for (MachineOperand &MO : MI.operands()) { |
71 | 478 | if (MO.isRegMask()) |
72 | 82 | MO.setRegMask(RegMask.data()); |
73 | 478 | } |
74 | 82 | } |
75 | | }; |
76 | | |
77 | | } // end of anonymous namespace |
78 | | |
79 | 42.3k | INITIALIZE_PASS_BEGIN(RegUsageInfoPropagation, "reg-usage-propagation", |
80 | 42.3k | RUIP_NAME, false, false) |
81 | 42.3k | INITIALIZE_PASS_DEPENDENCY(PhysicalRegisterUsageInfo) |
82 | 42.3k | INITIALIZE_PASS_END(RegUsageInfoPropagation, "reg-usage-propagation", |
83 | | RUIP_NAME, false, false) |
84 | | |
85 | | char RegUsageInfoPropagation::ID = 0; |
86 | | |
87 | | // Assumes call instructions have a single reference to a function. |
88 | | static const Function *findCalledFunction(const Module &M, |
89 | 480 | const MachineInstr &MI) { |
90 | 1.39k | for (const MachineOperand &MO : MI.operands()) { |
91 | 1.39k | if (MO.isGlobal()) |
92 | 480 | return dyn_cast<const Function>(MO.getGlobal()); |
93 | 918 | |
94 | 918 | if (MO.isSymbol()) |
95 | 0 | return M.getFunction(MO.getSymbolName()); |
96 | 918 | } |
97 | 480 | |
98 | 480 | return nullptr0 ; |
99 | 480 | } |
100 | | |
101 | 25.1k | bool RegUsageInfoPropagation::runOnMachineFunction(MachineFunction &MF) { |
102 | 25.1k | const Module &M = *MF.getFunction().getParent(); |
103 | 25.1k | PhysicalRegisterUsageInfo *PRUI = &getAnalysis<PhysicalRegisterUsageInfo>(); |
104 | 25.1k | |
105 | 25.1k | LLVM_DEBUG(dbgs() << " ++++++++++++++++++++ " << getPassName() |
106 | 25.1k | << " ++++++++++++++++++++ \n"); |
107 | 25.1k | LLVM_DEBUG(dbgs() << "MachineFunction : " << MF.getName() << "\n"); |
108 | 25.1k | |
109 | 25.1k | const MachineFrameInfo &MFI = MF.getFrameInfo(); |
110 | 25.1k | if (!MFI.hasCalls() && !MFI.hasTailCall()24.7k ) |
111 | 24.7k | return false; |
112 | 459 | |
113 | 459 | bool Changed = false; |
114 | 459 | |
115 | 523 | for (MachineBasicBlock &MBB : MF) { |
116 | 10.0k | for (MachineInstr &MI : MBB) { |
117 | 10.0k | if (!MI.isCall()) |
118 | 9.61k | continue; |
119 | 480 | LLVM_DEBUG( |
120 | 480 | dbgs() |
121 | 480 | << "Call Instruction Before Register Usage Info Propagation : \n"); |
122 | 480 | LLVM_DEBUG(dbgs() << MI << "\n"); |
123 | 480 | |
124 | 480 | auto UpdateRegMask = [&](const Function &F) { |
125 | 478 | const ArrayRef<uint32_t> RegMask = PRUI->getRegUsageInfo(F); |
126 | 478 | if (RegMask.empty()) |
127 | 396 | return; |
128 | 82 | setRegMask(MI, RegMask); |
129 | 82 | Changed = true; |
130 | 82 | }; |
131 | 480 | |
132 | 480 | if (const Function *F = findCalledFunction(M, MI)) { |
133 | 480 | if (F->isDefinitionExact()) { |
134 | 478 | UpdateRegMask(*F); |
135 | 478 | } else { |
136 | 2 | LLVM_DEBUG(dbgs() << "Function definition is not exact\n"); |
137 | 2 | } |
138 | 480 | } else { |
139 | 0 | LLVM_DEBUG(dbgs() << "Failed to find call target function\n"); |
140 | 0 | } |
141 | 480 | |
142 | 480 | LLVM_DEBUG( |
143 | 480 | dbgs() << "Call Instruction After Register Usage Info Propagation : " |
144 | 480 | << MI << '\n'); |
145 | 480 | } |
146 | 523 | } |
147 | 459 | |
148 | 459 | LLVM_DEBUG( |
149 | 459 | dbgs() << " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" |
150 | 459 | "++++++ \n"); |
151 | 459 | return Changed; |
152 | 459 | } |
153 | | |
154 | 2.44k | FunctionPass *llvm::createRegUsageInfoPropPass() { |
155 | 2.44k | return new RegUsageInfoPropagation(); |
156 | 2.44k | } |