Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / lib / Target / WebAssembly / WebAssemblyDebugValueManager.cpp
blobfd510f85a8a37aaa054540b85fc0ea56fb5bef6f
1 //===-- WebAssemblyDebugValueManager.cpp - WebAssembly DebugValue Manager -===//
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 /// \file
10 /// This file implements the manager for MachineInstr DebugValues.
11 ///
12 //===----------------------------------------------------------------------===//
14 #include "WebAssemblyDebugValueManager.h"
15 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
16 #include "WebAssembly.h"
17 #include "WebAssemblyMachineFunctionInfo.h"
18 #include "llvm/CodeGen/MachineInstr.h"
19 #include "llvm/IR/DebugInfoMetadata.h"
21 using namespace llvm;
23 WebAssemblyDebugValueManager::WebAssemblyDebugValueManager(MachineInstr *Def)
24 : Def(Def) {
25 // This code differs from MachineInstr::collectDebugValues in that it scans
26 // the whole BB, not just contiguous DBG_VALUEs, until another definition to
27 // the same register is encountered.
28 if (!Def->getOperand(0).isReg())
29 return;
30 CurrentReg = Def->getOperand(0).getReg();
32 for (MachineBasicBlock::iterator MI = std::next(Def->getIterator()),
33 ME = Def->getParent()->end();
34 MI != ME; ++MI) {
35 // If another definition appears, stop
36 if (MI->definesRegister(CurrentReg))
37 break;
38 if (MI->isDebugValue() && MI->hasDebugOperandForReg(CurrentReg))
39 DbgValues.push_back(&*MI);
43 // Returns true if both A and B are the same CONST_I32/I64/F32/F64 instructions.
44 // Doesn't include CONST_V128.
45 static bool isSameScalarConst(const MachineInstr *A, const MachineInstr *B) {
46 if (A->getOpcode() != B->getOpcode() ||
47 !WebAssembly::isScalarConst(A->getOpcode()) ||
48 !WebAssembly::isScalarConst(B->getOpcode()))
49 return false;
50 const MachineOperand &OpA = A->getOperand(1), &OpB = B->getOperand(1);
51 if ((OpA.isImm() && OpB.isImm() && OpA.getImm() == OpB.getImm()) ||
52 (OpA.isFPImm() && OpB.isFPImm() && OpA.getFPImm() == OpB.getFPImm()) ||
53 (OpA.isGlobal() && OpB.isGlobal() && OpA.getGlobal() == OpB.getGlobal()))
54 return true;
55 return false;
58 SmallVector<MachineInstr *, 1>
59 WebAssemblyDebugValueManager::getSinkableDebugValues(
60 MachineInstr *Insert) const {
61 if (DbgValues.empty())
62 return {};
63 // DBG_VALUEs between Def and Insert
64 SmallVector<MachineInstr *, 8> DbgValuesInBetween;
66 if (Def->getParent() == Insert->getParent()) {
67 // When Def and Insert are within the same BB, check if Insert comes after
68 // Def, because we only support sinking.
69 bool DefFirst = false;
70 for (MachineBasicBlock::iterator MI = std::next(Def->getIterator()),
71 ME = Def->getParent()->end();
72 MI != ME; ++MI) {
73 if (&*MI == Insert) {
74 DefFirst = true;
75 break;
77 if (MI->isDebugValue())
78 DbgValuesInBetween.push_back(&*MI);
80 if (!DefFirst) // Not a sink
81 return {};
83 } else { // Def and Insert are in different BBs
84 // If Def and Insert are in different BBs, we only handle a simple case in
85 // which Insert's BB is a successor of Def's BB.
86 if (!Def->getParent()->isSuccessor(Insert->getParent()))
87 return {};
89 // Gather DBG_VALUEs between 'Def~Def BB's end' and
90 // 'Insert BB's begin~Insert'
91 for (MachineBasicBlock::iterator MI = std::next(Def->getIterator()),
92 ME = Def->getParent()->end();
93 MI != ME; ++MI) {
94 if (MI->isDebugValue())
95 DbgValuesInBetween.push_back(&*MI);
97 for (MachineBasicBlock::iterator MI = Insert->getParent()->begin(),
98 ME = Insert->getIterator();
99 MI != ME; ++MI) {
100 if (MI->isDebugValue())
101 DbgValuesInBetween.push_back(&*MI);
105 // Gather DebugVariables that are seen between Def and Insert, excluding our
106 // own DBG_VALUEs in DbgValues.
107 SmallDenseMap<DebugVariable, SmallVector<MachineInstr *, 2>>
108 SeenDbgVarToDbgValues;
109 for (auto *DV : DbgValuesInBetween) {
110 if (!llvm::is_contained(DbgValues, DV)) {
111 DebugVariable Var(DV->getDebugVariable(), DV->getDebugExpression(),
112 DV->getDebugLoc()->getInlinedAt());
113 SeenDbgVarToDbgValues[Var].push_back(DV);
117 // Gather sinkable DBG_VALUEs. We should not sink a DBG_VALUE if there is
118 // another DBG_VALUE between Def and Insert referring to the same
119 // DebugVariable. For example,
120 // %0 = someinst
121 // DBG_VALUE %0, !"a", !DIExpression() // Should not sink with %0
122 // %1 = anotherinst
123 // DBG_VALUE %1, !"a", !DIExpression()
124 // Where if %0 were to sink, the DBG_VAUE should not sink with it, as that
125 // would re-order assignments.
126 SmallVector<MachineInstr *, 1> SinkableDbgValues;
127 MachineRegisterInfo &MRI = Def->getParent()->getParent()->getRegInfo();
128 for (auto *DV : DbgValues) {
129 DebugVariable Var(DV->getDebugVariable(), DV->getDebugExpression(),
130 DV->getDebugLoc()->getInlinedAt());
131 auto It = SeenDbgVarToDbgValues.find(Var);
132 if (It == SeenDbgVarToDbgValues.end()) {
133 SinkableDbgValues.push_back(DV);
134 continue;
136 if (!WebAssembly::isScalarConst(Def->getOpcode()))
137 continue;
138 auto &OverlappingDbgValues = It->second;
139 bool Sinkable = true;
140 for (auto *OverlappingDV : OverlappingDbgValues) {
141 MachineOperand &DbgOp = OverlappingDV->getDebugOperand(0);
142 if (!DbgOp.isReg()) {
143 Sinkable = false;
144 break;
146 Register OtherReg = DbgOp.getReg();
147 MachineInstr *OtherDef = MRI.getUniqueVRegDef(OtherReg);
148 // We have an exception to allow encoutering other DBG_VALUEs with the
149 // smae DebugVariables, only when they are referring to the same scalar
150 // CONST instruction. For example,
151 // %0 = CONST_I32 1
152 // DBG_VALUE %0, !"a", !DIExpression() // Can sink with %0
153 // %1 = CONST_I32 1
154 // DBG_VALUE %1, !"a", !DIExpression()
155 // When %0 were to be sunk/cloneed, the DBG_VALUE can be sunk/cloned with
156 // it because even though the second DBG_VALUE refers to the same
157 // DebugVariable, its value in effect is the same CONST instruction.
159 // This is to allow a case that can happen with RegStackify's
160 // "rematerializeCheapDef". For example, we have this program with two
161 // BBs:
162 // bb0:
163 // %0 = CONST_I32 1
164 // DBG_VALUE %0, !"a", ...
165 // ...
166 // INST0 ..., $0 ...
167 // bb1:
168 // INST1 ..., $0 ...
169 // INST2 ..., $0 ...
171 // We process bb0 first. Because %0 is used multiple times, %0 is cloned
172 // before INST0:
173 // bb0:
174 // %0 = CONST_I32 1
175 // DBG_VALUE %0, !"a", ...
176 // ...
177 // %1 = CONST_I32 1
178 // DBG_VALUE %1, !"a", ...
179 // INST0 ..., $1 ...
181 // And when we process bb1, we clone %0 and its DBG_VALUE again:
182 // bb0:
183 // %0 = CONST_I32 1
184 // DBG_VALUE %0, !"a", ...
185 // ...
186 // %1 = CONST_I32 1
187 // DBG_VALUE %1, !"a", ...
188 // INST0 ..., $1 ...
189 // bb1:
190 // %2 = CONST_I32 1
191 // DBG_VALUE %2, !"a", ... // !!!
192 // INST1 ..., $2 ...
193 // %3 = CONST_I32 1
194 // DBG_VALUE %3, !"a", ... // !!!
195 // INST2 ..., $3 ...
197 // But (without this exception) the cloned DBG_VALUEs marked with !!! are
198 // not possible to be cloned, because there is a previously cloned
199 // 'DBG_VALUE %1, !"a"' at the end of bb0 referring to the same
200 // DebugVariable "a". But in this case they are OK to be cloned, because
201 // the interfering DBG_VALUE is pointing to the same 'CONST_I32 1',
202 // because it was cloned from the same instruction.
203 if (!OtherDef || !isSameScalarConst(Def, OtherDef)) {
204 Sinkable = false;
205 break;
208 if (Sinkable)
209 SinkableDbgValues.push_back(DV);
211 return SinkableDbgValues;
214 // Returns true if the insertion point is the same as the current place.
215 // Following DBG_VALUEs for 'Def' are ignored.
216 bool WebAssemblyDebugValueManager::isInsertSamePlace(
217 MachineInstr *Insert) const {
218 if (Def->getParent() != Insert->getParent())
219 return false;
220 for (MachineBasicBlock::iterator MI = std::next(Def->getIterator()),
221 ME = Insert;
222 MI != ME; ++MI) {
223 if (!llvm::is_contained(DbgValues, MI)) {
224 return false;
227 return true;
230 // Returns true if any instruction in MBB has the same debug location as DL.
231 // Also returns true if DL is an empty location.
232 static bool hasSameDebugLoc(const MachineBasicBlock *MBB, DebugLoc DL) {
233 for (const auto &MI : *MBB)
234 if (MI.getDebugLoc() == DL)
235 return true;
236 return false;
239 // Sink 'Def', and also sink its eligible DBG_VALUEs to the place before
240 // 'Insert'. Convert the original DBG_VALUEs into undefs.
242 // For DBG_VALUEs to sink properly, if 'Def' and 'Insert' are within the same
243 // BB, 'Insert' should be below 'Def'; if they are in different BBs, 'Insert'
244 // should be in one of 'Def's BBs successors. Def will be sunk regardless of the
245 // location.
247 // This DebugValueManager's new Def and DbgValues will be updated to the newly
248 // sinked Def + DBG_VALUEs.
249 void WebAssemblyDebugValueManager::sink(MachineInstr *Insert) {
250 // In case Def is requested to be sunk to
251 // the same place, we don't need to do anything. If we actually do the sink,
252 // it will create unnecessary undef DBG_VALUEs. For example, if the original
253 // code is:
254 // %0 = someinst // Def
255 // DBG_VALUE %0, ...
256 // %1 = anotherinst // Insert
258 // If we actually sink %0 and the following DBG_VALUE and setting the original
259 // DBG_VALUE undef, the result will be:
260 // DBG_VALUE %noreg, ... // Unnecessary!
261 // %0 = someinst // Def
262 // DBG_VALUE %0, ...
263 // %1 = anotherinst // Insert
264 if (isInsertSamePlace(Insert))
265 return;
267 MachineBasicBlock *MBB = Insert->getParent();
268 MachineFunction *MF = MBB->getParent();
270 // Get the list of sinkable DBG_VALUEs. This should be done before sinking
271 // Def, because we need to examine instructions between Def and Insert.
272 SmallVector<MachineInstr *, 1> SinkableDbgValues =
273 getSinkableDebugValues(Insert);
275 // Sink Def first.
277 // When moving to a different BB, we preserve the debug loc only if the
278 // destination BB contains the same location. See
279 // https://llvm.org/docs/HowToUpdateDebugInfo.html#when-to-preserve-an-instruction-location.
280 if (Def->getParent() != MBB && !hasSameDebugLoc(MBB, Def->getDebugLoc()))
281 Def->setDebugLoc(DebugLoc());
282 MBB->splice(Insert, Def->getParent(), Def);
284 if (DbgValues.empty())
285 return;
287 // Clone sinkable DBG_VALUEs and insert them.
288 SmallVector<MachineInstr *, 1> NewDbgValues;
289 for (MachineInstr *DV : SinkableDbgValues) {
290 MachineInstr *Clone = MF->CloneMachineInstr(DV);
291 MBB->insert(Insert, Clone);
292 NewDbgValues.push_back(Clone);
295 // When sinking a Def and its DBG_VALUEs, we shouldn't just remove the
296 // original DBG_VALUE instructions; we should set them to undef not to create
297 // an impossible combination of variable assignments in the original program.
298 // For example, this is the original program in order:
299 // %0 = CONST_I32 0
300 // DBG_VALUE %0, !"a", !DIExpression() // a = 0, b = ?
301 // %1 = CONST_I32 1
302 // DBG_VALUE %1, !"b", !DIExpression() // a = 0, b = 1
303 // %2 = CONST_I32 2
304 // DBG_VALUE %2, !"a", !DIExpression() // a = 2, b = 1
305 // %3 = CONST_I32 3
306 // DBG_VALUE %3, !"b", !DIExpression() // a = 2, b = 3
308 // If %2 were to sink below %3, if we just sink DBG_VALUE %1 with it, the
309 // debug info will show the variable "b" is updated to 2, creating the
310 // variable assignment combination of (a = 0, b = 3), which is not possible in
311 // the original program:
312 // %0 = CONST_I32 0
313 // DBG_VALUE %0, !"a", !DIExpression() // a = 0, b = ?
314 // %1 = CONST_I32 1
315 // DBG_VALUE %1, !"b", !DIExpression() // a = 0, b = 1
316 // %3 = CONST_I32 3
317 // DBG_VALUE %3, !"b", !DIExpression() // a = 0, b = 3 (Incorrect!)
318 // %2 = CONST_I32 2
319 // DBG_VALUE %2, !"a", !DIExpression() // a = 2, b = 3
321 // To fix this,we leave an undef DBG_VALUE in its original place, so that the
322 // result will be
323 // %0 = CONST_I32 0
324 // DBG_VALUE %0, !"a", !DIExpression() // a = 0, b = ?
325 // %1 = CONST_I32 1
326 // DBG_VALUE %1, !"b", !DIExpression() // a = 0, b = 1
327 // DBG_VALUE $noreg, !"a", !DIExpression() // a = ?, b = 1
328 // %3 = CONST_I32 3
329 // DBG_VALUE %3, !"b", !DIExpression() // a = ?, b = 3
330 // %2 = CONST_I32 2
331 // DBG_VALUE %2, !"a", !DIExpression() // a = 2, b = 3
332 // Now in the middle "a" will be shown as "optimized out", but it wouldn't
333 // show the impossible combination of (a = 0, b = 3).
334 for (MachineInstr *DV : DbgValues)
335 DV->setDebugValueUndef();
337 DbgValues.swap(NewDbgValues);
340 // Clone 'Def', and also clone its eligible DBG_VALUEs to the place before
341 // 'Insert'.
343 // For DBG_VALUEs to be cloned properly, if 'Def' and 'Insert' are within the
344 // same BB, 'Insert' should be below 'Def'; if they are in different BBs,
345 // 'Insert' should be in one of 'Def's BBs successors. Def will be cloned
346 // regardless of the location.
348 // If NewReg is not $noreg, the newly cloned DBG_VALUEs will have the new
349 // register as its operand.
350 void WebAssemblyDebugValueManager::cloneSink(MachineInstr *Insert,
351 Register NewReg,
352 bool CloneDef) const {
353 MachineBasicBlock *MBB = Insert->getParent();
354 MachineFunction *MF = MBB->getParent();
356 SmallVector<MachineInstr *> SinkableDbgValues =
357 getSinkableDebugValues(Insert);
359 // Clone Def first.
360 if (CloneDef) {
361 MachineInstr *Clone = MF->CloneMachineInstr(Def);
362 // When cloning to a different BB, we preserve the debug loc only if the
363 // destination BB contains the same location. See
364 // https://llvm.org/docs/HowToUpdateDebugInfo.html#when-to-preserve-an-instruction-location.
365 if (Def->getParent() != MBB && !hasSameDebugLoc(MBB, Def->getDebugLoc()))
366 Clone->setDebugLoc(DebugLoc());
367 if (NewReg != CurrentReg && NewReg.isValid())
368 Clone->getOperand(0).setReg(NewReg);
369 MBB->insert(Insert, Clone);
372 if (DbgValues.empty())
373 return;
375 // Clone sinkable DBG_VALUEs and insert them.
376 SmallVector<MachineInstr *, 1> NewDbgValues;
377 for (MachineInstr *DV : SinkableDbgValues) {
378 MachineInstr *Clone = MF->CloneMachineInstr(DV);
379 MBB->insert(Insert, Clone);
380 NewDbgValues.push_back(Clone);
383 if (NewReg != CurrentReg && NewReg.isValid())
384 for (auto *DBI : NewDbgValues)
385 for (auto &MO : DBI->getDebugOperandsForReg(CurrentReg))
386 MO.setReg(NewReg);
389 // Update the register for Def and DBG_VALUEs.
390 void WebAssemblyDebugValueManager::updateReg(Register Reg) {
391 if (Reg != CurrentReg && Reg.isValid()) {
392 for (auto *DBI : DbgValues)
393 for (auto &MO : DBI->getDebugOperandsForReg(CurrentReg))
394 MO.setReg(Reg);
395 CurrentReg = Reg;
396 Def->getOperand(0).setReg(Reg);
400 void WebAssemblyDebugValueManager::replaceWithLocal(unsigned LocalId) {
401 for (auto *DBI : DbgValues) {
402 auto IndexType = DBI->isIndirectDebugValue()
403 ? llvm::WebAssembly::TI_LOCAL_INDIRECT
404 : llvm::WebAssembly::TI_LOCAL;
405 for (auto &MO : DBI->getDebugOperandsForReg(CurrentReg))
406 MO.ChangeToTargetIndex(IndexType, LocalId);
410 // Remove Def, and set its DBG_VALUEs to undef.
411 void WebAssemblyDebugValueManager::removeDef() {
412 Def->removeFromParent();
413 for (MachineInstr *DV : DbgValues)
414 DV->setDebugValueUndef();