1 //===- llvm/CodeGen/GlobalISel/GIMatchTableExecutor.cpp -------------------===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 /// \file 10 /// This file implements the GIMatchTableExecutor class. 11 // 12 //===----------------------------------------------------------------------===// 13 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" 19 20 #define DEBUG_TYPE "gi-match-table-executor" 21 22 using namespace llvm; 23 24 GIMatchTableExecutor::MatcherState::MatcherState(unsigned MaxRenderers) 25 : Renderers(MaxRenderers) {} 26 27 GIMatchTableExecutor::GIMatchTableExecutor() = default; 28 29 bool GIMatchTableExecutor::isOperandImmEqual( 30 const MachineOperand &MO, int64_t Value, 31 const MachineRegisterInfo &MRI) const { 32 if (MO.isReg() && MO.getReg()) 33 if (auto VRegVal = getIConstantVRegValWithLookThrough(MO.getReg(), MRI)) 34 return VRegVal->Value.getSExtValue() == Value; 35 return false; 36 } 37 38 bool GIMatchTableExecutor::isBaseWithConstantOffset( 39 const MachineOperand &Root, const MachineRegisterInfo &MRI) const { 40 if (!Root.isReg()) 41 return false; 42 43 MachineInstr *RootI = MRI.getVRegDef(Root.getReg()); 44 if (RootI->getOpcode() != TargetOpcode::G_PTR_ADD) 45 return false; 46 47 MachineOperand &RHS = RootI->getOperand(2); 48 MachineInstr *RHSI = MRI.getVRegDef(RHS.getReg()); 49 if (RHSI->getOpcode() != TargetOpcode::G_CONSTANT) 50 return false; 51 52 return true; 53 } 54 55 bool GIMatchTableExecutor::isObviouslySafeToFold(MachineInstr &MI, 56 MachineInstr &IntoMI) const { 57 // Immediate neighbours are already folded. 58 if (MI.getParent() == IntoMI.getParent() && 59 std::next(MI.getIterator()) == IntoMI.getIterator()) 60 return true; 61 62 // Convergent instructions cannot be moved in the CFG. 63 if (MI.isConvergent() && MI.getParent() != IntoMI.getParent()) 64 return false; 65 66 return !MI.mayLoadOrStore() && !MI.mayRaiseFPException() && 67 !MI.hasUnmodeledSideEffects() && MI.implicit_operands().empty(); 68 } 69