1fe013be4SDimitry Andric //===- llvm/CodeGen/GlobalISel/GIMatchTableExecutor.cpp -------------------===//
2fe013be4SDimitry Andric //
3fe013be4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe013be4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe013be4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe013be4SDimitry Andric //
7fe013be4SDimitry Andric //===----------------------------------------------------------------------===//
8fe013be4SDimitry Andric //
9fe013be4SDimitry Andric /// \file
10fe013be4SDimitry Andric /// This file implements the GIMatchTableExecutor class.
11fe013be4SDimitry Andric //
12fe013be4SDimitry Andric //===----------------------------------------------------------------------===//
13fe013be4SDimitry Andric
14fe013be4SDimitry Andric #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h"
15fe013be4SDimitry Andric #include "llvm/CodeGen/GlobalISel/Utils.h"
16fe013be4SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
17fe013be4SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
18fe013be4SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
19fe013be4SDimitry Andric
20fe013be4SDimitry Andric #define DEBUG_TYPE "gi-match-table-executor"
21fe013be4SDimitry Andric
22fe013be4SDimitry Andric using namespace llvm;
23fe013be4SDimitry Andric
MatcherState(unsigned MaxRenderers)24fe013be4SDimitry Andric GIMatchTableExecutor::MatcherState::MatcherState(unsigned MaxRenderers)
25fe013be4SDimitry Andric : Renderers(MaxRenderers) {}
26fe013be4SDimitry Andric
27fe013be4SDimitry Andric GIMatchTableExecutor::GIMatchTableExecutor() = default;
28fe013be4SDimitry Andric
isOperandImmEqual(const MachineOperand & MO,int64_t Value,const MachineRegisterInfo & MRI,bool Splat) const29*c9157d92SDimitry Andric bool GIMatchTableExecutor::isOperandImmEqual(const MachineOperand &MO,
30*c9157d92SDimitry Andric int64_t Value,
31*c9157d92SDimitry Andric const MachineRegisterInfo &MRI,
32*c9157d92SDimitry Andric bool Splat) const {
33*c9157d92SDimitry Andric if (MO.isReg() && MO.getReg()) {
34fe013be4SDimitry Andric if (auto VRegVal = getIConstantVRegValWithLookThrough(MO.getReg(), MRI))
35fe013be4SDimitry Andric return VRegVal->Value.getSExtValue() == Value;
36*c9157d92SDimitry Andric
37*c9157d92SDimitry Andric if (Splat) {
38*c9157d92SDimitry Andric if (auto VRegVal = getIConstantSplatVal(MO.getReg(), MRI))
39*c9157d92SDimitry Andric return VRegVal->getSExtValue() == Value;
40*c9157d92SDimitry Andric }
41*c9157d92SDimitry Andric }
42fe013be4SDimitry Andric return false;
43fe013be4SDimitry Andric }
44fe013be4SDimitry Andric
isBaseWithConstantOffset(const MachineOperand & Root,const MachineRegisterInfo & MRI) const45fe013be4SDimitry Andric bool GIMatchTableExecutor::isBaseWithConstantOffset(
46fe013be4SDimitry Andric const MachineOperand &Root, const MachineRegisterInfo &MRI) const {
47fe013be4SDimitry Andric if (!Root.isReg())
48fe013be4SDimitry Andric return false;
49fe013be4SDimitry Andric
50fe013be4SDimitry Andric MachineInstr *RootI = MRI.getVRegDef(Root.getReg());
51fe013be4SDimitry Andric if (RootI->getOpcode() != TargetOpcode::G_PTR_ADD)
52fe013be4SDimitry Andric return false;
53fe013be4SDimitry Andric
54fe013be4SDimitry Andric MachineOperand &RHS = RootI->getOperand(2);
55fe013be4SDimitry Andric MachineInstr *RHSI = MRI.getVRegDef(RHS.getReg());
56fe013be4SDimitry Andric if (RHSI->getOpcode() != TargetOpcode::G_CONSTANT)
57fe013be4SDimitry Andric return false;
58fe013be4SDimitry Andric
59fe013be4SDimitry Andric return true;
60fe013be4SDimitry Andric }
61fe013be4SDimitry Andric
isObviouslySafeToFold(MachineInstr & MI,MachineInstr & IntoMI) const62fe013be4SDimitry Andric bool GIMatchTableExecutor::isObviouslySafeToFold(MachineInstr &MI,
63fe013be4SDimitry Andric MachineInstr &IntoMI) const {
64fe013be4SDimitry Andric // Immediate neighbours are already folded.
65fe013be4SDimitry Andric if (MI.getParent() == IntoMI.getParent() &&
66fe013be4SDimitry Andric std::next(MI.getIterator()) == IntoMI.getIterator())
67fe013be4SDimitry Andric return true;
68fe013be4SDimitry Andric
69fe013be4SDimitry Andric // Convergent instructions cannot be moved in the CFG.
70fe013be4SDimitry Andric if (MI.isConvergent() && MI.getParent() != IntoMI.getParent())
71fe013be4SDimitry Andric return false;
72fe013be4SDimitry Andric
73fe013be4SDimitry Andric return !MI.mayLoadOrStore() && !MI.mayRaiseFPException() &&
74fe013be4SDimitry Andric !MI.hasUnmodeledSideEffects() && MI.implicit_operands().empty();
75fe013be4SDimitry Andric }
76