brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.2 KiB · 1edfc09 Raw
103 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9/// \file10/// 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 22using namespace llvm;23 24GIMatchTableExecutor::MatcherState::MatcherState(unsigned MaxRenderers)25    : Renderers(MaxRenderers) {}26 27GIMatchTableExecutor::GIMatchTableExecutor() = default;28 29bool GIMatchTableExecutor::isOperandImmEqual(const MachineOperand &MO,30                                             int64_t Value,31                                             const MachineRegisterInfo &MRI,32                                             bool Splat) const {33  if (MO.isReg() && MO.getReg()) {34    if (auto VRegVal = getIConstantVRegValWithLookThrough(MO.getReg(), MRI))35      return VRegVal->Value.getSExtValue() == Value;36 37    if (Splat) {38      if (auto VRegVal = getIConstantSplatVal(MO.getReg(), MRI))39        return VRegVal->getSExtValue() == Value;40    }41  }42  return false;43}44 45bool GIMatchTableExecutor::isBaseWithConstantOffset(46    const MachineOperand &Root, const MachineRegisterInfo &MRI) const {47  if (!Root.isReg())48    return false;49 50  MachineInstr *RootI = MRI.getVRegDef(Root.getReg());51  if (RootI->getOpcode() != TargetOpcode::G_PTR_ADD)52    return false;53 54  MachineOperand &RHS = RootI->getOperand(2);55  MachineInstr *RHSI = MRI.getVRegDef(RHS.getReg());56  if (RHSI->getOpcode() != TargetOpcode::G_CONSTANT)57    return false;58 59  return true;60}61 62bool GIMatchTableExecutor::isObviouslySafeToFold(MachineInstr &MI,63                                                 MachineInstr &IntoMI) const {64  auto IntoMIIter = IntoMI.getIterator();65 66  // Immediate neighbours are already folded.67  if (MI.getParent() == IntoMI.getParent() &&68      std::next(MI.getIterator()) == IntoMIIter)69    return true;70 71  // Convergent instructions cannot be moved in the CFG.72  if (MI.isConvergent() && MI.getParent() != IntoMI.getParent())73    return false;74 75  if (MI.isLoadFoldBarrier())76    return false;77 78  // If the load is simple, check instructions between MI and IntoMI79  if (MI.mayLoad() && MI.getParent() == IntoMI.getParent()) {80    if (MI.memoperands_empty())81      return false;82    auto &MMO = **(MI.memoperands_begin());83    if (MMO.isAtomic() || MMO.isVolatile())84      return false;85 86    // Ensure instructions between MI and IntoMI are not affected when combined87    unsigned Iter = 0;88    const unsigned MaxIter = 20;89    for (auto &CurrMI :90         instructionsWithoutDebug(MI.getIterator(), IntoMI.getIterator())) {91      if (CurrMI.isLoadFoldBarrier())92        return false;93 94      if (Iter++ == MaxIter)95        return false;96    }97 98    return true;99  }100 101  return !MI.mayLoad();102}103