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