mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
0fd4b778e9
When constraining an operand register using constrainOperandRegClass(), the function may emit a COPY in case the provided register class does not match the current operand register class. However, the operand itself is not updated to make use of the COPY, thereby resulting in incorrect code. This patch fixes that bug by updating the machine operand accordingly. Reviewed By: dsanders Differential Revision: https://reviews.llvm.org/D91244
72 lines
2.4 KiB
C++
72 lines
2.4 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::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.getSExtValue() == 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_PTR_ADD)
|
|
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.mayRaiseFPException() &&
|
|
!MI.hasUnmodeledSideEffects() && MI.implicit_operands().empty();
|
|
}
|