/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
Line | Count | Source |
1 | | //===- llvm/CodeGen/GlobalISel/InstructionSelect.cpp - InstructionSelect ---==// |
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 | | /// \file |
9 | | /// This file implements the InstructionSelect class. |
10 | | //===----------------------------------------------------------------------===// |
11 | | |
12 | | #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" |
13 | | #include "llvm/ADT/PostOrderIterator.h" |
14 | | #include "llvm/ADT/Twine.h" |
15 | | #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" |
16 | | #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" |
17 | | #include "llvm/CodeGen/GlobalISel/Utils.h" |
18 | | #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" |
19 | | #include "llvm/CodeGen/MachineRegisterInfo.h" |
20 | | #include "llvm/CodeGen/TargetLowering.h" |
21 | | #include "llvm/CodeGen/TargetPassConfig.h" |
22 | | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
23 | | #include "llvm/Config/config.h" |
24 | | #include "llvm/IR/Constants.h" |
25 | | #include "llvm/IR/Function.h" |
26 | | #include "llvm/Support/CommandLine.h" |
27 | | #include "llvm/Support/Debug.h" |
28 | | #include "llvm/Support/TargetRegistry.h" |
29 | | |
30 | | #define DEBUG_TYPE "instruction-select" |
31 | | |
32 | | using namespace llvm; |
33 | | |
34 | | #ifdef LLVM_GISEL_COV_PREFIX |
35 | | static cl::opt<std::string> |
36 | | CoveragePrefix("gisel-coverage-prefix", cl::init(LLVM_GISEL_COV_PREFIX), |
37 | | cl::desc("Record GlobalISel rule coverage files of this " |
38 | | "prefix if instrumentation was generated")); |
39 | | #else |
40 | | static const std::string CoveragePrefix = ""; |
41 | | #endif |
42 | | |
43 | | char InstructionSelect::ID = 0; |
44 | 102k | INITIALIZE_PASS_BEGIN(InstructionSelect, DEBUG_TYPE, |
45 | 102k | "Select target instructions out of generic instructions", |
46 | 102k | false, false) |
47 | 102k | INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) |
48 | 102k | INITIALIZE_PASS_END(InstructionSelect, DEBUG_TYPE, |
49 | | "Select target instructions out of generic instructions", |
50 | | false, false) |
51 | | |
52 | 7.45k | InstructionSelect::InstructionSelect() : MachineFunctionPass(ID) { } |
53 | | |
54 | 7.37k | void InstructionSelect::getAnalysisUsage(AnalysisUsage &AU) const { |
55 | 7.37k | AU.addRequired<TargetPassConfig>(); |
56 | 7.37k | getSelectionDAGFallbackAnalysisUsage(AU); |
57 | 7.37k | MachineFunctionPass::getAnalysisUsage(AU); |
58 | 7.37k | } |
59 | | |
60 | 239k | bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { |
61 | 239k | // If the ISel pipeline failed, do not bother running that pass. |
62 | 239k | if (MF.getProperties().hasProperty( |
63 | 239k | MachineFunctionProperties::Property::FailedISel)) |
64 | 4.83k | return false; |
65 | 235k | |
66 | 235k | LLVM_DEBUG(dbgs() << "Selecting function: " << MF.getName() << '\n'); |
67 | 235k | |
68 | 235k | const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>(); |
69 | 235k | const InstructionSelector *ISel = MF.getSubtarget().getInstructionSelector(); |
70 | 235k | CodeGenCoverage CoverageInfo; |
71 | 235k | assert(ISel && "Cannot work without InstructionSelector"); |
72 | 235k | |
73 | 235k | // An optimization remark emitter. Used to report failures. |
74 | 235k | MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr); |
75 | 235k | |
76 | 235k | // FIXME: There are many other MF/MFI fields we need to initialize. |
77 | 235k | |
78 | 235k | MachineRegisterInfo &MRI = MF.getRegInfo(); |
79 | | #ifndef NDEBUG |
80 | | // Check that our input is fully legal: we require the function to have the |
81 | | // Legalized property, so it should be. |
82 | | // FIXME: This should be in the MachineVerifier, as the RegBankSelected |
83 | | // property check already is. |
84 | | if (!DisableGISelLegalityCheck) |
85 | | if (const MachineInstr *MI = machineFunctionIsIllegal(MF)) { |
86 | | reportGISelFailure(MF, TPC, MORE, "gisel-select", |
87 | | "instruction is not legal", *MI); |
88 | | return false; |
89 | | } |
90 | | // FIXME: We could introduce new blocks and will need to fix the outer loop. |
91 | | // Until then, keep track of the number of blocks to assert that we don't. |
92 | | const size_t NumBlocks = MF.size(); |
93 | | #endif |
94 | | |
95 | 1.44M | for (MachineBasicBlock *MBB : post_order(&MF)) { |
96 | 1.44M | if (MBB->empty()) |
97 | 45.3k | continue; |
98 | 1.39M | |
99 | 1.39M | // Select instructions in reverse block order. We permit erasing so have |
100 | 1.39M | // to resort to manually iterating and recognizing the begin (rend) case. |
101 | 1.39M | bool ReachedBegin = false; |
102 | 1.39M | for (auto MII = std::prev(MBB->end()), Begin = MBB->begin(); |
103 | 18.5M | !ReachedBegin;) { |
104 | | #ifndef NDEBUG |
105 | | // Keep track of the insertion range for debug printing. |
106 | | const auto AfterIt = std::next(MII); |
107 | | #endif |
108 | | // Select this instruction. |
109 | 17.1M | MachineInstr &MI = *MII; |
110 | 17.1M | |
111 | 17.1M | // And have our iterator point to the next instruction, if there is one. |
112 | 17.1M | if (MII == Begin) |
113 | 1.39M | ReachedBegin = true; |
114 | 15.7M | else |
115 | 15.7M | --MII; |
116 | 17.1M | |
117 | 17.1M | LLVM_DEBUG(dbgs() << "Selecting: \n " << MI); |
118 | 17.1M | |
119 | 17.1M | // We could have folded this instruction away already, making it dead. |
120 | 17.1M | // If so, erase it. |
121 | 17.1M | if (isTriviallyDead(MI, MRI)) { |
122 | 3.34M | LLVM_DEBUG(dbgs() << "Is dead; erasing.\n"); |
123 | 3.34M | MI.eraseFromParentAndMarkDBGValuesForRemoval(); |
124 | 3.34M | continue; |
125 | 3.34M | } |
126 | 13.7M | |
127 | 13.7M | if (!ISel->select(MI, CoverageInfo)) { |
128 | 11.6k | // FIXME: It would be nice to dump all inserted instructions. It's |
129 | 11.6k | // not obvious how, esp. considering select() can insert after MI. |
130 | 11.6k | reportGISelFailure(MF, TPC, MORE, "gisel-select", "cannot select", MI); |
131 | 11.6k | return false; |
132 | 11.6k | } |
133 | 13.7M | |
134 | 13.7M | // Dump the range of instructions that MI expanded into. |
135 | 13.7M | LLVM_DEBUG({ |
136 | 13.7M | auto InsertedBegin = ReachedBegin ? MBB->begin() : std::next(MII); |
137 | 13.7M | dbgs() << "Into:\n"; |
138 | 13.7M | for (auto &InsertedMI : make_range(InsertedBegin, AfterIt)) |
139 | 13.7M | dbgs() << " " << InsertedMI; |
140 | 13.7M | dbgs() << '\n'; |
141 | 13.7M | }); |
142 | 13.7M | } |
143 | 1.39M | } |
144 | 235k | |
145 | 1.38M | for (MachineBasicBlock &MBB : MF)223k { |
146 | 1.38M | if (MBB.empty()) |
147 | 45.0k | continue; |
148 | 1.33M | |
149 | 1.33M | // Try to find redundant copies b/w vregs of the same register class. |
150 | 1.33M | bool ReachedBegin = false; |
151 | 15.5M | for (auto MII = std::prev(MBB.end()), Begin = MBB.begin(); !ReachedBegin;) { |
152 | 14.2M | // Select this instruction. |
153 | 14.2M | MachineInstr &MI = *MII; |
154 | 14.2M | |
155 | 14.2M | // And have our iterator point to the next instruction, if there is one. |
156 | 14.2M | if (MII == Begin) |
157 | 1.33M | ReachedBegin = true; |
158 | 12.8M | else |
159 | 12.8M | --MII; |
160 | 14.2M | if (MI.getOpcode() != TargetOpcode::COPY) |
161 | 10.0M | continue; |
162 | 4.20M | unsigned SrcReg = MI.getOperand(1).getReg(); |
163 | 4.20M | unsigned DstReg = MI.getOperand(0).getReg(); |
164 | 4.20M | if (TargetRegisterInfo::isVirtualRegister(SrcReg) && |
165 | 4.20M | TargetRegisterInfo::isVirtualRegister(DstReg)3.10M ) { |
166 | 610k | auto SrcRC = MRI.getRegClass(SrcReg); |
167 | 610k | auto DstRC = MRI.getRegClass(DstReg); |
168 | 610k | if (SrcRC == DstRC) { |
169 | 350k | MRI.replaceRegWith(DstReg, SrcReg); |
170 | 350k | MI.eraseFromParentAndMarkDBGValuesForRemoval(); |
171 | 350k | } |
172 | 610k | } |
173 | 4.20M | } |
174 | 1.33M | } |
175 | 223k | |
176 | | #ifndef NDEBUG |
177 | | const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); |
178 | | // Now that selection is complete, there are no more generic vregs. Verify |
179 | | // that the size of the now-constrained vreg is unchanged and that it has a |
180 | | // register class. |
181 | | for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) { |
182 | | unsigned VReg = TargetRegisterInfo::index2VirtReg(I); |
183 | | |
184 | | MachineInstr *MI = nullptr; |
185 | | if (!MRI.def_empty(VReg)) |
186 | | MI = &*MRI.def_instr_begin(VReg); |
187 | | else if (!MRI.use_empty(VReg)) |
188 | | MI = &*MRI.use_instr_begin(VReg); |
189 | | if (!MI) |
190 | | continue; |
191 | | |
192 | | const TargetRegisterClass *RC = MRI.getRegClassOrNull(VReg); |
193 | | if (!RC) { |
194 | | reportGISelFailure(MF, TPC, MORE, "gisel-select", |
195 | | "VReg has no regclass after selection", *MI); |
196 | | return false; |
197 | | } |
198 | | |
199 | | const LLT Ty = MRI.getType(VReg); |
200 | | if (Ty.isValid() && Ty.getSizeInBits() > TRI.getRegSizeInBits(*RC)) { |
201 | | reportGISelFailure( |
202 | | MF, TPC, MORE, "gisel-select", |
203 | | "VReg's low-level type and register class have different sizes", *MI); |
204 | | return false; |
205 | | } |
206 | | } |
207 | | |
208 | | if (MF.size() != NumBlocks) { |
209 | | MachineOptimizationRemarkMissed R("gisel-select", "GISelFailure", |
210 | | MF.getFunction().getSubprogram(), |
211 | | /*MBB=*/nullptr); |
212 | | R << "inserting blocks is not supported yet"; |
213 | | reportGISelFailure(MF, TPC, MORE, R); |
214 | | return false; |
215 | | } |
216 | | #endif |
217 | | auto &TLI = *MF.getSubtarget().getTargetLowering(); |
218 | 223k | TLI.finalizeLowering(MF); |
219 | 223k | |
220 | 223k | LLVM_DEBUG({ |
221 | 223k | dbgs() << "Rules covered by selecting function: " << MF.getName() << ":"; |
222 | 223k | for (auto RuleID : CoverageInfo.covered()) |
223 | 223k | dbgs() << " id" << RuleID; |
224 | 223k | dbgs() << "\n\n"; |
225 | 223k | }); |
226 | 223k | CoverageInfo.emit(CoveragePrefix, |
227 | 223k | MF.getSubtarget() |
228 | 223k | .getTargetLowering() |
229 | 223k | ->getTargetMachine() |
230 | 223k | .getTarget() |
231 | 223k | .getBackendName()); |
232 | 223k | |
233 | 223k | // If we successfully selected the function nothing is going to use the vreg |
234 | 223k | // types after us (otherwise MIRPrinter would need them). Make sure the types |
235 | 223k | // disappear. |
236 | 223k | MRI.clearVirtRegTypes(); |
237 | 223k | |
238 | 223k | // FIXME: Should we accurately track changes? |
239 | 223k | return true; |
240 | 235k | } |