Skip to content

Commit f61c29b

Browse files
author
Evgeniy Brevnov
committed
[NARY-REASSOCIATE] Simplify traversal logic by post deleting dead instructions
Currently we delete optimized instructions as we go. That has several negative consequences. First it complicates traversal logic itself. Second if newly generated instruction has been deleted the traversal is repeated from scratch. But real motivation for the change is upcoming change with support for min/max reassociation. Here we employ SCEV expander to generate code. As a result newly generated instructions may be inserted not right before original instruction (because SCEV may do hoisting) and there is no way to know 'next' instruction. Reviewed By: mkazantsev Differential Revision: https://reviews.llvm.org/D88285
1 parent 973f390 commit f61c29b

File tree

2 files changed

+43
-42
lines changed

2 files changed

+43
-42
lines changed

llvm/lib/Transforms/Scalar/NaryReassociate.cpp

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -231,36 +231,32 @@ bool NaryReassociatePass::doOneIteration(Function &F) {
231231
// Process the basic blocks in a depth first traversal of the dominator
232232
// tree. This order ensures that all bases of a candidate are in Candidates
233233
// when we process it.
234+
SmallVector<WeakTrackingVH, 16> DeadInsts;
234235
for (const auto Node : depth_first(DT)) {
235236
BasicBlock *BB = Node->getBlock();
236237
for (auto I = BB->begin(); I != BB->end(); ++I) {
237-
if (SE->isSCEVable(I->getType()) && isPotentiallyNaryReassociable(&*I)) {
238-
const SCEV *OldSCEV = SE->getSCEV(&*I);
239-
if (Instruction *NewI = tryReassociate(&*I)) {
240-
Changed = true;
241-
SE->forgetValue(&*I);
242-
I->replaceAllUsesWith(NewI);
243-
WeakVH NewIExist = NewI;
244-
// If SeenExprs/NewIExist contains I's WeakTrackingVH/WeakVH, that
245-
// entry will be replaced with nullptr if deleted.
246-
RecursivelyDeleteTriviallyDeadInstructions(&*I, TLI);
247-
if (!NewIExist) {
248-
// Rare occation where the new instruction (NewI) have been removed,
249-
// probably due to parts of the input code was dead from the
250-
// beginning, reset the iterator and start over from the beginning
251-
I = BB->begin();
252-
continue;
253-
}
254-
I = NewI->getIterator();
255-
}
256-
// Add the rewritten instruction to SeenExprs; the original instruction
257-
// is deleted.
258-
const SCEV *NewSCEV = SE->getSCEV(&*I);
259-
SeenExprs[NewSCEV].push_back(WeakTrackingVH(&*I));
238+
Instruction *OrigI = &*I;
239+
240+
if (!SE->isSCEVable(OrigI->getType()) ||
241+
!isPotentiallyNaryReassociable(OrigI))
242+
continue;
243+
244+
const SCEV *OrigSCEV = SE->getSCEV(OrigI);
245+
if (Instruction *NewI = tryReassociate(OrigI)) {
246+
Changed = true;
247+
OrigI->replaceAllUsesWith(NewI);
248+
249+
// Add 'OrigI' to the list of dead instructions.
250+
DeadInsts.push_back(WeakTrackingVH(OrigI));
251+
// Add the rewritten instruction to SeenExprs; the original
252+
// instruction is deleted.
253+
const SCEV *NewSCEV = SE->getSCEV(NewI);
254+
SeenExprs[NewSCEV].push_back(WeakTrackingVH(NewI));
255+
260256
// Ideally, NewSCEV should equal OldSCEV because tryReassociate(I)
261257
// is equivalent to I. However, ScalarEvolution::getSCEV may
262-
// weaken nsw causing NewSCEV not to equal OldSCEV. For example, suppose
263-
// we reassociate
258+
// weaken nsw causing NewSCEV not to equal OldSCEV. For example,
259+
// suppose we reassociate
264260
// I = &a[sext(i +nsw j)] // assuming sizeof(a[0]) = 4
265261
// to
266262
// NewI = &a[sext(i)] + sext(j).
@@ -274,12 +270,19 @@ bool NaryReassociatePass::doOneIteration(Function &F) {
274270
// equivalence, we add I to SeenExprs[OldSCEV] as well so that we can
275271
// map both SCEV before and after tryReassociate(I) to I.
276272
//
277-
// This improvement is exercised in @reassociate_gep_nsw in nary-gep.ll.
278-
if (NewSCEV != OldSCEV)
279-
SeenExprs[OldSCEV].push_back(WeakTrackingVH(&*I));
280-
}
273+
// This improvement is exercised in @reassociate_gep_nsw in
274+
// nary-gep.ll.
275+
if (NewSCEV != OrigSCEV)
276+
SeenExprs[OrigSCEV].push_back(WeakTrackingVH(NewI));
277+
} else
278+
SeenExprs[OrigSCEV].push_back(WeakTrackingVH(OrigI));
281279
}
282280
}
281+
// Delete all dead instructions from 'DeadInsts'.
282+
// Please note ScalarEvolution is updated along the way.
283+
RecursivelyDeleteTriviallyDeadInstructionsPermissive(
284+
DeadInsts, TLI, nullptr, [this](Value *V) { SE->forgetValue(V); });
285+
283286
return Changed;
284287
}
285288

llvm/test/Transforms/NaryReassociate/pr24301.ll

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
define i32 @foo(i32 %t4) {
66
; CHECK-LABEL: @foo(
77
; CHECK-NEXT: entry:
8-
; CHECK-NEXT: [[T5:%.*]] = add i32 [[T4:%.*]], 8
9-
; CHECK-NEXT: [[T14:%.*]] = add i32 [[T5]], -128
10-
; CHECK-NEXT: [[T21:%.*]] = add i32 119, [[T4]]
11-
; CHECK-NEXT: [[T23:%.*]] = add i32 [[T21]], -128
8+
; CHECK-NEXT: [[T13:%.*]] = add i32 [[T4:%.*]], -128
9+
; CHECK-NEXT: [[T14:%.*]] = add i32 [[T13]], 8
10+
; CHECK-NEXT: [[T23:%.*]] = add i32 [[T13]], 119
1211
; CHECK-NEXT: ret i32 [[T23]]
1312
;
1413
entry:
@@ -25,19 +24,18 @@ entry:
2524
define i32 @foo2(i32 %t4) {
2625
; CHECK-LABEL: @foo2(
2726
; CHECK-NEXT: entry:
28-
; CHECK-NEXT: [[T5:%.*]] = add i32 [[T4:%.*]], 8
29-
; CHECK-NEXT: [[T14:%.*]] = add i32 [[T5]], -128
30-
; CHECK-NEXT: [[T21:%.*]] = add i32 119, [[T4]]
31-
; CHECK-NEXT: [[T23:%.*]] = add i32 [[T21]], -128
27+
; CHECK-NEXT: [[T13:%.*]] = add i32 [[T4:%.*]], -128
28+
; CHECK-NEXT: [[T14:%.*]] = add i32 [[T13]], 8
29+
; CHECK-NEXT: [[T23:%.*]] = add i32 [[T13]], 119
3230
; CHECK-NEXT: [[RES:%.*]] = add i32 [[T14]], [[T23]]
3331
; CHECK-NEXT: ret i32 [[RES]]
3432
;
3533
entry:
36-
%t5 = add i32 %t4, 8
37-
%t13 = add i32 %t4, -128 ; deleted
38-
%t14 = add i32 %t13, 8 ; => %t5 + -128
39-
%t21 = add i32 119, %t4
40-
%t23 = add i32 %t21, -128
34+
%t5 = add i32 %t4, 8 ; initially dead
35+
%t13 = add i32 %t4, -128
36+
%t14 = add i32 %t13, 8
37+
%t21 = add i32 119, %t4 ; => dead after reassociation
38+
%t23 = add i32 %t21, -128; => reassociated to t13 + 119
4139
%res = add i32 %t14, %t23
4240
ret i32 %res
4341
}

0 commit comments

Comments
 (0)