[llvm] [CanonicalizeFreezeInLoops] fix duplicate removal (PR #74716)

Wei Tao via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 14 10:27:11 PST 2023


https://github.com/Friedrich20 updated https://github.com/llvm/llvm-project/pull/74716

>From 66cca9869a03f8eee8151f2eb88e91e0dc487957 Mon Sep 17 00:00:00 2001
From: Wei Tao <friedrich.taow at gmail.com>
Date: Thu, 7 Dec 2023 21:33:40 +0800
Subject: [PATCH 1/3] [LLVM][CanonicalizeFreezeInLoops] fix duplicate removal

---
 .../Transforms/Utils/CanonicalizeFreezeInLoops.cpp  | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp b/llvm/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp
index fb4d8288537725..ff1eb17e0c2488 100644
--- a/llvm/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp
+++ b/llvm/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp
@@ -151,11 +151,18 @@ bool CanonicalizeFreezeInLoopsImpl::run() {
       }
     }
 
+    bool Exist = false;
     auto Visit = [&](User *U) {
       if (auto *FI = dyn_cast<FreezeInst>(U)) {
-        LLVM_DEBUG(dbgs() << "canonfr: found: " << *FI << "\n");
-        Info.FI = FI;
-        Candidates.push_back(Info);
+        for (const auto &Candidate : Candidates) {
+          auto *FI_cand = Candidate.FI;
+          Exist = (FI_cand == FI) ? true : Exist;
+        }
+        if (!Exist) {
+          LLVM_DEBUG(dbgs() << "canonfr: found: " << *FI << "\n");
+          Info.FI = FI;
+          Candidates.push_back(Info);
+        }
       }
     };
     for_each(PHI.users(), Visit);

>From 48dd0aa3f0ef09dd84c71608e27656a83e50bda0 Mon Sep 17 00:00:00 2001
From: Wei Tao <friedrich.taow at gmail.com>
Date: Fri, 15 Dec 2023 02:23:44 +0800
Subject: [PATCH 2/3] [LLVM][CanonicalizeFreezeInLoops] refactor 'fix duplicate
 removal' by switching SmallSetVector

---
 .../Utils/CanonicalizeFreezeInLoops.cpp       | 68 ++++++++++++-------
 1 file changed, 42 insertions(+), 26 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp b/llvm/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp
index ff1eb17e0c2488..0c7d648ce095ad 100644
--- a/llvm/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp
+++ b/llvm/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp
@@ -29,9 +29,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallVector.h"
 #include "llvm/Analysis/IVDescriptors.h"
 #include "llvm/Analysis/LoopAnalysisManager.h"
 #include "llvm/Analysis/LoopInfo.h"
@@ -66,19 +66,6 @@ class CanonicalizeFreezeInLoopsImpl {
   ScalarEvolution &SE;
   DominatorTree &DT;
 
-  struct FrozenIndPHIInfo {
-    // A freeze instruction that uses an induction phi
-    FreezeInst *FI = nullptr;
-    // The induction phi, step instruction, the operand idx of StepInst which is
-    // a step value
-    PHINode *PHI;
-    BinaryOperator *StepInst;
-    unsigned StepValIdx = 0;
-
-    FrozenIndPHIInfo(PHINode *PHI, BinaryOperator *StepInst)
-        : PHI(PHI), StepInst(StepInst) {}
-  };
-
   // Can freeze instruction be pushed into operands of I?
   // In order to do this, I should not create a poison after I's flags are
   // stripped.
@@ -99,6 +86,42 @@ class CanonicalizeFreezeInLoopsImpl {
 
 } // anonymous namespace
 
+namespace llvm {
+
+struct FrozenIndPHIInfo {
+  // A freeze instruction that uses an induction phi
+  FreezeInst *FI = nullptr;
+  // The induction phi, step instruction, the operand idx of StepInst which is
+  // a step value
+  PHINode *PHI;
+  BinaryOperator *StepInst;
+  unsigned StepValIdx = 0;
+
+  FrozenIndPHIInfo(PHINode *PHI, BinaryOperator *StepInst)
+      : PHI(PHI), StepInst(StepInst) {}
+};
+
+template <> struct DenseMapInfo<FrozenIndPHIInfo> {
+  static inline FrozenIndPHIInfo getEmptyKey() {
+    return FrozenIndPHIInfo(DenseMapInfo<PHINode *>::getEmptyKey(),
+                            DenseMapInfo<BinaryOperator *>::getEmptyKey());
+  }
+
+  static inline FrozenIndPHIInfo getTombstoneKey() {
+    return FrozenIndPHIInfo(DenseMapInfo<PHINode *>::getTombstoneKey(),
+                            DenseMapInfo<BinaryOperator *>::getTombstoneKey());
+  }
+
+  static unsigned getHashValue(const FrozenIndPHIInfo &Val) {
+    return DenseMapInfo<FreezeInst *>::getHashValue(Val.FI);
+  };
+  static bool isEqual(const FrozenIndPHIInfo &LHS, const FrozenIndPHIInfo &RHS) {
+    return LHS.FI == RHS.FI;
+  };
+};
+
+} // end namespace llvm
+
 // Given U = (value, user), replace value with freeze(value), and let
 // SCEV forget user. The inserted freeze is placed in the preheader.
 void CanonicalizeFreezeInLoopsImpl::InsertFreezeAndForgetFromSCEV(Use &U) {
@@ -126,7 +149,7 @@ bool CanonicalizeFreezeInLoopsImpl::run() {
   if (!L->isLoopSimplifyForm())
     return false;
 
-  SmallVector<FrozenIndPHIInfo, 4> Candidates;
+  SmallSetVector<FrozenIndPHIInfo, 4> Candidates;
 
   for (auto &PHI : L->getHeader()->phis()) {
     InductionDescriptor ID;
@@ -151,18 +174,11 @@ bool CanonicalizeFreezeInLoopsImpl::run() {
       }
     }
 
-    bool Exist = false;
     auto Visit = [&](User *U) {
       if (auto *FI = dyn_cast<FreezeInst>(U)) {
-        for (const auto &Candidate : Candidates) {
-          auto *FI_cand = Candidate.FI;
-          Exist = (FI_cand == FI) ? true : Exist;
-        }
-        if (!Exist) {
-          LLVM_DEBUG(dbgs() << "canonfr: found: " << *FI << "\n");
-          Info.FI = FI;
-          Candidates.push_back(Info);
-        }
+        LLVM_DEBUG(dbgs() << "canonfr: found: " << *FI << "\n");
+        Info.FI = FI;
+        Candidates.insert(Info);
       }
     };
     for_each(PHI.users(), Visit);

>From 92fd7e98ec68819269dbf9401f43170e7fa4d7c9 Mon Sep 17 00:00:00 2001
From: Wei Tao <friedrich.taow at gmail.com>
Date: Fri, 15 Dec 2023 02:26:52 +0800
Subject: [PATCH 3/3] [LLVM][CanonicalizeFreezeInLoops] add testcase to check
 duplicate removal

---
 .../duplicate_remove.ll                          | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 llvm/test/Transforms/CanonicalizeFreezeInLoops/duplicate_remove.ll

diff --git a/llvm/test/Transforms/CanonicalizeFreezeInLoops/duplicate_remove.ll b/llvm/test/Transforms/CanonicalizeFreezeInLoops/duplicate_remove.ll
new file mode 100644
index 00000000000000..515dd589297527
--- /dev/null
+++ b/llvm/test/Transforms/CanonicalizeFreezeInLoops/duplicate_remove.ll
@@ -0,0 +1,16 @@
+; RUN: opt < %s -canon-freeze -S | FileCheck %s
+define void @check_duplicate_removal(i32 %n) {
+entry:
+br label %loop
+
+loop:
+%t1 = phi i32 [ 0, %entry], [%t3, %loop ]
+%t2 = phi i32 [ 0, %entry], [%t3, %loop ]
+%t3 = add i32 %n, %t2
+%.fr = freeze i32 %t3
+%cond = icmp eq i32 %t2, 0
+br i1 %cond, label %loop, label %exit
+
+exit:
+ret void
+}
\ No newline at end of file



More information about the llvm-commits mailing list