[PATCH] D139582: [GVN] Improve PRE on load instructions

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 16 08:03:44 PST 2022


nikic added a comment.

In D139582#3999511 <https://reviews.llvm.org/D139582#3999511>, @Carrot wrote:

> The compile time regression on ClamAV is in file libclamav_htmlnorm.c.  The increased compile time is completely in GVN pass, from 4.0s to 5.3s. There is a huge function cli_html_normalise in this file, it's more than 6600 lines in generated assembly file. The statistic result of NumPRELoad increased from 1 to 10 because of this patch. In function GVNPass::runImpl we have
>
>   unsigned Iteration = 0;
>   while (ShouldContinue) {
>     LLVM_DEBUG(dbgs() << "GVN iteration: " << Iteration << "\n");
>     (void) Iteration;
>     ShouldContinue = iterateOnFunction(F);
>     Changed |= ShouldContinue;
>     ++Iteration;
>   }
>
> It means we continuously do GVN on a function until there is no more such optimization applicable. This patch enables more optimizations, potentially it may also cause more iterations on a function. In this case, the loop is executed 4 times without this patch, but 5 times with this patch. These numbers closely correlate to the increased compile time.
>
> So the extra compile time is caused by more iterations on a huge function, and the more iterations is caused by more optimizations enabled by this patch.

Thanks for the analysis. I think this is fine then. I expect https://reviews.llvm.org/D140097 to mitigate this somewhat.



================
Comment at: llvm/lib/Transforms/Scalar/GVN.cpp:925
+/// NewValue.
+static void ReplaceValuesPerBlockEntry(
+    SmallVectorImpl<AvailableValueInBlock> &ValuesPerBlock, BasicBlock *BB,
----------------
nit: `replaceValuesPerBlockEntry`


================
Comment at: llvm/lib/Transforms/Scalar/GVN.cpp:1392
+
+  for (Instruction &Inst : *SuccBB) {
+    if (Inst.isIdenticalTo(Load)) {
----------------
Block scan needs a cutoff.


================
Comment at: llvm/lib/Transforms/Scalar/GVN.cpp:1397
+      // be safely moved to PredBB.
+      if (Dep.isNonLocal())
+        return static_cast<LoadInst *>(&Inst);
----------------
Do we need to be concerned about speculating the load? You do perform a speculation check, but I think it does not cover the speculation of this load.


================
Comment at: llvm/lib/Transforms/Scalar/GVN.cpp:1398
+      if (Dep.isNonLocal())
+        return static_cast<LoadInst *>(&Inst);
+
----------------
`cast<>`


================
Comment at: llvm/lib/Transforms/Scalar/GVN.cpp:2702
     for (auto *I : InstrsToErase) {
-      assert(I->getParent() == BB && "Removing instruction from wrong block?");
       LLVM_DEBUG(dbgs() << "GVN removed: " << *I << '\n');
----------------
I am not sure this assertion is safe to remove. I think a problem with your current code is that it may try to remove a load that is part of the leader table for that block, if that block has been processed before the current one.


================
Comment at: llvm/test/Transforms/GVN/PRE/pre-load.ll:766
+; critical edges. The other successors of those predecessors have same loads.
+; We can move all loads into predecessors.
+
----------------
Please pre-commit the test.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139582/new/

https://reviews.llvm.org/D139582



More information about the llvm-commits mailing list