LLVM: lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

21

22using namespace llvm;

23

25 : Def(Def) {

26 if (!Def->getMF()->getFunction().getSubprogram())

27 return;

28

29

30

31

32 if (!Def->getOperand(0).isReg())

33 return;

34 CurrentReg = Def->getOperand(0).getReg();

35

37 ME = Def->getParent()->end();

38 MI != ME; ++MI) {

39

40 if (MI->definesRegister(CurrentReg, nullptr))

41 break;

42 if (MI->isDebugValue() && MI->hasDebugOperandForReg(CurrentReg))

43 DbgValues.push_back(&*MI);

44 }

45}

46

47

48

50 if (A->getOpcode() != 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

63WebAssemblyDebugValueManager::getSinkableDebugValues(

65 if (DbgValues.empty())

66 return {};

67

68 SmallVector<MachineInstr *, 8> DbgValuesInBetween;

69

70 if (Def->getParent() == Insert->getParent()) {

71

72

73 bool DefFirst = false;

75 ME = Def->getParent()->end();

76 MI != ME; ++MI) {

77 if (&*MI == Insert) {

78 DefFirst = true;

79 break;

80 }

81 if (MI->isDebugValue())

83 }

84 if (!DefFirst)

85 return {};

86

87 } else {

88

89

90 if (!Def->getParent()->isSuccessor(Insert->getParent()))

91 return {};

92

93

94

96 ME = Def->getParent()->end();

97 MI != ME; ++MI) {

98 if (MI->isDebugValue())

100 }

102 ME = Insert->getIterator();

103 MI != ME; ++MI) {

104 if (MI->isDebugValue())

106 }

107 }

108

109

110

111 SmallDenseMap<DebugVariable, SmallVector<MachineInstr *, 2>>

112 SeenDbgVarToDbgValues;

113 for (auto *DV : DbgValuesInBetween) {

115 DebugVariable Var(DV->getDebugVariable(), DV->getDebugExpression(),

116 DV->getDebugLoc()->getInlinedAt());

117 SeenDbgVarToDbgValues[Var].push_back(DV);

118 }

119 }

120

121

122

123

124

125

126

127

128

129

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()) {

138 continue;

139 }

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 }

151 MachineInstr *OtherDef = MRI.getUniqueVRegDef(OtherReg);

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

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

208 Sinkable = false;

209 break;

210 }

211 }

212 if (Sinkable)

214 }

215 return SinkableDbgValues;

216}

217

218

219

220bool WebAssemblyDebugValueManager::isInsertSamePlace(

222 if (Def->getParent() != Insert->getParent())

223 return false;

225 ME = Insert;

226 MI != ME; ++MI) {

228 return false;

229 }

230 }

231 return true;

232}

233

234

235

237 for (const auto &MI : *MBB)

238 if (MI.getDebugLoc() == DL)

239 return true;

240 return false;

241}

242

243

244

245

246

247

248

249

250

251

252

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268 if (isInsertSamePlace(Insert))

269 return;

270

273

274

275

277 getSinkableDebugValues(Insert);

278

279

280

281

282

283

285 Def->setDebugLoc(DebugLoc());

286 MBB->splice(Insert, Def->getParent(), Def);

287

288 if (DbgValues.empty())

289 return;

290

291

294 MachineInstr *Clone = MF->CloneMachineInstr(DV);

295 MBB->insert(Insert, Clone);

297 }

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

339 DV->setDebugValueUndef();

340

341 DbgValues.swap(NewDbgValues);

342}

343

344

345

346

347

348

349

350

351

352

353

356 bool CloneDef) const {

359

361 getSinkableDebugValues(Insert);

362

363

364 if (CloneDef) {

365 MachineInstr *Clone = MF->CloneMachineInstr(Def);

366

367

368

371 if (NewReg != CurrentReg && NewReg.isValid())

373 MBB->insert(Insert, Clone);

374 }

375

376 if (DbgValues.empty())

377 return;

378

379

382 MachineInstr *Clone = MF->CloneMachineInstr(DV);

383 MBB->insert(Insert, 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

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

405 for (auto *DBI : DbgValues) {

406 auto IndexType = DBI->isIndirectDebugValue()

409 for (auto &MO : DBI->getDebugOperandsForReg(CurrentReg))

410 MO.ChangeToTargetIndex(IndexType, LocalId);

411 }

412}

413

414

416 Def->removeFromParent();

418 DV->setDebugValueUndef();

419}

unsigned const MachineRegisterInfo * MRI

for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

Promote Memory to Register

static bool isSameScalarConst(const MachineInstr *A, const MachineInstr *B)

Definition WebAssemblyDebugValueManager.cpp:49

static bool hasSameDebugLoc(const MachineBasicBlock *MBB, DebugLoc DL)

Definition WebAssemblyDebugValueManager.cpp:236

This file contains the declaration of the WebAssembly-specific manager for DebugValues associated wit...

This file provides WebAssembly-specific target descriptions.

This file declares WebAssembly-specific per-machine-function information.

This file contains the entry points for global functions defined in the LLVM WebAssembly back-end.

iterator find(const_arg_type_t< KeyT > Val)

MachineInstrBundleIterator< MachineInstr > iterator

Representation of each machine instruction.

const MachineOperand & getOperand(unsigned i) const

void setDebugLoc(DebugLoc DL)

Replace current source information with new such.

MachineOperand class - Representation of each machine instruction operand.

const GlobalValue * getGlobal() const

bool isReg() const

isReg - Tests if this is a MO_Register operand.

LLVM_ABI void setReg(Register Reg)

Change the register this operand corresponds to.

bool isImm() const

isImm - Tests if this is a MO_Immediate operand.

bool isGlobal() const

isGlobal - Tests if this is a MO_GlobalAddress operand.

Register getReg() const

getReg - Returns the register number.

const ConstantFP * getFPImm() const

bool isFPImm() const

isFPImm - Tests if this is a MO_FPImmediate operand.

Wrapper class representing virtual and physical registers.

constexpr bool isValid() const

void swap(SmallVectorImpl &RHS)

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

WebAssemblyDebugValueManager(MachineInstr *Def)

Definition WebAssemblyDebugValueManager.cpp:24

void updateReg(Register Reg)

Definition WebAssemblyDebugValueManager.cpp:394

void removeDef()

Definition WebAssemblyDebugValueManager.cpp:415

void cloneSink(MachineInstr *Insert, Register NewReg=Register(), bool CloneDef=true) const

Definition WebAssemblyDebugValueManager.cpp:354

void replaceWithLocal(unsigned LocalId)

Definition WebAssemblyDebugValueManager.cpp:404

void sink(MachineInstr *Insert)

Definition WebAssemblyDebugValueManager.cpp:253

bool isScalarConst(unsigned Opc)

This is an optimization pass for GlobalISel generic memory operations.

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.