annotate lib/CodeGen/MIRCanonicalizerPass.cpp @ 134:3a76565eade5 LLVM5.0.1

update 5.0.1
author mir3636
date Sat, 17 Feb 2018 09:57:20 +0900
parents
children c2174574ed3a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
134
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
1 //===-------------- MIRCanonicalizer.cpp - MIR Canonicalizer --------------===//
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
2 //
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
3 // The LLVM Compiler Infrastructure
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
4 //
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
5 // This file is distributed under the University of Illinois Open Source
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
6 // License. See LICENSE.TXT for details.
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
7 //
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
8 //===----------------------------------------------------------------------===//
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
9 //
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
10 // The purpose of this pass is to employ a canonical code transformation so
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
11 // that code compiled with slightly different IR passes can be diffed more
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
12 // effectively than otherwise. This is done by renaming vregs in a given
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
13 // LiveRange in a canonical way. This pass also does a pseudo-scheduling to
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
14 // move defs closer to their use inorder to reduce diffs caused by slightly
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
15 // different schedules.
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
16 //
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
17 // Basic Usage:
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
18 //
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
19 // llc -o - -run-pass mir-canonicalizer example.mir
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
20 //
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
21 // Reorders instructions canonically.
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
22 // Renames virtual register operands canonically.
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
23 // Strips certain MIR artifacts (optionally).
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
24 //
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
25 //===----------------------------------------------------------------------===//
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
26
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
27 #include "llvm/ADT/PostOrderIterator.h"
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
28 #include "llvm/ADT/STLExtras.h"
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
29 #include "llvm/CodeGen/MachineFunctionPass.h"
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
30 #include "llvm/CodeGen/MachineInstrBuilder.h"
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
31 #include "llvm/CodeGen/MachineRegisterInfo.h"
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
32 #include "llvm/CodeGen/Passes.h"
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
33 #include "llvm/Support/raw_ostream.h"
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
34
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
35 #include <queue>
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
36
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
37 using namespace llvm;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
38
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
39 namespace llvm {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
40 extern char &MIRCanonicalizerID;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
41 } // namespace llvm
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
42
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
43 #define DEBUG_TYPE "mir-canonicalizer"
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
44
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
45 static cl::opt<unsigned>
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
46 CanonicalizeFunctionNumber("canon-nth-function", cl::Hidden, cl::init(~0u),
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
47 cl::value_desc("N"),
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
48 cl::desc("Function number to canonicalize."));
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
49
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
50 static cl::opt<unsigned>
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
51 CanonicalizeBasicBlockNumber("canon-nth-basicblock", cl::Hidden, cl::init(~0u),
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
52 cl::value_desc("N"),
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
53 cl::desc("BasicBlock number to canonicalize."));
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
54
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
55 namespace {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
56
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
57 class MIRCanonicalizer : public MachineFunctionPass {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
58 public:
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
59 static char ID;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
60 MIRCanonicalizer() : MachineFunctionPass(ID) {}
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
61
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
62 StringRef getPassName() const override {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
63 return "Rename register operands in a canonical ordering.";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
64 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
65
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
66 void getAnalysisUsage(AnalysisUsage &AU) const override {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
67 AU.setPreservesCFG();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
68 MachineFunctionPass::getAnalysisUsage(AU);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
69 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
70
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
71 bool runOnMachineFunction(MachineFunction &MF) override;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
72 };
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
73
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
74 } // end anonymous namespace
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
75
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
76 enum VRType { RSE_Reg = 0, RSE_FrameIndex, RSE_NewCandidate };
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
77 class TypedVReg {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
78 VRType type;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
79 unsigned reg;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
80
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
81 public:
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
82 TypedVReg(unsigned reg) : type(RSE_Reg), reg(reg) {}
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
83 TypedVReg(VRType type) : type(type), reg(~0U) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
84 assert(type != RSE_Reg && "Expected a non-register type.");
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
85 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
86
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
87 bool isReg() const { return type == RSE_Reg; }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
88 bool isFrameIndex() const { return type == RSE_FrameIndex; }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
89 bool isCandidate() const { return type == RSE_NewCandidate; }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
90
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
91 VRType getType() const { return type; }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
92 unsigned getReg() const {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
93 assert(this->isReg() && "Expected a virtual or physical register.");
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
94 return reg;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
95 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
96 };
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
97
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
98 char MIRCanonicalizer::ID;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
99
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
100 char &llvm::MIRCanonicalizerID = MIRCanonicalizer::ID;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
101
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
102 INITIALIZE_PASS_BEGIN(MIRCanonicalizer, "mir-canonicalizer",
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
103 "Rename Register Operands Canonically", false, false)
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
104
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
105 INITIALIZE_PASS_END(MIRCanonicalizer, "mir-canonicalizer",
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
106 "Rename Register Operands Canonically", false, false)
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
107
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
108 static std::vector<MachineBasicBlock *> GetRPOList(MachineFunction &MF) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
109 ReversePostOrderTraversal<MachineBasicBlock *> RPOT(&*MF.begin());
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
110 std::vector<MachineBasicBlock *> RPOList;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
111 for (auto MBB : RPOT) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
112 RPOList.push_back(MBB);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
113 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
114
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
115 return RPOList;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
116 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
117
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
118 // Set a dummy vreg. We use this vregs register class to generate throw-away
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
119 // vregs that are used to skip vreg numbers so that vreg numbers line up.
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
120 static unsigned GetDummyVReg(const MachineFunction &MF) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
121 for (auto &MBB : MF) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
122 for (auto &MI : MBB) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
123 for (auto &MO : MI.operands()) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
124 if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
125 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
126 return MO.getReg();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
127 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
128 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
129 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
130
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
131 return ~0U;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
132 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
133
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
134 static bool rescheduleCanonically(MachineBasicBlock *MBB) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
135
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
136 bool Changed = false;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
137
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
138 // Calculates the distance of MI from the begining of its parent BB.
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
139 auto getInstrIdx = [](const MachineInstr &MI) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
140 unsigned i = 0;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
141 for (auto &CurMI : *MI.getParent()) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
142 if (&CurMI == &MI)
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
143 return i;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
144 i++;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
145 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
146 return ~0U;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
147 };
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
148
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
149 // Pre-Populate vector of instructions to reschedule so that we don't
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
150 // clobber the iterator.
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
151 std::vector<MachineInstr *> Instructions;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
152 for (auto &MI : *MBB) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
153 Instructions.push_back(&MI);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
154 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
155
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
156 for (auto *II : Instructions) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
157 if (II->getNumOperands() == 0)
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
158 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
159
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
160 MachineOperand &MO = II->getOperand(0);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
161 if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
162 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
163
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
164 DEBUG(dbgs() << "Operand " << 0 << " of "; II->dump(); MO.dump(););
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
165
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
166 MachineInstr *Def = II;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
167 unsigned Distance = ~0U;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
168 MachineInstr *UseToBringDefCloserTo = nullptr;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
169 MachineRegisterInfo *MRI = &MBB->getParent()->getRegInfo();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
170 for (auto &UO : MRI->use_nodbg_operands(MO.getReg())) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
171 MachineInstr *UseInst = UO.getParent();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
172
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
173 const unsigned DefLoc = getInstrIdx(*Def);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
174 const unsigned UseLoc = getInstrIdx(*UseInst);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
175 const unsigned Delta = (UseLoc - DefLoc);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
176
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
177 if (UseInst->getParent() != Def->getParent())
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
178 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
179 if (DefLoc >= UseLoc)
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
180 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
181
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
182 if (Delta < Distance) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
183 Distance = Delta;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
184 UseToBringDefCloserTo = UseInst;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
185 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
186 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
187
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
188 const auto BBE = MBB->instr_end();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
189 MachineBasicBlock::iterator DefI = BBE;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
190 MachineBasicBlock::iterator UseI = BBE;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
191
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
192 for (auto BBI = MBB->instr_begin(); BBI != BBE; ++BBI) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
193
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
194 if (DefI != BBE && UseI != BBE)
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
195 break;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
196
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
197 if ((&*BBI != Def) && (&*BBI != UseToBringDefCloserTo))
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
198 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
199
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
200 if (&*BBI == Def) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
201 DefI = BBI;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
202 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
203 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
204
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
205 if (&*BBI == UseToBringDefCloserTo) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
206 UseI = BBI;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
207 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
208 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
209 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
210
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
211 if (DefI == BBE || UseI == BBE)
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
212 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
213
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
214 DEBUG({
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
215 dbgs() << "Splicing ";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
216 DefI->dump();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
217 dbgs() << " right before: ";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
218 UseI->dump();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
219 });
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
220
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
221 Changed = true;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
222 MBB->splice(UseI, MBB, DefI);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
223 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
224
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
225 return Changed;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
226 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
227
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
228 /// Here we find our candidates. What makes an interesting candidate?
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
229 /// An candidate for a canonicalization tree root is normally any kind of
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
230 /// instruction that causes side effects such as a store to memory or a copy to
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
231 /// a physical register or a return instruction. We use these as an expression
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
232 /// tree root that we walk inorder to build a canonical walk which should result
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
233 /// in canoncal vreg renaming.
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
234 static std::vector<MachineInstr *> populateCandidates(MachineBasicBlock *MBB) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
235 std::vector<MachineInstr *> Candidates;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
236 MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
237
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
238 for (auto II = MBB->begin(), IE = MBB->end(); II != IE; ++II) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
239 MachineInstr *MI = &*II;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
240
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
241 bool DoesMISideEffect = false;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
242
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
243 if (MI->getNumOperands() > 0 && MI->getOperand(0).isReg()) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
244 const unsigned Dst = MI->getOperand(0).getReg();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
245 DoesMISideEffect |= !TargetRegisterInfo::isVirtualRegister(Dst);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
246
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
247 for (auto UI = MRI.use_begin(Dst); UI != MRI.use_end(); ++UI) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
248 if (DoesMISideEffect) break;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
249 DoesMISideEffect |= (UI->getParent()->getParent() != MI->getParent());
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
250 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
251 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
252
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
253 if (!MI->mayStore() && !MI->isBranch() && !DoesMISideEffect)
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
254 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
255
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
256 DEBUG(dbgs() << "Found Candidate: "; MI->dump(););
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
257 Candidates.push_back(MI);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
258 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
259
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
260 return Candidates;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
261 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
262
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
263 static void doCandidateWalk(std::vector<TypedVReg> &VRegs,
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
264 std::queue<TypedVReg> &RegQueue,
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
265 std::vector<MachineInstr *> &VisitedMIs,
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
266 const MachineBasicBlock *MBB) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
267
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
268 const MachineFunction &MF = *MBB->getParent();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
269 const MachineRegisterInfo &MRI = MF.getRegInfo();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
270
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
271 while (!RegQueue.empty()) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
272
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
273 auto TReg = RegQueue.front();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
274 RegQueue.pop();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
275
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
276 if (TReg.isFrameIndex()) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
277 DEBUG(dbgs() << "Popping frame index.\n";);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
278 VRegs.push_back(TypedVReg(RSE_FrameIndex));
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
279 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
280 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
281
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
282 assert(TReg.isReg() && "Expected vreg or physreg.");
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
283 unsigned Reg = TReg.getReg();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
284
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
285 if (TargetRegisterInfo::isVirtualRegister(Reg)) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
286 DEBUG({
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
287 dbgs() << "Popping vreg ";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
288 MRI.def_begin(Reg)->dump();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
289 dbgs() << "\n";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
290 });
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
291
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
292 if (!llvm::any_of(VRegs, [&](const TypedVReg &TR) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
293 return TR.isReg() && TR.getReg() == Reg;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
294 })) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
295 VRegs.push_back(TypedVReg(Reg));
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
296 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
297 } else {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
298 DEBUG(dbgs() << "Popping physreg.\n";);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
299 VRegs.push_back(TypedVReg(Reg));
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
300 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
301 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
302
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
303 for (auto RI = MRI.def_begin(Reg), RE = MRI.def_end(); RI != RE; ++RI) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
304 MachineInstr *Def = RI->getParent();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
305
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
306 if (Def->getParent() != MBB)
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
307 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
308
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
309 if (llvm::any_of(VisitedMIs,
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
310 [&](const MachineInstr *VMI) { return Def == VMI; })) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
311 break;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
312 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
313
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
314 DEBUG({
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
315 dbgs() << "\n========================\n";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
316 dbgs() << "Visited MI: ";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
317 Def->dump();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
318 dbgs() << "BB Name: " << Def->getParent()->getName() << "\n";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
319 dbgs() << "\n========================\n";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
320 });
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
321 VisitedMIs.push_back(Def);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
322 for (unsigned I = 1, E = Def->getNumOperands(); I != E; ++I) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
323
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
324 MachineOperand &MO = Def->getOperand(I);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
325 if (MO.isFI()) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
326 DEBUG(dbgs() << "Pushing frame index.\n";);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
327 RegQueue.push(TypedVReg(RSE_FrameIndex));
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
328 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
329
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
330 if (!MO.isReg())
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
331 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
332 RegQueue.push(TypedVReg(MO.getReg()));
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
333 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
334 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
335 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
336 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
337
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
338 // TODO: Work to remove this in the future. One day when we have named vregs
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
339 // we should be able to form the canonical name based on some characteristic
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
340 // we see in that point of the expression tree (like if we were to name based
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
341 // on some sort of value numbering scheme).
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
342 static void SkipVRegs(unsigned &VRegGapIndex, MachineRegisterInfo &MRI,
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
343 const TargetRegisterClass *RC) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
344 const unsigned VR_GAP = (++VRegGapIndex * 1000);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
345
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
346 DEBUG({
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
347 dbgs() << "Adjusting per-BB VR_GAP for BB" << VRegGapIndex << " to "
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
348 << VR_GAP << "\n";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
349 });
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
350
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
351 unsigned I = MRI.createVirtualRegister(RC);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
352 const unsigned E = (((I + VR_GAP) / VR_GAP) + 1) * VR_GAP;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
353 while (I != E) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
354 I = MRI.createVirtualRegister(RC);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
355 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
356 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
357
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
358 static std::map<unsigned, unsigned>
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
359 GetVRegRenameMap(const std::vector<TypedVReg> &VRegs,
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
360 const std::vector<unsigned> &renamedInOtherBB,
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
361 MachineRegisterInfo &MRI,
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
362 const TargetRegisterClass *RC) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
363 std::map<unsigned, unsigned> VRegRenameMap;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
364 unsigned LastRenameReg = MRI.createVirtualRegister(RC);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
365 bool FirstCandidate = true;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
366
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
367 for (auto &vreg : VRegs) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
368 if (vreg.isFrameIndex()) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
369 // We skip one vreg for any frame index because there is a good chance
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
370 // (especially when comparing SelectionDAG to GlobalISel generated MIR)
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
371 // that in the other file we are just getting an incoming vreg that comes
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
372 // from a copy from a frame index. So it's safe to skip by one.
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
373 LastRenameReg = MRI.createVirtualRegister(RC);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
374 DEBUG(dbgs() << "Skipping rename for FI " << LastRenameReg << "\n";);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
375 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
376 } else if (vreg.isCandidate()) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
377
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
378 // After the first candidate, for every subsequent candidate, we skip mod
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
379 // 10 registers so that the candidates are more likely to start at the
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
380 // same vreg number making it more likely that the canonical walk from the
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
381 // candidate insruction. We don't need to skip from the first candidate of
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
382 // the BasicBlock because we already skip ahead several vregs for each BB.
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
383 while (LastRenameReg % 10) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
384 if (!FirstCandidate) break;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
385 LastRenameReg = MRI.createVirtualRegister(RC);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
386
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
387 DEBUG({
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
388 dbgs() << "Skipping rename for new candidate " << LastRenameReg
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
389 << "\n";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
390 });
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
391 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
392 FirstCandidate = false;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
393 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
394 } else if (!TargetRegisterInfo::isVirtualRegister(vreg.getReg())) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
395 LastRenameReg = MRI.createVirtualRegister(RC);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
396 DEBUG({
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
397 dbgs() << "Skipping rename for Phys Reg " << LastRenameReg << "\n";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
398 });
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
399 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
400 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
401
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
402 auto Reg = vreg.getReg();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
403 if (llvm::find(renamedInOtherBB, Reg) != renamedInOtherBB.end()) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
404 DEBUG(dbgs() << "Vreg " << Reg << " already renamed in other BB.\n";);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
405 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
406 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
407
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
408 auto Rename = MRI.createVirtualRegister(MRI.getRegClass(Reg));
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
409 LastRenameReg = Rename;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
410
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
411 if (VRegRenameMap.find(Reg) == VRegRenameMap.end()) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
412 DEBUG(dbgs() << "Mapping vreg ";);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
413 if (MRI.reg_begin(Reg) != MRI.reg_end()) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
414 DEBUG(auto foo = &*MRI.reg_begin(Reg); foo->dump(););
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
415 } else {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
416 DEBUG(dbgs() << Reg;);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
417 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
418 DEBUG(dbgs() << " to ";);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
419 if (MRI.reg_begin(Rename) != MRI.reg_end()) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
420 DEBUG(auto foo = &*MRI.reg_begin(Rename); foo->dump(););
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
421 } else {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
422 DEBUG(dbgs() << Rename;);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
423 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
424 DEBUG(dbgs() << "\n";);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
425
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
426 VRegRenameMap.insert(std::pair<unsigned, unsigned>(Reg, Rename));
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
427 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
428 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
429
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
430 return VRegRenameMap;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
431 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
432
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
433 static bool doVRegRenaming(std::vector<unsigned> &RenamedInOtherBB,
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
434 const std::map<unsigned, unsigned> &VRegRenameMap,
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
435 MachineRegisterInfo &MRI) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
436 bool Changed = false;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
437 for (auto I = VRegRenameMap.begin(), E = VRegRenameMap.end(); I != E; ++I) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
438
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
439 auto VReg = I->first;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
440 auto Rename = I->second;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
441
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
442 RenamedInOtherBB.push_back(Rename);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
443
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
444 std::vector<MachineOperand *> RenameMOs;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
445 for (auto &MO : MRI.reg_operands(VReg)) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
446 RenameMOs.push_back(&MO);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
447 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
448
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
449 for (auto *MO : RenameMOs) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
450 Changed = true;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
451 MO->setReg(Rename);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
452
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
453 if (!MO->isDef())
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
454 MO->setIsKill(false);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
455 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
456 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
457
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
458 return Changed;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
459 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
460
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
461 static bool doDefKillClear(MachineBasicBlock *MBB) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
462 bool Changed = false;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
463
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
464 for (auto &MI : *MBB) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
465 for (auto &MO : MI.operands()) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
466 if (!MO.isReg())
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
467 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
468 if (!MO.isDef() && MO.isKill()) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
469 Changed = true;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
470 MO.setIsKill(false);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
471 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
472
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
473 if (MO.isDef() && MO.isDead()) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
474 Changed = true;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
475 MO.setIsDead(false);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
476 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
477 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
478 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
479
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
480 return Changed;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
481 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
482
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
483 static bool runOnBasicBlock(MachineBasicBlock *MBB,
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
484 std::vector<StringRef> &bbNames,
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
485 std::vector<unsigned> &renamedInOtherBB,
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
486 unsigned &basicBlockNum, unsigned &VRegGapIndex) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
487
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
488 if (CanonicalizeBasicBlockNumber != ~0U) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
489 if (CanonicalizeBasicBlockNumber != basicBlockNum++)
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
490 return false;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
491 DEBUG(dbgs() << "\n Canonicalizing BasicBlock " << MBB->getName() << "\n";);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
492 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
493
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
494 if (llvm::find(bbNames, MBB->getName()) != bbNames.end()) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
495 DEBUG({
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
496 dbgs() << "Found potentially duplicate BasicBlocks: " << MBB->getName()
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
497 << "\n";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
498 });
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
499 return false;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
500 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
501
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
502 DEBUG({
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
503 dbgs() << "\n\n NEW BASIC BLOCK: " << MBB->getName() << " \n\n";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
504 dbgs() << "\n\n================================================\n\n";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
505 });
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
506
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
507 bool Changed = false;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
508 MachineFunction &MF = *MBB->getParent();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
509 MachineRegisterInfo &MRI = MF.getRegInfo();
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
510
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
511 const unsigned DummyVReg = GetDummyVReg(MF);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
512 const TargetRegisterClass *DummyRC =
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
513 (DummyVReg == ~0U) ? nullptr : MRI.getRegClass(DummyVReg);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
514 if (!DummyRC) return false;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
515
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
516 bbNames.push_back(MBB->getName());
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
517 DEBUG(dbgs() << "\n\n NEW BASIC BLOCK: " << MBB->getName() << "\n\n";);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
518
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
519 DEBUG(dbgs() << "MBB Before Scheduling:\n"; MBB->dump(););
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
520 Changed |= rescheduleCanonically(MBB);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
521 DEBUG(dbgs() << "MBB After Scheduling:\n"; MBB->dump(););
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
522
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
523 std::vector<MachineInstr *> Candidates = populateCandidates(MBB);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
524 std::vector<MachineInstr *> VisitedMIs;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
525 std::copy(Candidates.begin(), Candidates.end(),
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
526 std::back_inserter(VisitedMIs));
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
527
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
528 std::vector<TypedVReg> VRegs;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
529 for (auto candidate : Candidates) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
530 VRegs.push_back(TypedVReg(RSE_NewCandidate));
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
531
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
532 std::queue<TypedVReg> RegQueue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
533
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
534 // Here we walk the vreg operands of a non-root node along our walk.
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
535 // The root nodes are the original candidates (stores normally).
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
536 // These are normally not the root nodes (except for the case of copies to
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
537 // physical registers).
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
538 for (unsigned i = 1; i < candidate->getNumOperands(); i++) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
539 if (candidate->mayStore() || candidate->isBranch())
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
540 break;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
541
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
542 MachineOperand &MO = candidate->getOperand(i);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
543 if (!(MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg())))
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
544 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
545
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
546 DEBUG(dbgs() << "Enqueue register"; MO.dump(); dbgs() << "\n";);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
547 RegQueue.push(TypedVReg(MO.getReg()));
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
548 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
549
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
550 // Here we walk the root candidates. We start from the 0th operand because
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
551 // the root is normally a store to a vreg.
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
552 for (unsigned i = 0; i < candidate->getNumOperands(); i++) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
553
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
554 if (!candidate->mayStore() && !candidate->isBranch())
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
555 break;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
556
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
557 MachineOperand &MO = candidate->getOperand(i);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
558
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
559 // TODO: Do we want to only add vregs here?
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
560 if (!MO.isReg() && !MO.isFI())
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
561 continue;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
562
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
563 DEBUG(dbgs() << "Enqueue Reg/FI"; MO.dump(); dbgs() << "\n";);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
564
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
565 RegQueue.push(MO.isReg() ? TypedVReg(MO.getReg()) :
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
566 TypedVReg(RSE_FrameIndex));
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
567 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
568
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
569 doCandidateWalk(VRegs, RegQueue, VisitedMIs, MBB);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
570 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
571
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
572 // If we have populated no vregs to rename then bail.
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
573 // The rest of this function does the vreg remaping.
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
574 if (VRegs.size() == 0)
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
575 return Changed;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
576
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
577 // Skip some vregs, so we can recon where we'll land next.
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
578 SkipVRegs(VRegGapIndex, MRI, DummyRC);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
579
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
580 auto VRegRenameMap = GetVRegRenameMap(VRegs, renamedInOtherBB, MRI, DummyRC);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
581 Changed |= doVRegRenaming(renamedInOtherBB, VRegRenameMap, MRI);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
582 Changed |= doDefKillClear(MBB);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
583
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
584 DEBUG(dbgs() << "Updated MachineBasicBlock:\n"; MBB->dump(); dbgs() << "\n";);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
585 DEBUG(dbgs() << "\n\n================================================\n\n");
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
586 return Changed;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
587 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
588
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
589 bool MIRCanonicalizer::runOnMachineFunction(MachineFunction &MF) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
590
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
591 static unsigned functionNum = 0;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
592 if (CanonicalizeFunctionNumber != ~0U) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
593 if (CanonicalizeFunctionNumber != functionNum++)
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
594 return false;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
595 DEBUG(dbgs() << "\n Canonicalizing Function " << MF.getName() << "\n";);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
596 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
597
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
598 // we need a valid vreg to create a vreg type for skipping all those
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
599 // stray vreg numbers so reach alignment/canonical vreg values.
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
600 std::vector<MachineBasicBlock*> RPOList = GetRPOList(MF);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
601
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
602 DEBUG(
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
603 dbgs() << "\n\n NEW MACHINE FUNCTION: " << MF.getName() << " \n\n";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
604 dbgs() << "\n\n================================================\n\n";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
605 dbgs() << "Total Basic Blocks: " << RPOList.size() << "\n";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
606 for (auto MBB : RPOList) {
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
607 dbgs() << MBB->getName() << "\n";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
608 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
609 dbgs() << "\n\n================================================\n\n";
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
610 );
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
611
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
612 std::vector<StringRef> BBNames;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
613 std::vector<unsigned> RenamedInOtherBB;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
614
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
615 unsigned GapIdx = 0;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
616 unsigned BBNum = 0;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
617
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
618 bool Changed = false;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
619
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
620 for (auto MBB : RPOList)
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
621 Changed |= runOnBasicBlock(MBB, BBNames, RenamedInOtherBB, BBNum, GapIdx);
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
622
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
623 return Changed;
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
624 }
3a76565eade5 update 5.0.1
mir3636
parents:
diff changeset
625