@@ -260,11 +260,31 @@ static InstructionCost ComputeSpeculationCost(const Instruction *I,
260
260
}
261
261
}
262
262
263
+ // Do not hoist any debug info intrinsics.
264
+ // ...
265
+ // if (cond) {
266
+ // x = y * z;
267
+ // foo();
268
+ // }
269
+ // ...
270
+ // -------- Which then becomes:
271
+ // ...
272
+ // if.then:
273
+ // %x = mul i32 %y, %z
274
+ // call void @llvm.dbg.value(%x, !"x", !DIExpression())
275
+ // call void foo()
276
+ //
277
+ // SpeculativeExecution might decide to hoist the 'y * z' calculation
278
+ // out of the 'if' block, because it is more efficient that way, so the
279
+ // '%x = mul i32 %y, %z' moves to the block above. But it might also
280
+ // decide to hoist the 'llvm.dbg.value' call.
281
+ // This is incorrect, because even if we've moved the calculation of
282
+ // 'y * z', we should not see the value of 'x' change unless we
283
+ // actually go inside the 'if' block.
284
+
263
285
bool SpeculativeExecutionPass::considerHoistingFromTo (
264
286
BasicBlock &FromBlock, BasicBlock &ToBlock) {
265
287
SmallPtrSet<const Instruction *, 8 > NotHoisted;
266
- SmallDenseMap<const Instruction *, SmallVector<DbgVariableRecord *>>
267
- DbgVariableRecordsToHoist;
268
288
auto HasNoUnhoistedInstr = [&NotHoisted](auto Values) {
269
289
for (const Value *V : Values) {
270
290
if (const auto *I = dyn_cast_or_null<Instruction>(V))
@@ -275,15 +295,8 @@ bool SpeculativeExecutionPass::considerHoistingFromTo(
275
295
};
276
296
auto AllPrecedingUsesFromBlockHoisted =
277
297
[&HasNoUnhoistedInstr](const User *U) {
278
- // Debug variable has special operand to check it's not hoisted.
279
- if (const auto *DVI = dyn_cast<DbgVariableIntrinsic>(U))
280
- return HasNoUnhoistedInstr (DVI->location_ops ());
281
-
282
- // Usially debug label intrinsic corresponds to label in LLVM IR. In
283
- // these cases we should not move it here.
284
- // TODO: Possible special processing needed to detect it is related to a
285
- // hoisted instruction.
286
- if (isa<DbgLabelInst>(U))
298
+ // Do not hoist any debug info intrinsics.
299
+ if (isa<DbgInfoIntrinsic>(U))
287
300
return false ;
288
301
289
302
return HasNoUnhoistedInstr (U->operand_values ());
@@ -292,12 +305,6 @@ bool SpeculativeExecutionPass::considerHoistingFromTo(
292
305
InstructionCost TotalSpeculationCost = 0 ;
293
306
unsigned NotHoistedInstCount = 0 ;
294
307
for (const auto &I : FromBlock) {
295
- // Make note of any DbgVariableRecords that need hoisting. DbgLabelRecords
296
- // get left behind just like llvm.dbg.labels.
297
- for (DbgVariableRecord &DVR : filterDbgVars (I.getDbgRecordRange ())) {
298
- if (HasNoUnhoistedInstr (DVR.location_ops ()))
299
- DbgVariableRecordsToHoist[DVR.getInstruction ()].push_back (&DVR);
300
- }
301
308
const InstructionCost Cost = ComputeSpeculationCost (&I, *TTI);
302
309
if (Cost.isValid () && isSafeToSpeculativelyExecute (&I) &&
303
310
AllPrecedingUsesFromBlockHoisted (&I)) {
@@ -315,16 +322,6 @@ bool SpeculativeExecutionPass::considerHoistingFromTo(
315
322
}
316
323
317
324
for (auto I = FromBlock.begin (); I != FromBlock.end ();) {
318
- // If any DbgVariableRecords attached to this instruction should be hoisted,
319
- // hoist them now - they will end up attached to either the next hoisted
320
- // instruction or the ToBlock terminator.
321
- if (DbgVariableRecordsToHoist.contains (&*I)) {
322
- for (auto *DVR : DbgVariableRecordsToHoist[&*I]) {
323
- DVR->removeFromParent ();
324
- ToBlock.insertDbgRecordBefore (DVR,
325
- ToBlock.getTerminator ()->getIterator ());
326
- }
327
- }
328
325
// We have to increment I before moving Current as moving Current
329
326
// changes the list that I is iterating through.
330
327
auto Current = I;
0 commit comments