From b8cf84d40e00d359d3550bc8f87db30f28934c59 Mon Sep 17 00:00:00 2001 From: Vladislav Dzhidzhoev 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 26752369a7711..3441df8a342e4 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); }