1 //===- llvm/CodeGen/GlobalISel/GIMatchTableExecutor.cpp -------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// This file implements the GIMatchTableExecutor class.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h"
15 #include "llvm/CodeGen/GlobalISel/Utils.h"
16 #include "llvm/CodeGen/MachineInstr.h"
17 #include "llvm/CodeGen/MachineOperand.h"
18 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #define DEBUG_TYPE "gi-match-table-executor"
24 GIMatchTableExecutor::MatcherState::MatcherState(unsigned MaxRenderers
)
25 : Renderers(MaxRenderers
) {}
27 GIMatchTableExecutor::GIMatchTableExecutor() = default;
29 bool GIMatchTableExecutor::isOperandImmEqual(const MachineOperand
&MO
,
31 const MachineRegisterInfo
&MRI
,
33 if (MO
.isReg() && MO
.getReg()) {
34 if (auto VRegVal
= getIConstantVRegValWithLookThrough(MO
.getReg(), MRI
))
35 return VRegVal
->Value
.getSExtValue() == Value
;
38 if (auto VRegVal
= getIConstantSplatVal(MO
.getReg(), MRI
))
39 return VRegVal
->getSExtValue() == Value
;
45 bool GIMatchTableExecutor::isBaseWithConstantOffset(
46 const MachineOperand
&Root
, const MachineRegisterInfo
&MRI
) const {
50 MachineInstr
*RootI
= MRI
.getVRegDef(Root
.getReg());
51 if (RootI
->getOpcode() != TargetOpcode::G_PTR_ADD
)
54 MachineOperand
&RHS
= RootI
->getOperand(2);
55 MachineInstr
*RHSI
= MRI
.getVRegDef(RHS
.getReg());
56 if (RHSI
->getOpcode() != TargetOpcode::G_CONSTANT
)
62 bool GIMatchTableExecutor::isObviouslySafeToFold(MachineInstr
&MI
,
63 MachineInstr
&IntoMI
) const {
64 auto IntoMIIter
= IntoMI
.getIterator();
66 // Immediate neighbours are already folded.
67 if (MI
.getParent() == IntoMI
.getParent() &&
68 std::next(MI
.getIterator()) == IntoMIIter
)
71 // Convergent instructions cannot be moved in the CFG.
72 if (MI
.isConvergent() && MI
.getParent() != IntoMI
.getParent())
75 if (MI
.isLoadFoldBarrier())
78 // If the load is simple, check instructions between MI and IntoMI
79 if (MI
.mayLoad() && MI
.getParent() == IntoMI
.getParent()) {
80 if (MI
.memoperands_empty())
82 auto &MMO
= **(MI
.memoperands_begin());
83 if (MMO
.isAtomic() || MMO
.isVolatile())
86 // Ensure instructions between MI and IntoMI are not affected when combined
88 const unsigned MaxIter
= 20;
90 instructionsWithoutDebug(MI
.getIterator(), IntoMI
.getIterator())) {
91 if (CurrMI
.isLoadFoldBarrier())
94 if (Iter
++ == MaxIter
)
101 return !MI
.mayLoad();