/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- llvm/CodeGen/GlobalISel/InstructionSelect.cpp - InstructionSelect ---==// |
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 | | /// \file |
10 | | /// This file implements the InstructionSelect class. |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" |
14 | | #include "llvm/ADT/PostOrderIterator.h" |
15 | | #include "llvm/ADT/ScopeExit.h" |
16 | | #include "llvm/ADT/Twine.h" |
17 | | #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" |
18 | | #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" |
19 | | #include "llvm/CodeGen/GlobalISel/Utils.h" |
20 | | #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" |
21 | | #include "llvm/CodeGen/MachineRegisterInfo.h" |
22 | | #include "llvm/CodeGen/TargetPassConfig.h" |
23 | | #include "llvm/IR/Constants.h" |
24 | | #include "llvm/IR/Function.h" |
25 | | #include "llvm/Support/CommandLine.h" |
26 | | #include "llvm/Support/Debug.h" |
27 | | #include "llvm/Target/TargetLowering.h" |
28 | | #include "llvm/Target/TargetSubtargetInfo.h" |
29 | | |
30 | | #define DEBUG_TYPE "instruction-select" |
31 | | |
32 | | using namespace llvm; |
33 | | |
34 | | char InstructionSelect::ID = 0; |
35 | 90.2k | INITIALIZE_PASS_BEGIN90.2k (InstructionSelect, DEBUG_TYPE,
|
36 | 90.2k | "Select target instructions out of generic instructions", |
37 | 90.2k | false, false) |
38 | 90.2k | INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) |
39 | 90.2k | INITIALIZE_PASS_END(InstructionSelect, DEBUG_TYPE, |
40 | | "Select target instructions out of generic instructions", |
41 | | false, false) |
42 | | |
43 | 6.52k | InstructionSelect::InstructionSelect() : MachineFunctionPass(ID) { |
44 | 6.52k | initializeInstructionSelectPass(*PassRegistry::getPassRegistry()); |
45 | 6.52k | } |
46 | | |
47 | 6.50k | void InstructionSelect::getAnalysisUsage(AnalysisUsage &AU) const { |
48 | 6.50k | AU.addRequired<TargetPassConfig>(); |
49 | 6.50k | MachineFunctionPass::getAnalysisUsage(AU); |
50 | 6.50k | } |
51 | | |
52 | 223k | bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { |
53 | 223k | const MachineRegisterInfo &MRI = MF.getRegInfo(); |
54 | 223k | |
55 | 223k | // No matter what happens, whether we successfully select the function or not, |
56 | 223k | // nothing is going to use the vreg types after us. Make sure they disappear. |
57 | 223k | auto ClearVRegTypesOnReturn = |
58 | 223k | make_scope_exit([&]() { MRI.getVRegToType().clear(); }); |
59 | 223k | |
60 | 223k | // If the ISel pipeline failed, do not bother running that pass. |
61 | 223k | if (MF.getProperties().hasProperty( |
62 | 223k | MachineFunctionProperties::Property::FailedISel)) |
63 | 43.3k | return false; |
64 | 179k | |
65 | 179k | DEBUG179k (dbgs() << "Selecting function: " << MF.getName() << '\n'); |
66 | 179k | |
67 | 179k | const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>(); |
68 | 179k | const InstructionSelector *ISel = MF.getSubtarget().getInstructionSelector(); |
69 | 179k | assert(ISel && "Cannot work without InstructionSelector"); |
70 | 179k | |
71 | 179k | // An optimization remark emitter. Used to report failures. |
72 | 179k | MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr); |
73 | 179k | |
74 | 179k | // FIXME: There are many other MF/MFI fields we need to initialize. |
75 | 179k | |
76 | | #ifndef NDEBUG |
77 | | // Check that our input is fully legal: we require the function to have the |
78 | | // Legalized property, so it should be. |
79 | | // FIXME: This should be in the MachineVerifier, but it can't use the |
80 | | // LegalizerInfo as it's currently in the separate GlobalISel library. |
81 | | // The RegBankSelected property is already checked in the verifier. Note |
82 | | // that it has the same layering problem, but we only use inline methods so |
83 | | // end up not needing to link against the GlobalISel library. |
84 | | if (const LegalizerInfo *MLI = MF.getSubtarget().getLegalizerInfo()) |
85 | | for (MachineBasicBlock &MBB : MF) |
86 | | for (MachineInstr &MI : MBB) |
87 | | if (isPreISelGenericOpcode(MI.getOpcode()) && !MLI->isLegal(MI, MRI)) { |
88 | | reportGISelFailure(MF, TPC, MORE, "gisel-select", |
89 | | "instruction is not legal", MI); |
90 | | return false; |
91 | | } |
92 | | |
93 | | #endif |
94 | | // FIXME: We could introduce new blocks and will need to fix the outer loop. |
95 | 179k | // Until then, keep track of the number of blocks to assert that we don't. |
96 | 179k | const size_t NumBlocks = MF.size(); |
97 | 179k | |
98 | 472k | for (MachineBasicBlock *MBB : post_order(&MF)) { |
99 | 472k | if (MBB->empty()) |
100 | 2.31k | continue; |
101 | 470k | |
102 | 470k | // Select instructions in reverse block order. We permit erasing so have |
103 | 470k | // to resort to manually iterating and recognizing the begin (rend) case. |
104 | 470k | bool ReachedBegin = false; |
105 | 470k | for (auto MII = std::prev(MBB->end()), Begin = MBB->begin(); |
106 | 7.70M | !ReachedBegin7.70M ;) { |
107 | | #ifndef NDEBUG |
108 | | // Keep track of the insertion range for debug printing. |
109 | | const auto AfterIt = std::next(MII); |
110 | | #endif |
111 | | // Select this instruction. |
112 | 7.25M | MachineInstr &MI = *MII; |
113 | 7.25M | |
114 | 7.25M | // And have our iterator point to the next instruction, if there is one. |
115 | 7.25M | if (MII == Begin) |
116 | 455k | ReachedBegin = true; |
117 | 7.25M | else |
118 | 6.79M | --MII; |
119 | 7.25M | |
120 | 7.25M | DEBUG(dbgs() << "Selecting: \n " << MI); |
121 | 7.25M | |
122 | 7.25M | // We could have folded this instruction away already, making it dead. |
123 | 7.25M | // If so, erase it. |
124 | 7.25M | if (isTriviallyDead(MI, MRI)7.25M ) { |
125 | 769k | DEBUG(dbgs() << "Is dead; erasing.\n"); |
126 | 769k | MI.eraseFromParentAndMarkDBGValuesForRemoval(); |
127 | 769k | continue; |
128 | 769k | } |
129 | 6.48M | |
130 | 6.48M | if (6.48M !ISel->select(MI)6.48M ) { |
131 | 20.1k | // FIXME: It would be nice to dump all inserted instructions. It's |
132 | 20.1k | // not obvious how, esp. considering select() can insert after MI. |
133 | 20.1k | reportGISelFailure(MF, TPC, MORE, "gisel-select", "cannot select", MI); |
134 | 20.1k | return false; |
135 | 20.1k | } |
136 | 6.46M | |
137 | 6.46M | // Dump the range of instructions that MI expanded into. |
138 | 6.46M | DEBUG6.46M ({ |
139 | 6.46M | auto InsertedBegin = ReachedBegin ? MBB->begin() : std::next(MII); |
140 | 6.46M | dbgs() << "Into:\n"; |
141 | 6.46M | for (auto &InsertedMI : make_range(InsertedBegin, AfterIt)) |
142 | 6.46M | dbgs() << " " << InsertedMI; |
143 | 6.46M | dbgs() << '\n'; |
144 | 6.46M | }); |
145 | 6.46M | } |
146 | 472k | } |
147 | 179k | |
148 | 159k | const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); |
149 | 159k | |
150 | 159k | // Now that selection is complete, there are no more generic vregs. Verify |
151 | 159k | // that the size of the now-constrained vreg is unchanged and that it has a |
152 | 159k | // register class. |
153 | 3.18M | for (auto &VRegToType : MRI.getVRegToType()) { |
154 | 3.18M | unsigned VReg = VRegToType.first; |
155 | 3.18M | auto *RC = MRI.getRegClassOrNull(VReg); |
156 | 3.18M | MachineInstr *MI = nullptr; |
157 | 3.18M | if (!MRI.def_empty(VReg)) |
158 | 2.42M | MI = &*MRI.def_instr_begin(VReg); |
159 | 765k | else if (765k !MRI.use_empty(VReg)765k ) |
160 | 0 | MI = &*MRI.use_instr_begin(VReg); |
161 | 3.18M | |
162 | 3.18M | if (MI && 3.18M !RC2.42M ) { |
163 | 179 | reportGISelFailure(MF, TPC, MORE, "gisel-select", |
164 | 179 | "VReg has no regclass after selection", *MI); |
165 | 179 | return false; |
166 | 3.18M | } else if (3.18M !RC3.18M ) |
167 | 765k | continue; |
168 | 2.42M | |
169 | 2.42M | if (2.42M VRegToType.second.isValid() && |
170 | 2.42M | VRegToType.second.getSizeInBits() > TRI.getRegSizeInBits(*RC)2.42M ) { |
171 | 0 | reportGISelFailure(MF, TPC, MORE, "gisel-select", |
172 | 0 | "VReg has explicit size different from class size", |
173 | 0 | *MI); |
174 | 0 | return false; |
175 | 0 | } |
176 | 159k | } |
177 | 159k | |
178 | 159k | if (159k MF.size() != NumBlocks159k ) { |
179 | 0 | MachineOptimizationRemarkMissed R("gisel-select", "GISelFailure", |
180 | 0 | MF.getFunction()->getSubprogram(), |
181 | 0 | /*MBB=*/nullptr); |
182 | 0 | R << "inserting blocks is not supported yet"; |
183 | 0 | reportGISelFailure(MF, TPC, MORE, R); |
184 | 0 | return false; |
185 | 0 | } |
186 | 159k | |
187 | 159k | auto &TLI = *MF.getSubtarget().getTargetLowering(); |
188 | 159k | TLI.finalizeLowering(MF); |
189 | 159k | |
190 | 159k | // FIXME: Should we accurately track changes? |
191 | 159k | return true; |
192 | 159k | } |