LLVM: lib/Target/WebAssembly/WebAssemblyRegColoring.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
27using namespace llvm;
28
29#define DEBUG_TYPE "wasm-reg-coloring"
30
31namespace {
33public:
34 static char ID;
36
37 StringRef getPassName() const override {
38 return "WebAssembly Register Coloring";
39 }
40
41 void getAnalysisUsage(AnalysisUsage &AU) const override {
48 }
49
51
52private:
53};
54}
55
56char WebAssemblyRegColoring::ID = 0;
58 "Minimize number of registers used", false, false)
59
61 return new WebAssemblyRegColoring();
62}
63
64
67 unsigned VReg) {
68 float Weight = 0.0f;
71 *MO.getParent());
72 return Weight;
73}
74
75
76
77
78
82 DbgVRegToValues;
85
86
87
88 auto CloseNewDVRange = [&DbgVRegToValues, &ToInsert](SlotIndex Slot) {
89 for (auto *X : ToInsert) {
90 for (const auto &Op : X->debug_operands()) {
91 if (Op.isReg() && Op.getReg().isVirtual())
92 DbgVRegToValues[Op.getReg()].push_back({Slot, X});
93 }
94 }
95
96 ToInsert.clear();
97 };
98
99
100
101
102 for (auto &MBB : MF) {
104
106 if (MI.isDebugValue()) {
108 return MO.isReg() && MO.getReg().isVirtual();
109 }))
111 } else if (.isDebugOrPseudoInstr()) {
113 CloseNewDVRange(CurrentSlot);
114 }
115 }
116
117
119 }
120
121
122 for (auto &Pair : DbgVRegToValues)
124 return DbgVRegToValues;
125}
126
127
128
129
133 DenseMap<Register, std::vector<std::pair<SlotIndex, MachineInstr *>>>
134 &DbgVRegToValues) {
135#ifndef NDEBUG
137#endif
138 for (const auto &CoalescedIntervals : Assignments) {
139 if (CoalescedIntervals.empty())
140 continue;
141 for (LiveInterval *LI : CoalescedIntervals) {
143#ifndef NDEBUG
144
146#endif
147 auto RegMapIt = DbgVRegToValues.find(Reg);
148 if (RegMapIt == DbgVRegToValues.end())
149 continue;
151 bool LastUndefResult = false;
152 for (auto [Slot, DbgValue] : RegMapIt->second) {
153
154
155
156
157
158
159
160
161 if (Slot == LastSlot) {
162 if (LastUndefResult) {
164 DbgValue->setDebugValueUndef();
165 }
166 continue;
167 }
168 LastSlot = Slot;
169 LastUndefResult = false;
170 for (LiveInterval *OtherLI : CoalescedIntervals) {
171 if (LI == OtherLI)
172 continue;
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207 auto *SegmentIt = OtherLI->find(Slot);
208 if (SegmentIt != OtherLI->end() && SegmentIt->contains(Slot)) {
210 DbgValue->setDebugValueUndef();
211 LastUndefResult = true;
212 break;
213 }
214 }
215 }
216 }
217 }
218}
219
220bool WebAssemblyRegColoring::runOnMachineFunction(MachineFunction &MF) {
222 dbgs() << "********** Register Coloring **********\n"
223 << "********** Function: " << MF.getName() << '\n';
224 });
225
226
227
228
229
231 return false;
232
234 LiveIntervals *Liveness = &getAnalysis().getLIS();
235 const MachineBlockFrequencyInfo *MBFI =
236 &getAnalysis().getMBFI();
237 WebAssemblyFunctionInfo &MFI = *MF.getInfo();
238
239
240 MRI->leaveSSA();
241
242
243 unsigned NumVRegs = MRI->getNumVirtRegs();
245 SortedIntervals.reserve(NumVRegs);
246
247
249
250 LLVM_DEBUG(dbgs() << "Interesting register intervals:\n");
251 for (unsigned I = 0; I < NumVRegs; ++I) {
252 Register VReg = Register::index2VirtReg(I);
254 continue;
255
256 if (MRI->use_empty(VReg))
257 continue;
258
259 LiveInterval *LI = &Liveness->getInterval(VReg);
264 }
266
267
268
269
270
271 llvm::sort(SortedIntervals, [MRI](LiveInterval *LHS, LiveInterval *RHS) {
272 if (MRI->isLiveIn(LHS->reg()) != MRI->isLiveIn(RHS->reg()))
273 return MRI->isLiveIn(LHS->reg());
274 if (LHS->weight() != RHS->weight())
275 return LHS->weight() > RHS->weight();
276 if (LHS->empty() || RHS->empty())
277 return ->empty() && RHS->empty();
279 });
280
281 LLVM_DEBUG(dbgs() << "Coloring register intervals:\n");
282 SmallVector<unsigned, 16> SlotMapping(SortedIntervals.size(), -1u);
284 SortedIntervals.size());
285 BitVector UsedColors(SortedIntervals.size());
287 for (size_t I = 0, E = SortedIntervals.size(); I < E; ++I) {
288 LiveInterval *LI = SortedIntervals[I];
290 size_t Color = I;
291 const TargetRegisterClass *RC = MRI->getRegClass(Old);
292
293
294 if (->isLiveIn(Old))
295 for (unsigned C : UsedColors.set_bits()) {
296 if (MRI->getRegClass(SortedIntervals[C]->reg()) != RC)
297 continue;
298 for (LiveInterval *OtherLI : Assignments[C])
299 if (!OtherLI->empty() && OtherLI->overlaps(*LI))
300 goto continue_outer;
301 Color = C;
302 break;
303 continue_outer:;
304 }
305
306 Register New = SortedIntervals[Color]->reg();
309 UsedColors.set(Color);
310 Assignments[Color].push_back(LI);
311
316 }
318 return false;
319
320
322
323
324 for (size_t I = 0, E = SortedIntervals.size(); I < E; ++I) {
325 Register Old = SortedIntervals[I]->reg();
326 unsigned New = SlotMapping[I];
327 if (Old != New)
328 MRI->replaceRegWith(Old, New);
329 }
330 return true;
331}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
This file declares WebAssembly-specific per-machine-function information.
static void undefInvalidDbgValues(const LiveIntervals *Liveness, ArrayRef< SmallVector< LiveInterval *, 4 > > Assignments, DenseMap< Register, std::vector< std::pair< SlotIndex, MachineInstr * > > > &DbgVRegToValues)
Definition WebAssemblyRegColoring.cpp:130
static DenseMap< Register, std::vector< std::pair< SlotIndex, MachineInstr * > > > buildVRegToDbgValueMap(MachineFunction &MF, const LiveIntervals *Liveness)
Definition WebAssemblyRegColoring.cpp:80
static float computeWeight(const MachineRegisterInfo *MRI, const MachineBlockFrequencyInfo *MBFI, unsigned VReg)
Definition WebAssemblyRegColoring.cpp:65
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end.
Class recording the (high level) value of a variable.
Represent the analysis usage information of a pass.
AnalysisUsage & addPreservedID(const void *ID)
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Implements a dense probed hash-table based set.
FunctionPass class - This class is used to implement most global optimizations.
LiveInterval - This class represents the liveness of a register, or stack slot.
LLVM_ABI void dump() const
void setWeight(float Value)
SlotIndexes * getSlotIndexes() const
static LLVM_ABI float getSpillWeight(bool isDef, bool isUse, const MachineBlockFrequencyInfo *MBFI, const MachineInstr &MI, ProfileSummaryInfo *PSI=nullptr)
Calculate the spill weight to assign to a single instruction.
LiveInterval & getInterval(Register Reg)
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
bool exposesReturnsTwice() const
exposesReturnsTwice - Returns true if the function calls setjmp or any other similar functions with a...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
SlotIndex - An opaque wrapper around machine indexes.
SlotIndex getMBBEndIdx(unsigned Num) const
Returns the index past the last valid index in the given basic block.
SlotIndex getInstructionIndex(const MachineInstr &MI, bool IgnoreBundle=false) const
Returns the base index for the given instruction.
SlotIndex getMBBStartIdx(unsigned Num) const
Returns the first index in the given basic block number.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
void setFrameBaseVreg(unsigned Reg)
unsigned getFrameBaseVreg() const
bool isVRegStackified(Register VReg) const
bool isFrameBaseVirtual() const
std::pair< iterator, bool > insert(const ValueT &V)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
DWARFExpression::Operation Op
FunctionPass * createWebAssemblyRegColoring()
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.