
getConstantVRegVal used to only look for G_CONSTANT when looking at unboxing the value of a vreg. However, constants are sometimes not directly used and are hidden behind trunc, s|zext or copy chain of computation. In particular this may be introduced by the legalization process that doesn't want to simplify these patterns because it can lead to infine loop when legalizing a constant. To circumvent that problem, add a new variant of getConstantVRegVal, named getConstantVRegValWithLookThrough, that allow to look through extensions. Differential Revision: https://reviews.llvm.org/D59227 llvm-svn: 356116
84 lines
2.8 KiB
C++
84 lines
2.8 KiB
C++
//===- llvm/CodeGen/GlobalISel/InstructionSelector.cpp --------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
/// \file
|
|
/// This file implements the InstructionSelector class.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
|
|
#include "llvm/CodeGen/GlobalISel/Utils.h"
|
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
#include "llvm/CodeGen/MachineInstr.h"
|
|
#include "llvm/CodeGen/MachineOperand.h"
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
|
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
|
#include "llvm/MC/MCInstrDesc.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include <cassert>
|
|
|
|
#define DEBUG_TYPE "instructionselector"
|
|
|
|
using namespace llvm;
|
|
|
|
InstructionSelector::MatcherState::MatcherState(unsigned MaxRenderers)
|
|
: Renderers(MaxRenderers), MIs() {}
|
|
|
|
InstructionSelector::InstructionSelector() = default;
|
|
|
|
bool InstructionSelector::constrainOperandRegToRegClass(
|
|
MachineInstr &I, unsigned OpIdx, const TargetRegisterClass &RC,
|
|
const TargetInstrInfo &TII, const TargetRegisterInfo &TRI,
|
|
const RegisterBankInfo &RBI) const {
|
|
MachineBasicBlock &MBB = *I.getParent();
|
|
MachineFunction &MF = *MBB.getParent();
|
|
MachineRegisterInfo &MRI = MF.getRegInfo();
|
|
|
|
return
|
|
constrainRegToClass(MRI, TII, RBI, I, I.getOperand(OpIdx).getReg(), RC);
|
|
}
|
|
|
|
bool InstructionSelector::isOperandImmEqual(
|
|
const MachineOperand &MO, int64_t Value,
|
|
const MachineRegisterInfo &MRI) const {
|
|
if (MO.isReg() && MO.getReg())
|
|
if (auto VRegVal = getConstantVRegValWithLookThrough(MO.getReg(), MRI))
|
|
return VRegVal->Value == Value;
|
|
return false;
|
|
}
|
|
|
|
bool InstructionSelector::isBaseWithConstantOffset(
|
|
const MachineOperand &Root, const MachineRegisterInfo &MRI) const {
|
|
if (!Root.isReg())
|
|
return false;
|
|
|
|
MachineInstr *RootI = MRI.getVRegDef(Root.getReg());
|
|
if (RootI->getOpcode() != TargetOpcode::G_GEP)
|
|
return false;
|
|
|
|
MachineOperand &RHS = RootI->getOperand(2);
|
|
MachineInstr *RHSI = MRI.getVRegDef(RHS.getReg());
|
|
if (RHSI->getOpcode() != TargetOpcode::G_CONSTANT)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool InstructionSelector::isObviouslySafeToFold(MachineInstr &MI,
|
|
MachineInstr &IntoMI) const {
|
|
// Immediate neighbours are already folded.
|
|
if (MI.getParent() == IntoMI.getParent() &&
|
|
std::next(MI.getIterator()) == IntoMI.getIterator())
|
|
return true;
|
|
|
|
return !MI.mayLoadOrStore() && !MI.hasUnmodeledSideEffects() &&
|
|
empty(MI.implicit_operands());
|
|
}
|