1 //===-- WebAssemblyDebugValueManager.cpp - WebAssembly DebugValue Manager -===//
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
7 //===----------------------------------------------------------------------===//
10 /// This file implements the manager for MachineInstr DebugValues.
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"
23 WebAssemblyDebugValueManager::WebAssemblyDebugValueManager(MachineInstr
*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())
30 CurrentReg
= Def
->getOperand(0).getReg();
32 for (MachineBasicBlock::iterator MI
= std::next(Def
->getIterator()),
33 ME
= Def
->getParent()->end();
35 // If another definition appears, stop
36 if (MI
->definesRegister(CurrentReg
))
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()))
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()))
58 SmallVector
<MachineInstr
*, 1>
59 WebAssemblyDebugValueManager::getSinkableDebugValues(
60 MachineInstr
*Insert
) const {
61 if (DbgValues
.empty())
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();
77 if (MI
->isDebugValue())
78 DbgValuesInBetween
.push_back(&*MI
);
80 if (!DefFirst
) // Not a sink
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()))
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();
94 if (MI
->isDebugValue())
95 DbgValuesInBetween
.push_back(&*MI
);
97 for (MachineBasicBlock::iterator MI
= Insert
->getParent()->begin(),
98 ME
= Insert
->getIterator();
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,
121 // DBG_VALUE %0, !"a", !DIExpression() // Should not sink with %0
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
);
136 if (!WebAssembly::isScalarConst(Def
->getOpcode()))
138 auto &OverlappingDbgValues
= It
->second
;
139 bool Sinkable
= true;
140 for (auto *OverlappingDV
: OverlappingDbgValues
) {
141 MachineOperand
&DbgOp
= OverlappingDV
->getDebugOperand(0);
142 if (!DbgOp
.isReg()) {
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,
152 // DBG_VALUE %0, !"a", !DIExpression() // Can sink with %0
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
164 // DBG_VALUE %0, !"a", ...
171 // We process bb0 first. Because %0 is used multiple times, %0 is cloned
175 // DBG_VALUE %0, !"a", ...
178 // DBG_VALUE %1, !"a", ...
181 // And when we process bb1, we clone %0 and its DBG_VALUE again:
184 // DBG_VALUE %0, !"a", ...
187 // DBG_VALUE %1, !"a", ...
191 // DBG_VALUE %2, !"a", ... // !!!
194 // DBG_VALUE %3, !"a", ... // !!!
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
)) {
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())
220 for (MachineBasicBlock::iterator MI
= std::next(Def
->getIterator()),
223 if (!llvm::is_contained(DbgValues
, MI
)) {
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
)
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
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
254 // %0 = someinst // Def
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
263 // %1 = anotherinst // Insert
264 if (isInsertSamePlace(Insert
))
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
);
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())
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:
300 // DBG_VALUE %0, !"a", !DIExpression() // a = 0, b = ?
302 // DBG_VALUE %1, !"b", !DIExpression() // a = 0, b = 1
304 // DBG_VALUE %2, !"a", !DIExpression() // a = 2, b = 1
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:
313 // DBG_VALUE %0, !"a", !DIExpression() // a = 0, b = ?
315 // DBG_VALUE %1, !"b", !DIExpression() // a = 0, b = 1
317 // DBG_VALUE %3, !"b", !DIExpression() // a = 0, b = 3 (Incorrect!)
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
324 // DBG_VALUE %0, !"a", !DIExpression() // a = 0, b = ?
326 // DBG_VALUE %1, !"b", !DIExpression() // a = 0, b = 1
327 // DBG_VALUE $noreg, !"a", !DIExpression() // a = ?, b = 1
329 // DBG_VALUE %3, !"b", !DIExpression() // a = ?, b = 3
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
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
,
352 bool CloneDef
) const {
353 MachineBasicBlock
*MBB
= Insert
->getParent();
354 MachineFunction
*MF
= MBB
->getParent();
356 SmallVector
<MachineInstr
*> SinkableDbgValues
=
357 getSinkableDebugValues(Insert
);
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())
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
))
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
))
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();