xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/GIMatchTableExecutor.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
106c3fb27SDimitry Andric //===- llvm/CodeGen/GlobalISel/GIMatchTableExecutor.cpp -------------------===//
206c3fb27SDimitry Andric //
306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606c3fb27SDimitry Andric //
706c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
806c3fb27SDimitry Andric //
906c3fb27SDimitry Andric /// \file
1006c3fb27SDimitry Andric /// This file implements the GIMatchTableExecutor class.
1106c3fb27SDimitry Andric //
1206c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
1306c3fb27SDimitry Andric 
1406c3fb27SDimitry Andric #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h"
1506c3fb27SDimitry Andric #include "llvm/CodeGen/GlobalISel/Utils.h"
1606c3fb27SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
1706c3fb27SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
1806c3fb27SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
1906c3fb27SDimitry Andric 
2006c3fb27SDimitry Andric #define DEBUG_TYPE "gi-match-table-executor"
2106c3fb27SDimitry Andric 
2206c3fb27SDimitry Andric using namespace llvm;
2306c3fb27SDimitry Andric 
MatcherState(unsigned MaxRenderers)2406c3fb27SDimitry Andric GIMatchTableExecutor::MatcherState::MatcherState(unsigned MaxRenderers)
2506c3fb27SDimitry Andric     : Renderers(MaxRenderers) {}
2606c3fb27SDimitry Andric 
2706c3fb27SDimitry Andric GIMatchTableExecutor::GIMatchTableExecutor() = default;
2806c3fb27SDimitry Andric 
isOperandImmEqual(const MachineOperand & MO,int64_t Value,const MachineRegisterInfo & MRI,bool Splat) const29*5f757f3fSDimitry Andric bool GIMatchTableExecutor::isOperandImmEqual(const MachineOperand &MO,
30*5f757f3fSDimitry Andric                                              int64_t Value,
31*5f757f3fSDimitry Andric                                              const MachineRegisterInfo &MRI,
32*5f757f3fSDimitry Andric                                              bool Splat) const {
33*5f757f3fSDimitry Andric   if (MO.isReg() && MO.getReg()) {
3406c3fb27SDimitry Andric     if (auto VRegVal = getIConstantVRegValWithLookThrough(MO.getReg(), MRI))
3506c3fb27SDimitry Andric       return VRegVal->Value.getSExtValue() == Value;
36*5f757f3fSDimitry Andric 
37*5f757f3fSDimitry Andric     if (Splat) {
38*5f757f3fSDimitry Andric       if (auto VRegVal = getIConstantSplatVal(MO.getReg(), MRI))
39*5f757f3fSDimitry Andric         return VRegVal->getSExtValue() == Value;
40*5f757f3fSDimitry Andric     }
41*5f757f3fSDimitry Andric   }
4206c3fb27SDimitry Andric   return false;
4306c3fb27SDimitry Andric }
4406c3fb27SDimitry Andric 
isBaseWithConstantOffset(const MachineOperand & Root,const MachineRegisterInfo & MRI) const4506c3fb27SDimitry Andric bool GIMatchTableExecutor::isBaseWithConstantOffset(
4606c3fb27SDimitry Andric     const MachineOperand &Root, const MachineRegisterInfo &MRI) const {
4706c3fb27SDimitry Andric   if (!Root.isReg())
4806c3fb27SDimitry Andric     return false;
4906c3fb27SDimitry Andric 
5006c3fb27SDimitry Andric   MachineInstr *RootI = MRI.getVRegDef(Root.getReg());
5106c3fb27SDimitry Andric   if (RootI->getOpcode() != TargetOpcode::G_PTR_ADD)
5206c3fb27SDimitry Andric     return false;
5306c3fb27SDimitry Andric 
5406c3fb27SDimitry Andric   MachineOperand &RHS = RootI->getOperand(2);
5506c3fb27SDimitry Andric   MachineInstr *RHSI = MRI.getVRegDef(RHS.getReg());
5606c3fb27SDimitry Andric   if (RHSI->getOpcode() != TargetOpcode::G_CONSTANT)
5706c3fb27SDimitry Andric     return false;
5806c3fb27SDimitry Andric 
5906c3fb27SDimitry Andric   return true;
6006c3fb27SDimitry Andric }
6106c3fb27SDimitry Andric 
isObviouslySafeToFold(MachineInstr & MI,MachineInstr & IntoMI) const6206c3fb27SDimitry Andric bool GIMatchTableExecutor::isObviouslySafeToFold(MachineInstr &MI,
6306c3fb27SDimitry Andric                                                  MachineInstr &IntoMI) const {
6406c3fb27SDimitry Andric   // Immediate neighbours are already folded.
6506c3fb27SDimitry Andric   if (MI.getParent() == IntoMI.getParent() &&
6606c3fb27SDimitry Andric       std::next(MI.getIterator()) == IntoMI.getIterator())
6706c3fb27SDimitry Andric     return true;
6806c3fb27SDimitry Andric 
6906c3fb27SDimitry Andric   // Convergent instructions cannot be moved in the CFG.
7006c3fb27SDimitry Andric   if (MI.isConvergent() && MI.getParent() != IntoMI.getParent())
7106c3fb27SDimitry Andric     return false;
7206c3fb27SDimitry Andric 
7306c3fb27SDimitry Andric   return !MI.mayLoadOrStore() && !MI.mayRaiseFPException() &&
7406c3fb27SDimitry Andric          !MI.hasUnmodeledSideEffects() && MI.implicit_operands().empty();
7506c3fb27SDimitry Andric }
76