[llvm] [GlobalISel] Allow some load/store instructions to be folded in Match Table backend (PR #70830)

Vladislav Dzhidzhoev via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 31 10:00:39 PDT 2023


https://github.com/dzhidzhoev created https://github.com/llvm/llvm-project/pull/70830

Load/store instruction can be folded into non-adjacent instruction
within the same basic block, if there are no other instructions with
memory/other side effects between them.


>From b8cf84d40e00d359d3550bc8f87db30f28934c59 Mon Sep 17 00:00:00 2001
From: Vladislav Dzhidzhoev <vdzhidzhoev at accesssoftek.com>
Date: Tue, 31 Oct 2023 17:51:21 +0100
Subject: [PATCH] [GlobalISel] Allow some load/store instructions to be folded
 in Match Table backend

Load/store instruction can be folded into non-adjacent instruction
within the same basic block, if there are no other instructions with
memory/other side effects between them.
---
 .../GlobalISel/GIMatchTableExecutor.cpp       | 23 +++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp b/llvm/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp
index 26752369a7711a1..3441df8a342e4f1 100644
--- a/llvm/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp
@@ -70,6 +70,25 @@ bool GIMatchTableExecutor::isObviouslySafeToFold(MachineInstr &MI,
   if (MI.isConvergent() && MI.getParent() != IntoMI.getParent())
     return false;
 
-  return !MI.mayLoadOrStore() && !MI.mayRaiseFPException() &&
-         !MI.hasUnmodeledSideEffects() && MI.implicit_operands().empty();
+  auto IsSafe = [](const MachineInstr &MI) {
+    return !MI.mayRaiseFPException() && !MI.hasUnmodeledSideEffects() &&
+           MI.implicit_operands().empty();
+  };
+  auto IsSafeNoMem = [IsSafe](const MachineInstr &MI) {
+    return !MI.mayLoadOrStore() && IsSafe(MI);
+  };
+
+  // If source instruction uses memory, fold if no intermediate
+  // instructions use it.
+  if (MI.mayLoadOrStore() && IsSafe(MI) &&
+      MI.getParent() == IntoMI.getParent()) {
+    auto IntoIt = IntoMI.getIterator();
+    auto NextIt = std::next(MI.getIterator());
+    while (!NextIt.isEnd() && NextIt != IntoIt && IsSafeNoMem(*NextIt))
+      ++NextIt;
+    if (NextIt == IntoIt)
+      return true;
+  }
+
+  return IsSafeNoMem(MI);
 }



More information about the llvm-commits mailing list