xref: /llvm-project/llvm/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp (revision 549413fa4034898250c506098c3602e0b07680a2)
11fe7d9c7Spvanhout //===- llvm/CodeGen/GlobalISel/GIMatchTableExecutor.cpp -------------------===//
21fe7d9c7Spvanhout //
31fe7d9c7Spvanhout // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41fe7d9c7Spvanhout // See https://llvm.org/LICENSE.txt for license information.
51fe7d9c7Spvanhout // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61fe7d9c7Spvanhout //
71fe7d9c7Spvanhout //===----------------------------------------------------------------------===//
81fe7d9c7Spvanhout //
91fe7d9c7Spvanhout /// \file
101fe7d9c7Spvanhout /// This file implements the GIMatchTableExecutor class.
111fe7d9c7Spvanhout //
121fe7d9c7Spvanhout //===----------------------------------------------------------------------===//
131fe7d9c7Spvanhout 
141fe7d9c7Spvanhout #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h"
151fe7d9c7Spvanhout #include "llvm/CodeGen/GlobalISel/Utils.h"
161fe7d9c7Spvanhout #include "llvm/CodeGen/MachineInstr.h"
171fe7d9c7Spvanhout #include "llvm/CodeGen/MachineOperand.h"
181fe7d9c7Spvanhout #include "llvm/CodeGen/MachineRegisterInfo.h"
191fe7d9c7Spvanhout 
201fe7d9c7Spvanhout #define DEBUG_TYPE "gi-match-table-executor"
211fe7d9c7Spvanhout 
221fe7d9c7Spvanhout using namespace llvm;
231fe7d9c7Spvanhout 
241fe7d9c7Spvanhout GIMatchTableExecutor::MatcherState::MatcherState(unsigned MaxRenderers)
251fe7d9c7Spvanhout     : Renderers(MaxRenderers) {}
261fe7d9c7Spvanhout 
271fe7d9c7Spvanhout GIMatchTableExecutor::GIMatchTableExecutor() = default;
281fe7d9c7Spvanhout 
2963afb705Spvanhout bool GIMatchTableExecutor::isOperandImmEqual(const MachineOperand &MO,
3063afb705Spvanhout                                              int64_t Value,
3163afb705Spvanhout                                              const MachineRegisterInfo &MRI,
3263afb705Spvanhout                                              bool Splat) const {
3363afb705Spvanhout   if (MO.isReg() && MO.getReg()) {
341fe7d9c7Spvanhout     if (auto VRegVal = getIConstantVRegValWithLookThrough(MO.getReg(), MRI))
351fe7d9c7Spvanhout       return VRegVal->Value.getSExtValue() == Value;
3663afb705Spvanhout 
3763afb705Spvanhout     if (Splat) {
3863afb705Spvanhout       if (auto VRegVal = getIConstantSplatVal(MO.getReg(), MRI))
3963afb705Spvanhout         return VRegVal->getSExtValue() == Value;
4063afb705Spvanhout     }
4163afb705Spvanhout   }
421fe7d9c7Spvanhout   return false;
431fe7d9c7Spvanhout }
441fe7d9c7Spvanhout 
451fe7d9c7Spvanhout bool GIMatchTableExecutor::isBaseWithConstantOffset(
461fe7d9c7Spvanhout     const MachineOperand &Root, const MachineRegisterInfo &MRI) const {
471fe7d9c7Spvanhout   if (!Root.isReg())
481fe7d9c7Spvanhout     return false;
491fe7d9c7Spvanhout 
501fe7d9c7Spvanhout   MachineInstr *RootI = MRI.getVRegDef(Root.getReg());
511fe7d9c7Spvanhout   if (RootI->getOpcode() != TargetOpcode::G_PTR_ADD)
521fe7d9c7Spvanhout     return false;
531fe7d9c7Spvanhout 
541fe7d9c7Spvanhout   MachineOperand &RHS = RootI->getOperand(2);
551fe7d9c7Spvanhout   MachineInstr *RHSI = MRI.getVRegDef(RHS.getReg());
561fe7d9c7Spvanhout   if (RHSI->getOpcode() != TargetOpcode::G_CONSTANT)
571fe7d9c7Spvanhout     return false;
581fe7d9c7Spvanhout 
591fe7d9c7Spvanhout   return true;
601fe7d9c7Spvanhout }
611fe7d9c7Spvanhout 
621fe7d9c7Spvanhout bool GIMatchTableExecutor::isObviouslySafeToFold(MachineInstr &MI,
631fe7d9c7Spvanhout                                                  MachineInstr &IntoMI) const {
64d58bd211Schuongg3   auto IntoMIIter = IntoMI.getIterator();
65d58bd211Schuongg3 
661fe7d9c7Spvanhout   // Immediate neighbours are already folded.
671fe7d9c7Spvanhout   if (MI.getParent() == IntoMI.getParent() &&
68d58bd211Schuongg3       std::next(MI.getIterator()) == IntoMIIter)
691fe7d9c7Spvanhout     return true;
701fe7d9c7Spvanhout 
711fe7d9c7Spvanhout   // Convergent instructions cannot be moved in the CFG.
721fe7d9c7Spvanhout   if (MI.isConvergent() && MI.getParent() != IntoMI.getParent())
731fe7d9c7Spvanhout     return false;
741fe7d9c7Spvanhout 
75d58bd211Schuongg3   if (MI.isLoadFoldBarrier())
76d58bd211Schuongg3     return false;
77d58bd211Schuongg3 
78d58bd211Schuongg3   // If the load is simple, check instructions between MI and IntoMI
79d58bd211Schuongg3   if (MI.mayLoad() && MI.getParent() == IntoMI.getParent()) {
80d58bd211Schuongg3     if (MI.memoperands_empty())
81d58bd211Schuongg3       return false;
82d58bd211Schuongg3     auto &MMO = **(MI.memoperands_begin());
83d58bd211Schuongg3     if (MMO.isAtomic() || MMO.isVolatile())
84d58bd211Schuongg3       return false;
85d58bd211Schuongg3 
86d58bd211Schuongg3     // Ensure instructions between MI and IntoMI are not affected when combined
87d58bd211Schuongg3     unsigned Iter = 0;
88d58bd211Schuongg3     const unsigned MaxIter = 20;
89d58bd211Schuongg3     for (auto &CurrMI :
90d58bd211Schuongg3          instructionsWithoutDebug(MI.getIterator(), IntoMI.getIterator())) {
91d58bd211Schuongg3       if (CurrMI.isLoadFoldBarrier())
92d58bd211Schuongg3         return false;
93d58bd211Schuongg3 
94d58bd211Schuongg3       if (Iter++ == MaxIter)
95d58bd211Schuongg3         return false;
96d58bd211Schuongg3     }
97d58bd211Schuongg3 
98d58bd211Schuongg3     return true;
99d58bd211Schuongg3   }
100d58bd211Schuongg3 
101*549413faSDavid Green   return !MI.mayLoad();
1021fe7d9c7Spvanhout }
103