2017-06-27 06:44:03 +08:00
|
|
|
//===- llvm/CodeGen/GlobalISel/InstructionSelector.cpp --------------------===//
|
2016-07-27 22:31:55 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// 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
|
2016-07-27 22:31:55 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2017-09-30 05:55:49 +08:00
|
|
|
//
|
2016-07-27 22:31:55 +08:00
|
|
|
/// \file
|
|
|
|
/// This file implements the InstructionSelector class.
|
2017-09-30 05:55:49 +08:00
|
|
|
//
|
2016-07-27 22:31:55 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
|
2016-12-23 05:56:19 +08:00
|
|
|
#include "llvm/CodeGen/GlobalISel/Utils.h"
|
2017-06-27 06:44:03 +08:00
|
|
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
|
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
2016-07-27 22:31:55 +08:00
|
|
|
#include "llvm/CodeGen/MachineInstr.h"
|
2017-06-27 06:44:03 +08:00
|
|
|
#include "llvm/CodeGen/MachineOperand.h"
|
2017-10-16 11:36:29 +08:00
|
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
2017-11-17 09:07:10 +08:00
|
|
|
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
2017-06-27 06:44:03 +08:00
|
|
|
#include "llvm/MC/MCInstrDesc.h"
|
|
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
#include <cassert>
|
2016-07-27 22:31:55 +08:00
|
|
|
|
|
|
|
#define DEBUG_TYPE "instructionselector"
|
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
InstructionSelector::MatcherState::MatcherState(unsigned MaxRenderers)
|
2017-10-16 02:22:54 +08:00
|
|
|
: Renderers(MaxRenderers), MIs() {}
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
|
2017-06-27 06:44:03 +08:00
|
|
|
InstructionSelector::InstructionSelector() = default;
|
2016-07-27 22:31:55 +08:00
|
|
|
|
2017-06-20 20:36:34 +08:00
|
|
|
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();
|
|
|
|
|
2019-04-26 15:21:56 +08:00
|
|
|
return constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, RC,
|
|
|
|
I.getOperand(OpIdx), OpIdx);
|
2017-06-20 20:36:34 +08:00
|
|
|
}
|
|
|
|
|
2017-03-20 00:12:48 +08:00
|
|
|
bool InstructionSelector::isOperandImmEqual(
|
|
|
|
const MachineOperand &MO, int64_t Value,
|
|
|
|
const MachineRegisterInfo &MRI) const {
|
2017-05-18 18:33:36 +08:00
|
|
|
if (MO.isReg() && MO.getReg())
|
2019-03-14 09:37:13 +08:00
|
|
|
if (auto VRegVal = getConstantVRegValWithLookThrough(MO.getReg(), MRI))
|
|
|
|
return VRegVal->Value == Value;
|
2017-03-20 00:12:48 +08:00
|
|
|
return false;
|
|
|
|
}
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
|
2017-10-16 11:36:29 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2017-11-11 11:23:44 +08:00
|
|
|
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;
|
|
|
|
|
2019-06-06 06:33:10 +08:00
|
|
|
return !MI.mayLoadOrStore() && !MI.mayRaiseFPException() &&
|
|
|
|
!MI.hasUnmodeledSideEffects() && empty(MI.implicit_operands());
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
}
|