[llvm] [CodeGenPrepare] Pack boolean phi nodes into a bit string (PR #100972)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 28 23:13:24 PDT 2024


https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/100972

Affected files:
```
delta-rs/optimized/264wku5om6u5pdmz.ll
diesel-rs/optimized/3u2yeit18bjlrsid.ll
diesel-rs/optimized/3zo4rpq1l30wnri7.ll
flac/optimized/main.c.ll
glslang/optimized/GlslangToSpv.cpp.ll
meilisearch-rs/optimized/3f4k2xees4fvt0r.ll
ockam-rs/optimized/445trp5tofqtvmh3.ll
ockam-rs/optimized/4h15go5rbmdr09f8.ll
openblas/optimized/dlascl.c.ll
openblas/optimized/dlatms.c.ll
openblas/optimized/dlatmt.c.ll
rust-analyzer-rs/optimized/1cf75p1eybr0uy0c.ll
rust-analyzer-rs/optimized/k57ct4r8b4mvzu9.ll
typst-rs/optimized/3dimj4rf5dyrieyi.ll
wasmtime-rs/optimized/3r0osxvwe4cd326n.ll
wasmtime-rs/optimized/3xuz4wft4mnh9t46.ll
wireshark/optimized/packet-uts.c.ll
```

>From 51b8ef1e42155ec6aeccbe899011a055047d7b21 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 29 Jul 2024 14:12:28 +0800
Subject: [PATCH] [CodeGenPrepare] Pack boolean phi nodes into a bit string

---
 llvm/lib/CodeGen/CodeGenPrepare.cpp | 61 +++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 22d0708f54786..9ab401419f6c9 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -274,6 +274,10 @@ static cl::opt<bool>
     DisableDeletePHIs("disable-cgp-delete-phis", cl::Hidden, cl::init(false),
                       cl::desc("Disable elimination of dead PHI nodes."));
 
+static cl::opt<unsigned>
+    MinBooleanPhisToPack("min-boolean-phis-to-pack", cl::Hidden, cl::init(8),
+                         cl::desc("Min number of boolean PHI nodes to pack."));
+
 namespace {
 
 enum ExtType {
@@ -473,6 +477,7 @@ class CodeGenPrepare {
   bool optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT);
   bool combineToUSubWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
   bool combineToUAddWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
+  bool packBooleanPhiNodes(Function &F);
   void verifyBFIUpdates(Function &F);
   bool _run(Function &F);
 };
@@ -635,6 +640,8 @@ bool CodeGenPrepare::_run(Function &F) {
   EverMadeChange |=
       SplitIndirectBrCriticalEdges(F, /*IgnoreBlocksWithoutPHI=*/true);
 
+  EverMadeChange |= packBooleanPhiNodes(F);
+
   // If we are optimzing huge function, we need to consider the build time.
   // Because the basic algorithm's complex is near O(N!).
   IsHugeFunc = F.size() > HugeFuncThresholdInCGPP;
@@ -8920,3 +8927,57 @@ bool CodeGenPrepare::splitBranchCondition(Function &F, ModifyDT &ModifiedDT) {
   }
   return MadeChange;
 }
+
+bool CodeGenPrepare::packBooleanPhiNodes(Function &F) {
+  bool Changed = false;
+  for (auto &BB : F) {
+    SmallVector<PHINode *, 8> PhiNodes;
+    for (auto &PN : BB.phis()) {
+      if (!PN.getType()->isIntegerTy(1))
+        continue;
+      bool AllConst = true;
+      for (Value *V : PN.incoming_values())
+        if (!isa<ConstantInt>(V)) {
+          AllConst = false;
+          break;
+        }
+      if (AllConst)
+        PhiNodes.push_back(&PN);
+    }
+    uint32_t BitWidth = PhiNodes.size();
+    if (BitWidth < MinBooleanPhisToPack)
+      continue;
+
+    if (BitWidth > 64 || !DL->fitsInLegalInteger(BitWidth))
+      continue;
+    IRBuilder<> Builder(&BB, BB.begin());
+    PHINode *FirstPN = PhiNodes.front();
+    IntegerType *StateTy = IntegerType::get(F.getContext(), BitWidth);
+    PHINode *PackedPN =
+        Builder.CreatePHI(StateTy, FirstPN->getNumIncomingValues());
+
+    for (auto *PredBB : FirstPN->blocks()) {
+      uint64_t State = 0;
+      uint32_t Idx = 0;
+      for (PHINode *PN : PhiNodes) {
+        ConstantInt *CI =
+            cast<ConstantInt>(PN->getIncomingValueForBlock(PredBB));
+        State |= CI->getZExtValue() << Idx;
+        ++Idx;
+      }
+      PackedPN->addIncoming(ConstantInt::get(StateTy, State), PredBB);
+    }
+    Builder.SetInsertPoint(&BB, BB.getFirstInsertionPt());
+    uint32_t Idx = 0;
+    for (PHINode *PN : PhiNodes) {
+      Value *BitTest = Builder.CreateIsNotNull(
+          Builder.CreateAnd(PackedPN, ConstantInt::get(StateTy, 1ULL << Idx)));
+      PN->replaceAllUsesWith(BitTest);
+      PN->eraseFromParent();
+      ++Idx;
+    }
+    Changed = true;
+  }
+
+  return Changed;
+}



More information about the llvm-commits mailing list