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 2406c3fb27SDimitry Andric GIMatchTableExecutor::MatcherState::MatcherState(unsigned MaxRenderers) 2506c3fb27SDimitry Andric : Renderers(MaxRenderers) {} 2606c3fb27SDimitry Andric 2706c3fb27SDimitry Andric GIMatchTableExecutor::GIMatchTableExecutor() = default; 2806c3fb27SDimitry Andric 29*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 4506c3fb27SDimitry 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 6206c3fb27SDimitry 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