[PATCH] D113377: [Sink] Use reverse post order in iterative sinking algorithm

Bin Cheng via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 7 19:03:26 PST 2021


bin.cheng created this revision.
bin.cheng added a reviewer: sunfish.
bin.cheng added a project: LLVM.
Herald added a subscriber: hiraditya.
bin.cheng requested review of this revision.
Herald added a subscriber: llvm-commits.

Hi,
The iterative sinking algorithm sinks load instructions step by step, so
it's better to use RPO that helps fast convergence by visiting BB before
its sink successors.  Also adds a test showing the behavior change.

Thanks,
bin


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D113377

Files:
  llvm/lib/Transforms/Scalar/Sink.cpp
  llvm/test/Transforms/Sink/reverse-post-order.ll


Index: llvm/test/Transforms/Sink/reverse-post-order.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/Sink/reverse-post-order.ll
@@ -0,0 +1,62 @@
+; REQUIRES: asserts
+; RUN: opt < %s -passes='sink' -debug-only=sink -S 2>&1 | FileCheck %s
+
+; CHECK-NOT: Sinking iteration 2
+
+%struct.expression = type { i8*, i32 }
+%struct.node = type { i8, i8, i16 }
+%struct.info = type { i8*, i32 }
+
+ at .str = private unnamed_addr constant [16 x i8] c"Can't handle %d\00", align 1
+
+; Function Attrs: nounwind uwtable
+define dso_local i8* @foo(%struct.expression* nocapture readonly %expr, %struct.node* nocapture readonly %n, i8* readnone %start, i8* readnone %end, %struct.info* nocapture readonly %info) {
+entry:
+  br label %entry.tmp
+
+while.cond.preheader:                             ; preds = %while.cond.preheader.tmp
+  %flag7 = getelementptr inbounds %struct.info, %struct.info* %info, i64 0, i32 1
+  %cmp520 = icmp ult i8* %start, %end
+  br i1 %cmp520, label %while.body, label %cleanup
+
+while.cond.preheader.tmp:
+  %s.tmp = icmp eq i8* %start, null
+  br i1 %s.tmp, label %cleanup, label %while.cond.preheader
+
+entry.tmp:
+  %flag = getelementptr inbounds %struct.expression, %struct.expression* %expr, i64 0, i32 1
+  %0 = load i32, i32* %flag, align 8
+  %and = and i32 %0, 1
+  %1 = xor i32 %and, 1
+  %type = getelementptr inbounds %struct.node, %struct.node* %n, i64 0, i32 1
+  %tmp.2 = load i8, i8* %type, align 1
+  %cmp3 = icmp eq i8 %tmp.2, 18
+  br i1 %cmp3, label %while.cond.preheader.tmp, label %if.else10
+
+while.body:                                       ; preds = %while.cond.preheader, %if.else
+  %flag1.023 = phi i32 [ %1, %if.else ], [ 1, %while.cond.preheader ]
+  %start.addr.021 = phi i8* [ %incdec.ptr, %if.else ], [ %start, %while.cond.preheader ]
+  %tobool.not = icmp eq i32 %flag1.023, 0
+  br i1 %tobool.not, label %if.else, label %land.lhs.true
+
+land.lhs.true:                                    ; preds = %while.body
+  %tmp.3 = load i32, i32* %flag7, align 8
+  %tobool8.not = icmp eq i32 %tmp.3, 0
+  br i1 %tobool8.not, label %if.else, label %cleanup
+
+if.else:                                          ; preds = %land.lhs.true, %while.body
+  %incdec.ptr = getelementptr inbounds i8, i8* %start.addr.021, i64 1
+  %cmp5 = icmp ult i8* %incdec.ptr, %end
+  br i1 %cmp5, label %while.body, label %cleanup
+
+if.else10:                                        ; preds = %entry
+  %conv2 = zext i8 %tmp.2 to i32
+  tail call void @report_error(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str, i64 0, i64 0), i32 %conv2)
+  br label %cleanup
+
+cleanup:                                          ; preds = %land.lhs.true, %if.else, %while.cond.preheader, %if.else10, %while.cond.preheader.tmp
+  %retval.0 = phi i8* [ null, %if.else10 ], [ null, %while.cond.preheader ], [ %start.addr.021, %land.lhs.true ], [ null, %if.else ], [null, %while.cond.preheader.tmp]
+  ret i8* %retval.0
+}
+
+declare dso_local void @report_error(i8*, i32)
Index: llvm/lib/Transforms/Scalar/Sink.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/Sink.cpp
+++ llvm/lib/Transforms/Scalar/Sink.cpp
@@ -13,6 +13,7 @@
 
 #include "llvm/Transforms/Scalar/Sink.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/PostOrderIterator.h"
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/ValueTracking.h"
@@ -223,9 +224,10 @@
   do {
     MadeChange = false;
     LLVM_DEBUG(dbgs() << "Sinking iteration " << NumSinkIter << "\n");
-    // Process all basic blocks.
-    for (BasicBlock &I : F)
-      MadeChange |= ProcessBlock(I, DT, LI, AA);
+    // Process all basic blocks in RPO for fast convergence.
+    ReversePostOrderTraversal<Function *> RPOT(&F);
+    for (BasicBlock *I : RPOT)
+      MadeChange |= ProcessBlock(*I, DT, LI, AA);
     EverMadeChange |= MadeChange;
     NumSinkIter++;
   } while (MadeChange);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D113377.385387.patch
Type: text/x-patch
Size: 4016 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211108/efcdbdcd/attachment.bin>


More information about the llvm-commits mailing list