[globalisel][combiner] Make the CombinerChangeObserver a MachineFunction::Delegate
Summary:
This allows us to register it with the MachineFunction delegate and be
notified automatically about erasure and creation of instructions. However,
we still need explicit notification for modifications such as those caused
by setReg() or replaceRegWith().
There is a catch with this though. The notification for creation is
delivered before any operands can be added. While appropriate for
scheduling combiner work. This is unfortunate for debug output since an
opcode by itself doesn't provide sufficient information on what happened.
As a result, the work list remembers the instructions (when debug output is
requested) and emits a more complete dump later.
Another nit is that the MachineFunction::Delegate provides const pointers
which is inconvenient since we want to use it to schedule future
modification. To resolve this GISelWorkList now has an optional pointer to
the MachineFunction which describes the scope of the work it is permitted
to schedule. If a given MachineInstr* is in this function then it is
permitted to schedule work to be performed on the MachineInstr's. An
alternative to this would be to remove the const from the
MachineFunction::Delegate interface, however delegates are not permitted
to modify the MachineInstr's they receive.
In addition to this, the observer has three interface changes.
* erasedInstr() is now erasingInstr() to indicate it is about to be erased
but still exists at the moment.
* changingInstr() and changedInstr() have been added to report changes
before and after they are made. This allows us to trace the changes
in the debug output.
* As a convenience changingAllUsesOfReg() and
finishedChangingAllUsesOfReg() will report changingInstr() and
changedInstr() for each use of a given register. This is primarily useful
for changes caused by MachineRegisterInfo::replaceRegWith()
With this in place, both combine rules have been updated to report their
changes to the observer.
Finally, make some cosmetic changes to the debug output and make Combiner
and CombinerHelp
Reviewers: aditya_nandakumar, bogner, volkan, rtereshin, javed.absar
Reviewed By: aditya_nandakumar
Subscribers: mgorny, rovka, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D52947
llvm-svn: 349167
2018-12-15 01:50:14 +08:00
|
|
|
//===-- lib/CodeGen/GlobalISel/GICombinerHelper.cpp -----------------------===//
|
2018-01-25 08:41:58 +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
|
2018-01-25 08:41:58 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
|
2018-12-06 04:14:52 +08:00
|
|
|
#include "llvm/CodeGen/GlobalISel/Combiner.h"
|
|
|
|
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
|
2018-01-25 08:41:58 +08:00
|
|
|
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
|
|
|
|
#include "llvm/CodeGen/GlobalISel/Utils.h"
|
|
|
|
#include "llvm/CodeGen/MachineInstr.h"
|
|
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
#include "llvm/CodeGen/TargetInstrInfo.h"
|
2018-01-25 08:41:58 +08:00
|
|
|
|
[globalisel][combiner] Make the CombinerChangeObserver a MachineFunction::Delegate
Summary:
This allows us to register it with the MachineFunction delegate and be
notified automatically about erasure and creation of instructions. However,
we still need explicit notification for modifications such as those caused
by setReg() or replaceRegWith().
There is a catch with this though. The notification for creation is
delivered before any operands can be added. While appropriate for
scheduling combiner work. This is unfortunate for debug output since an
opcode by itself doesn't provide sufficient information on what happened.
As a result, the work list remembers the instructions (when debug output is
requested) and emits a more complete dump later.
Another nit is that the MachineFunction::Delegate provides const pointers
which is inconvenient since we want to use it to schedule future
modification. To resolve this GISelWorkList now has an optional pointer to
the MachineFunction which describes the scope of the work it is permitted
to schedule. If a given MachineInstr* is in this function then it is
permitted to schedule work to be performed on the MachineInstr's. An
alternative to this would be to remove the const from the
MachineFunction::Delegate interface, however delegates are not permitted
to modify the MachineInstr's they receive.
In addition to this, the observer has three interface changes.
* erasedInstr() is now erasingInstr() to indicate it is about to be erased
but still exists at the moment.
* changingInstr() and changedInstr() have been added to report changes
before and after they are made. This allows us to trace the changes
in the debug output.
* As a convenience changingAllUsesOfReg() and
finishedChangingAllUsesOfReg() will report changingInstr() and
changedInstr() for each use of a given register. This is primarily useful
for changes caused by MachineRegisterInfo::replaceRegWith()
With this in place, both combine rules have been updated to report their
changes to the observer.
Finally, make some cosmetic changes to the debug output and make Combiner
and CombinerHelp
Reviewers: aditya_nandakumar, bogner, volkan, rtereshin, javed.absar
Reviewed By: aditya_nandakumar
Subscribers: mgorny, rovka, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D52947
llvm-svn: 349167
2018-12-15 01:50:14 +08:00
|
|
|
#define DEBUG_TYPE "gi-combiner"
|
2018-01-25 08:41:58 +08:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
2018-12-06 04:14:52 +08:00
|
|
|
CombinerHelper::CombinerHelper(GISelChangeObserver &Observer,
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
MachineIRBuilder &B)
|
|
|
|
: Builder(B), MRI(Builder.getMF().getRegInfo()), Observer(Observer) {}
|
|
|
|
|
[globalisel][combiner] Make the CombinerChangeObserver a MachineFunction::Delegate
Summary:
This allows us to register it with the MachineFunction delegate and be
notified automatically about erasure and creation of instructions. However,
we still need explicit notification for modifications such as those caused
by setReg() or replaceRegWith().
There is a catch with this though. The notification for creation is
delivered before any operands can be added. While appropriate for
scheduling combiner work. This is unfortunate for debug output since an
opcode by itself doesn't provide sufficient information on what happened.
As a result, the work list remembers the instructions (when debug output is
requested) and emits a more complete dump later.
Another nit is that the MachineFunction::Delegate provides const pointers
which is inconvenient since we want to use it to schedule future
modification. To resolve this GISelWorkList now has an optional pointer to
the MachineFunction which describes the scope of the work it is permitted
to schedule. If a given MachineInstr* is in this function then it is
permitted to schedule work to be performed on the MachineInstr's. An
alternative to this would be to remove the const from the
MachineFunction::Delegate interface, however delegates are not permitted
to modify the MachineInstr's they receive.
In addition to this, the observer has three interface changes.
* erasedInstr() is now erasingInstr() to indicate it is about to be erased
but still exists at the moment.
* changingInstr() and changedInstr() have been added to report changes
before and after they are made. This allows us to trace the changes
in the debug output.
* As a convenience changingAllUsesOfReg() and
finishedChangingAllUsesOfReg() will report changingInstr() and
changedInstr() for each use of a given register. This is primarily useful
for changes caused by MachineRegisterInfo::replaceRegWith()
With this in place, both combine rules have been updated to report their
changes to the observer.
Finally, make some cosmetic changes to the debug output and make Combiner
and CombinerHelp
Reviewers: aditya_nandakumar, bogner, volkan, rtereshin, javed.absar
Reviewed By: aditya_nandakumar
Subscribers: mgorny, rovka, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D52947
llvm-svn: 349167
2018-12-15 01:50:14 +08:00
|
|
|
void CombinerHelper::replaceRegWith(MachineRegisterInfo &MRI, unsigned FromReg,
|
|
|
|
unsigned ToReg) const {
|
|
|
|
Observer.changingAllUsesOfReg(MRI, FromReg);
|
|
|
|
|
|
|
|
if (MRI.constrainRegAttrs(ToReg, FromReg))
|
|
|
|
MRI.replaceRegWith(FromReg, ToReg);
|
|
|
|
else
|
|
|
|
Builder.buildCopy(ToReg, FromReg);
|
|
|
|
|
|
|
|
Observer.finishedChangingAllUsesOfReg();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CombinerHelper::replaceRegOpWith(MachineRegisterInfo &MRI,
|
|
|
|
MachineOperand &FromRegOp,
|
|
|
|
unsigned ToReg) const {
|
|
|
|
assert(FromRegOp.getParent() && "Expected an operand in an MI");
|
|
|
|
Observer.changingInstr(*FromRegOp.getParent());
|
|
|
|
|
|
|
|
FromRegOp.setReg(ToReg);
|
|
|
|
|
|
|
|
Observer.changedInstr(*FromRegOp.getParent());
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
}
|
2018-01-25 08:41:58 +08:00
|
|
|
|
|
|
|
bool CombinerHelper::tryCombineCopy(MachineInstr &MI) {
|
2019-02-14 08:15:28 +08:00
|
|
|
if (matchCombineCopy(MI)) {
|
|
|
|
applyCombineCopy(MI);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
bool CombinerHelper::matchCombineCopy(MachineInstr &MI) {
|
2018-01-25 08:41:58 +08:00
|
|
|
if (MI.getOpcode() != TargetOpcode::COPY)
|
|
|
|
return false;
|
|
|
|
unsigned DstReg = MI.getOperand(0).getReg();
|
|
|
|
unsigned SrcReg = MI.getOperand(1).getReg();
|
|
|
|
LLT DstTy = MRI.getType(DstReg);
|
|
|
|
LLT SrcTy = MRI.getType(SrcReg);
|
|
|
|
// Simple Copy Propagation.
|
|
|
|
// a(sx) = COPY b(sx) -> Replace all uses of a with b.
|
2019-02-14 08:15:28 +08:00
|
|
|
if (DstTy.isValid() && SrcTy.isValid() && DstTy == SrcTy)
|
2018-01-25 08:41:58 +08:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
2019-02-14 08:15:28 +08:00
|
|
|
void CombinerHelper::applyCombineCopy(MachineInstr &MI) {
|
|
|
|
unsigned DstReg = MI.getOperand(0).getReg();
|
|
|
|
unsigned SrcReg = MI.getOperand(1).getReg();
|
|
|
|
MI.eraseFromParent();
|
|
|
|
replaceRegWith(MRI, DstReg, SrcReg);
|
|
|
|
}
|
2018-01-25 08:41:58 +08:00
|
|
|
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
/// Select a preference between two uses. CurrentUse is the current preference
|
|
|
|
/// while *ForCandidate is attributes of the candidate under consideration.
|
|
|
|
PreferredTuple ChoosePreferredUse(PreferredTuple &CurrentUse,
|
|
|
|
const LLT &TyForCandidate,
|
|
|
|
unsigned OpcodeForCandidate,
|
|
|
|
MachineInstr *MIForCandidate) {
|
|
|
|
if (!CurrentUse.Ty.isValid()) {
|
2018-10-05 05:44:32 +08:00
|
|
|
if (CurrentUse.ExtendOpcode == OpcodeForCandidate ||
|
|
|
|
CurrentUse.ExtendOpcode == TargetOpcode::G_ANYEXT)
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
return {TyForCandidate, OpcodeForCandidate, MIForCandidate};
|
|
|
|
return CurrentUse;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We permit the extend to hoist through basic blocks but this is only
|
|
|
|
// sensible if the target has extending loads. If you end up lowering back
|
|
|
|
// into a load and extend during the legalizer then the end result is
|
|
|
|
// hoisting the extend up to the load.
|
|
|
|
|
|
|
|
// Prefer defined extensions to undefined extensions as these are more
|
|
|
|
// likely to reduce the number of instructions.
|
|
|
|
if (OpcodeForCandidate == TargetOpcode::G_ANYEXT &&
|
|
|
|
CurrentUse.ExtendOpcode != TargetOpcode::G_ANYEXT)
|
|
|
|
return CurrentUse;
|
|
|
|
else if (CurrentUse.ExtendOpcode == TargetOpcode::G_ANYEXT &&
|
|
|
|
OpcodeForCandidate != TargetOpcode::G_ANYEXT)
|
|
|
|
return {TyForCandidate, OpcodeForCandidate, MIForCandidate};
|
|
|
|
|
|
|
|
// Prefer sign extensions to zero extensions as sign-extensions tend to be
|
|
|
|
// more expensive.
|
|
|
|
if (CurrentUse.Ty == TyForCandidate) {
|
|
|
|
if (CurrentUse.ExtendOpcode == TargetOpcode::G_SEXT &&
|
|
|
|
OpcodeForCandidate == TargetOpcode::G_ZEXT)
|
|
|
|
return CurrentUse;
|
|
|
|
else if (CurrentUse.ExtendOpcode == TargetOpcode::G_ZEXT &&
|
|
|
|
OpcodeForCandidate == TargetOpcode::G_SEXT)
|
|
|
|
return {TyForCandidate, OpcodeForCandidate, MIForCandidate};
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is potentially target specific. We've chosen the largest type
|
|
|
|
// because G_TRUNC is usually free. One potential catch with this is that
|
|
|
|
// some targets have a reduced number of larger registers than smaller
|
|
|
|
// registers and this choice potentially increases the live-range for the
|
|
|
|
// larger value.
|
|
|
|
if (TyForCandidate.getSizeInBits() > CurrentUse.Ty.getSizeInBits()) {
|
|
|
|
return {TyForCandidate, OpcodeForCandidate, MIForCandidate};
|
|
|
|
}
|
|
|
|
return CurrentUse;
|
2018-10-03 18:59:19 +08:00
|
|
|
}
|
2018-10-05 02:44:58 +08:00
|
|
|
|
|
|
|
/// Find a suitable place to insert some instructions and insert them. This
|
|
|
|
/// function accounts for special cases like inserting before a PHI node.
|
|
|
|
/// The current strategy for inserting before PHI's is to duplicate the
|
|
|
|
/// instructions for each predecessor. However, while that's ok for G_TRUNC
|
|
|
|
/// on most targets since it generally requires no code, other targets/cases may
|
|
|
|
/// want to try harder to find a dominating block.
|
|
|
|
static void InsertInsnsWithoutSideEffectsBeforeUse(
|
|
|
|
MachineIRBuilder &Builder, MachineInstr &DefMI, MachineOperand &UseMO,
|
2019-06-18 04:56:31 +08:00
|
|
|
std::function<void(MachineBasicBlock *, MachineBasicBlock::iterator,
|
|
|
|
MachineOperand &UseMO)>
|
2018-10-05 07:47:37 +08:00
|
|
|
Inserter) {
|
2018-10-05 02:44:58 +08:00
|
|
|
MachineInstr &UseMI = *UseMO.getParent();
|
|
|
|
|
|
|
|
MachineBasicBlock *InsertBB = UseMI.getParent();
|
|
|
|
|
|
|
|
// If the use is a PHI then we want the predecessor block instead.
|
|
|
|
if (UseMI.isPHI()) {
|
|
|
|
MachineOperand *PredBB = std::next(&UseMO);
|
|
|
|
InsertBB = PredBB->getMBB();
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the block is the same block as the def then we want to insert just after
|
|
|
|
// the def instead of at the start of the block.
|
|
|
|
if (InsertBB == DefMI.getParent()) {
|
|
|
|
MachineBasicBlock::iterator InsertPt = &DefMI;
|
2019-06-18 04:56:31 +08:00
|
|
|
Inserter(InsertBB, std::next(InsertPt), UseMO);
|
2018-10-05 02:44:58 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise we want the start of the BB
|
2019-06-18 04:56:31 +08:00
|
|
|
Inserter(InsertBB, InsertBB->getFirstNonPHI(), UseMO);
|
2018-10-05 02:44:58 +08:00
|
|
|
}
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
|
|
bool CombinerHelper::tryCombineExtendingLoads(MachineInstr &MI) {
|
2019-02-14 08:15:28 +08:00
|
|
|
PreferredTuple Preferred;
|
|
|
|
if (matchCombineExtendingLoads(MI, Preferred)) {
|
|
|
|
applyCombineExtendingLoads(MI, Preferred);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2018-10-05 07:47:37 +08:00
|
|
|
|
2019-02-14 08:15:28 +08:00
|
|
|
bool CombinerHelper::matchCombineExtendingLoads(MachineInstr &MI,
|
|
|
|
PreferredTuple &Preferred) {
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
// We match the loads and follow the uses to the extend instead of matching
|
|
|
|
// the extends and following the def to the load. This is because the load
|
|
|
|
// must remain in the same position for correctness (unless we also add code
|
|
|
|
// to find a safe place to sink it) whereas the extend is freely movable.
|
|
|
|
// It also prevents us from duplicating the load for the volatile case or just
|
|
|
|
// for performance.
|
|
|
|
|
|
|
|
if (MI.getOpcode() != TargetOpcode::G_LOAD &&
|
|
|
|
MI.getOpcode() != TargetOpcode::G_SEXTLOAD &&
|
|
|
|
MI.getOpcode() != TargetOpcode::G_ZEXTLOAD)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
auto &LoadValue = MI.getOperand(0);
|
|
|
|
assert(LoadValue.isReg() && "Result wasn't a register?");
|
|
|
|
|
|
|
|
LLT LoadValueTy = MRI.getType(LoadValue.getReg());
|
|
|
|
if (!LoadValueTy.isScalar())
|
|
|
|
return false;
|
|
|
|
|
2019-01-27 18:56:20 +08:00
|
|
|
// Most architectures are going to legalize <s8 loads into at least a 1 byte
|
|
|
|
// load, and the MMOs can only describe memory accesses in multiples of bytes.
|
|
|
|
// If we try to perform extload combining on those, we can end up with
|
|
|
|
// %a(s8) = extload %ptr (load 1 byte from %ptr)
|
|
|
|
// ... which is an illegal extload instruction.
|
|
|
|
if (LoadValueTy.getSizeInBits() < 8)
|
|
|
|
return false;
|
|
|
|
|
2019-04-16 06:34:08 +08:00
|
|
|
// For non power-of-2 types, they will very likely be legalized into multiple
|
|
|
|
// loads. Don't bother trying to match them into extending loads.
|
|
|
|
if (!isPowerOf2_32(LoadValueTy.getSizeInBits()))
|
|
|
|
return false;
|
|
|
|
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
// Find the preferred type aside from the any-extends (unless it's the only
|
|
|
|
// one) and non-extending ops. We'll emit an extending load to that type and
|
|
|
|
// and emit a variant of (extend (trunc X)) for the others according to the
|
|
|
|
// relative type sizes. At the same time, pick an extend to use based on the
|
|
|
|
// extend involved in the chosen type.
|
|
|
|
unsigned PreferredOpcode = MI.getOpcode() == TargetOpcode::G_LOAD
|
|
|
|
? TargetOpcode::G_ANYEXT
|
|
|
|
: MI.getOpcode() == TargetOpcode::G_SEXTLOAD
|
|
|
|
? TargetOpcode::G_SEXT
|
|
|
|
: TargetOpcode::G_ZEXT;
|
2019-02-14 08:15:28 +08:00
|
|
|
Preferred = {LLT(), PreferredOpcode, nullptr};
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
for (auto &UseMI : MRI.use_instructions(LoadValue.getReg())) {
|
|
|
|
if (UseMI.getOpcode() == TargetOpcode::G_SEXT ||
|
2018-10-05 05:44:32 +08:00
|
|
|
UseMI.getOpcode() == TargetOpcode::G_ZEXT ||
|
|
|
|
UseMI.getOpcode() == TargetOpcode::G_ANYEXT) {
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
Preferred = ChoosePreferredUse(Preferred,
|
|
|
|
MRI.getType(UseMI.getOperand(0).getReg()),
|
|
|
|
UseMI.getOpcode(), &UseMI);
|
2018-10-05 05:44:32 +08:00
|
|
|
}
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// There were no extends
|
|
|
|
if (!Preferred.MI)
|
|
|
|
return false;
|
|
|
|
// It should be impossible to chose an extend without selecting a different
|
|
|
|
// type since by definition the result of an extend is larger.
|
|
|
|
assert(Preferred.Ty != LoadValueTy && "Extending to same type?");
|
|
|
|
|
[globalisel][combiner] Make the CombinerChangeObserver a MachineFunction::Delegate
Summary:
This allows us to register it with the MachineFunction delegate and be
notified automatically about erasure and creation of instructions. However,
we still need explicit notification for modifications such as those caused
by setReg() or replaceRegWith().
There is a catch with this though. The notification for creation is
delivered before any operands can be added. While appropriate for
scheduling combiner work. This is unfortunate for debug output since an
opcode by itself doesn't provide sufficient information on what happened.
As a result, the work list remembers the instructions (when debug output is
requested) and emits a more complete dump later.
Another nit is that the MachineFunction::Delegate provides const pointers
which is inconvenient since we want to use it to schedule future
modification. To resolve this GISelWorkList now has an optional pointer to
the MachineFunction which describes the scope of the work it is permitted
to schedule. If a given MachineInstr* is in this function then it is
permitted to schedule work to be performed on the MachineInstr's. An
alternative to this would be to remove the const from the
MachineFunction::Delegate interface, however delegates are not permitted
to modify the MachineInstr's they receive.
In addition to this, the observer has three interface changes.
* erasedInstr() is now erasingInstr() to indicate it is about to be erased
but still exists at the moment.
* changingInstr() and changedInstr() have been added to report changes
before and after they are made. This allows us to trace the changes
in the debug output.
* As a convenience changingAllUsesOfReg() and
finishedChangingAllUsesOfReg() will report changingInstr() and
changedInstr() for each use of a given register. This is primarily useful
for changes caused by MachineRegisterInfo::replaceRegWith()
With this in place, both combine rules have been updated to report their
changes to the observer.
Finally, make some cosmetic changes to the debug output and make Combiner
and CombinerHelp
Reviewers: aditya_nandakumar, bogner, volkan, rtereshin, javed.absar
Reviewed By: aditya_nandakumar
Subscribers: mgorny, rovka, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D52947
llvm-svn: 349167
2018-12-15 01:50:14 +08:00
|
|
|
LLVM_DEBUG(dbgs() << "Preferred use is: " << *Preferred.MI);
|
2019-02-14 08:15:28 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CombinerHelper::applyCombineExtendingLoads(MachineInstr &MI,
|
|
|
|
PreferredTuple &Preferred) {
|
2019-06-18 04:56:31 +08:00
|
|
|
// Rewrite the load to the chosen extending load.
|
|
|
|
unsigned ChosenDstReg = Preferred.MI->getOperand(0).getReg();
|
|
|
|
|
|
|
|
// Inserter to insert a truncate back to the original type at a given point
|
|
|
|
// with some basic CSE to limit truncate duplication to one per BB.
|
|
|
|
DenseMap<MachineBasicBlock *, MachineInstr *> EmittedInsns;
|
|
|
|
auto InsertTruncAt = [&](MachineBasicBlock *InsertIntoBB,
|
|
|
|
MachineBasicBlock::iterator InsertBefore,
|
|
|
|
MachineOperand &UseMO) {
|
|
|
|
MachineInstr *PreviouslyEmitted = EmittedInsns.lookup(InsertIntoBB);
|
|
|
|
if (PreviouslyEmitted) {
|
|
|
|
Observer.changingInstr(*UseMO.getParent());
|
|
|
|
UseMO.setReg(PreviouslyEmitted->getOperand(0).getReg());
|
|
|
|
Observer.changedInstr(*UseMO.getParent());
|
|
|
|
return;
|
2019-02-14 08:15:28 +08:00
|
|
|
}
|
2019-06-18 04:56:31 +08:00
|
|
|
|
|
|
|
Builder.setInsertPt(*InsertIntoBB, InsertBefore);
|
|
|
|
unsigned NewDstReg = MRI.cloneVirtualRegister(MI.getOperand(0).getReg());
|
|
|
|
MachineInstr *NewMI = Builder.buildTrunc(NewDstReg, ChosenDstReg);
|
|
|
|
EmittedInsns[InsertIntoBB] = NewMI;
|
|
|
|
replaceRegOpWith(MRI, UseMO, NewDstReg);
|
2019-02-14 08:15:28 +08:00
|
|
|
};
|
[globalisel][combiner] Make the CombinerChangeObserver a MachineFunction::Delegate
Summary:
This allows us to register it with the MachineFunction delegate and be
notified automatically about erasure and creation of instructions. However,
we still need explicit notification for modifications such as those caused
by setReg() or replaceRegWith().
There is a catch with this though. The notification for creation is
delivered before any operands can be added. While appropriate for
scheduling combiner work. This is unfortunate for debug output since an
opcode by itself doesn't provide sufficient information on what happened.
As a result, the work list remembers the instructions (when debug output is
requested) and emits a more complete dump later.
Another nit is that the MachineFunction::Delegate provides const pointers
which is inconvenient since we want to use it to schedule future
modification. To resolve this GISelWorkList now has an optional pointer to
the MachineFunction which describes the scope of the work it is permitted
to schedule. If a given MachineInstr* is in this function then it is
permitted to schedule work to be performed on the MachineInstr's. An
alternative to this would be to remove the const from the
MachineFunction::Delegate interface, however delegates are not permitted
to modify the MachineInstr's they receive.
In addition to this, the observer has three interface changes.
* erasedInstr() is now erasingInstr() to indicate it is about to be erased
but still exists at the moment.
* changingInstr() and changedInstr() have been added to report changes
before and after they are made. This allows us to trace the changes
in the debug output.
* As a convenience changingAllUsesOfReg() and
finishedChangingAllUsesOfReg() will report changingInstr() and
changedInstr() for each use of a given register. This is primarily useful
for changes caused by MachineRegisterInfo::replaceRegWith()
With this in place, both combine rules have been updated to report their
changes to the observer.
Finally, make some cosmetic changes to the debug output and make Combiner
and CombinerHelp
Reviewers: aditya_nandakumar, bogner, volkan, rtereshin, javed.absar
Reviewed By: aditya_nandakumar
Subscribers: mgorny, rovka, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D52947
llvm-svn: 349167
2018-12-15 01:50:14 +08:00
|
|
|
|
|
|
|
Observer.changingInstr(MI);
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
MI.setDesc(
|
|
|
|
Builder.getTII().get(Preferred.ExtendOpcode == TargetOpcode::G_SEXT
|
|
|
|
? TargetOpcode::G_SEXTLOAD
|
|
|
|
: Preferred.ExtendOpcode == TargetOpcode::G_ZEXT
|
|
|
|
? TargetOpcode::G_ZEXTLOAD
|
|
|
|
: TargetOpcode::G_LOAD));
|
|
|
|
|
|
|
|
// Rewrite all the uses to fix up the types.
|
2019-02-14 08:15:28 +08:00
|
|
|
auto &LoadValue = MI.getOperand(0);
|
2019-06-18 04:56:31 +08:00
|
|
|
SmallVector<MachineOperand *, 4> Uses;
|
|
|
|
for (auto &UseMO : MRI.use_operands(LoadValue.getReg()))
|
|
|
|
Uses.push_back(&UseMO);
|
|
|
|
|
|
|
|
for (auto *UseMO : Uses) {
|
|
|
|
MachineInstr *UseMI = UseMO->getParent();
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
|
|
|
|
// If the extend is compatible with the preferred extend then we should fix
|
|
|
|
// up the type and extend so that it uses the preferred use.
|
|
|
|
if (UseMI->getOpcode() == Preferred.ExtendOpcode ||
|
|
|
|
UseMI->getOpcode() == TargetOpcode::G_ANYEXT) {
|
|
|
|
unsigned UseDstReg = UseMI->getOperand(0).getReg();
|
[globalisel][combiner] Make the CombinerChangeObserver a MachineFunction::Delegate
Summary:
This allows us to register it with the MachineFunction delegate and be
notified automatically about erasure and creation of instructions. However,
we still need explicit notification for modifications such as those caused
by setReg() or replaceRegWith().
There is a catch with this though. The notification for creation is
delivered before any operands can be added. While appropriate for
scheduling combiner work. This is unfortunate for debug output since an
opcode by itself doesn't provide sufficient information on what happened.
As a result, the work list remembers the instructions (when debug output is
requested) and emits a more complete dump later.
Another nit is that the MachineFunction::Delegate provides const pointers
which is inconvenient since we want to use it to schedule future
modification. To resolve this GISelWorkList now has an optional pointer to
the MachineFunction which describes the scope of the work it is permitted
to schedule. If a given MachineInstr* is in this function then it is
permitted to schedule work to be performed on the MachineInstr's. An
alternative to this would be to remove the const from the
MachineFunction::Delegate interface, however delegates are not permitted
to modify the MachineInstr's they receive.
In addition to this, the observer has three interface changes.
* erasedInstr() is now erasingInstr() to indicate it is about to be erased
but still exists at the moment.
* changingInstr() and changedInstr() have been added to report changes
before and after they are made. This allows us to trace the changes
in the debug output.
* As a convenience changingAllUsesOfReg() and
finishedChangingAllUsesOfReg() will report changingInstr() and
changedInstr() for each use of a given register. This is primarily useful
for changes caused by MachineRegisterInfo::replaceRegWith()
With this in place, both combine rules have been updated to report their
changes to the observer.
Finally, make some cosmetic changes to the debug output and make Combiner
and CombinerHelp
Reviewers: aditya_nandakumar, bogner, volkan, rtereshin, javed.absar
Reviewed By: aditya_nandakumar
Subscribers: mgorny, rovka, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D52947
llvm-svn: 349167
2018-12-15 01:50:14 +08:00
|
|
|
MachineOperand &UseSrcMO = UseMI->getOperand(1);
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
const LLT &UseDstTy = MRI.getType(UseDstReg);
|
|
|
|
if (UseDstReg != ChosenDstReg) {
|
|
|
|
if (Preferred.Ty == UseDstTy) {
|
|
|
|
// If the use has the same type as the preferred use, then merge
|
|
|
|
// the vregs and erase the extend. For example:
|
|
|
|
// %1:_(s8) = G_LOAD ...
|
|
|
|
// %2:_(s32) = G_SEXT %1(s8)
|
|
|
|
// %3:_(s32) = G_ANYEXT %1(s8)
|
|
|
|
// ... = ... %3(s32)
|
|
|
|
// rewrites to:
|
|
|
|
// %2:_(s32) = G_SEXTLOAD ...
|
|
|
|
// ... = ... %2(s32)
|
[globalisel][combiner] Make the CombinerChangeObserver a MachineFunction::Delegate
Summary:
This allows us to register it with the MachineFunction delegate and be
notified automatically about erasure and creation of instructions. However,
we still need explicit notification for modifications such as those caused
by setReg() or replaceRegWith().
There is a catch with this though. The notification for creation is
delivered before any operands can be added. While appropriate for
scheduling combiner work. This is unfortunate for debug output since an
opcode by itself doesn't provide sufficient information on what happened.
As a result, the work list remembers the instructions (when debug output is
requested) and emits a more complete dump later.
Another nit is that the MachineFunction::Delegate provides const pointers
which is inconvenient since we want to use it to schedule future
modification. To resolve this GISelWorkList now has an optional pointer to
the MachineFunction which describes the scope of the work it is permitted
to schedule. If a given MachineInstr* is in this function then it is
permitted to schedule work to be performed on the MachineInstr's. An
alternative to this would be to remove the const from the
MachineFunction::Delegate interface, however delegates are not permitted
to modify the MachineInstr's they receive.
In addition to this, the observer has three interface changes.
* erasedInstr() is now erasingInstr() to indicate it is about to be erased
but still exists at the moment.
* changingInstr() and changedInstr() have been added to report changes
before and after they are made. This allows us to trace the changes
in the debug output.
* As a convenience changingAllUsesOfReg() and
finishedChangingAllUsesOfReg() will report changingInstr() and
changedInstr() for each use of a given register. This is primarily useful
for changes caused by MachineRegisterInfo::replaceRegWith()
With this in place, both combine rules have been updated to report their
changes to the observer.
Finally, make some cosmetic changes to the debug output and make Combiner
and CombinerHelp
Reviewers: aditya_nandakumar, bogner, volkan, rtereshin, javed.absar
Reviewed By: aditya_nandakumar
Subscribers: mgorny, rovka, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D52947
llvm-svn: 349167
2018-12-15 01:50:14 +08:00
|
|
|
replaceRegWith(MRI, UseDstReg, ChosenDstReg);
|
2019-06-18 04:56:31 +08:00
|
|
|
Observer.erasingInstr(*UseMO->getParent());
|
|
|
|
UseMO->getParent()->eraseFromParent();
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
} else if (Preferred.Ty.getSizeInBits() < UseDstTy.getSizeInBits()) {
|
|
|
|
// If the preferred size is smaller, then keep the extend but extend
|
|
|
|
// from the result of the extending load. For example:
|
|
|
|
// %1:_(s8) = G_LOAD ...
|
|
|
|
// %2:_(s32) = G_SEXT %1(s8)
|
|
|
|
// %3:_(s64) = G_ANYEXT %1(s8)
|
|
|
|
// ... = ... %3(s64)
|
|
|
|
/// rewrites to:
|
|
|
|
// %2:_(s32) = G_SEXTLOAD ...
|
|
|
|
// %3:_(s64) = G_ANYEXT %2:_(s32)
|
|
|
|
// ... = ... %3(s64)
|
[globalisel][combiner] Make the CombinerChangeObserver a MachineFunction::Delegate
Summary:
This allows us to register it with the MachineFunction delegate and be
notified automatically about erasure and creation of instructions. However,
we still need explicit notification for modifications such as those caused
by setReg() or replaceRegWith().
There is a catch with this though. The notification for creation is
delivered before any operands can be added. While appropriate for
scheduling combiner work. This is unfortunate for debug output since an
opcode by itself doesn't provide sufficient information on what happened.
As a result, the work list remembers the instructions (when debug output is
requested) and emits a more complete dump later.
Another nit is that the MachineFunction::Delegate provides const pointers
which is inconvenient since we want to use it to schedule future
modification. To resolve this GISelWorkList now has an optional pointer to
the MachineFunction which describes the scope of the work it is permitted
to schedule. If a given MachineInstr* is in this function then it is
permitted to schedule work to be performed on the MachineInstr's. An
alternative to this would be to remove the const from the
MachineFunction::Delegate interface, however delegates are not permitted
to modify the MachineInstr's they receive.
In addition to this, the observer has three interface changes.
* erasedInstr() is now erasingInstr() to indicate it is about to be erased
but still exists at the moment.
* changingInstr() and changedInstr() have been added to report changes
before and after they are made. This allows us to trace the changes
in the debug output.
* As a convenience changingAllUsesOfReg() and
finishedChangingAllUsesOfReg() will report changingInstr() and
changedInstr() for each use of a given register. This is primarily useful
for changes caused by MachineRegisterInfo::replaceRegWith()
With this in place, both combine rules have been updated to report their
changes to the observer.
Finally, make some cosmetic changes to the debug output and make Combiner
and CombinerHelp
Reviewers: aditya_nandakumar, bogner, volkan, rtereshin, javed.absar
Reviewed By: aditya_nandakumar
Subscribers: mgorny, rovka, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D52947
llvm-svn: 349167
2018-12-15 01:50:14 +08:00
|
|
|
replaceRegOpWith(MRI, UseSrcMO, ChosenDstReg);
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
} else {
|
|
|
|
// If the preferred size is large, then insert a truncate. For
|
|
|
|
// example:
|
|
|
|
// %1:_(s8) = G_LOAD ...
|
|
|
|
// %2:_(s64) = G_SEXT %1(s8)
|
|
|
|
// %3:_(s32) = G_ZEXT %1(s8)
|
|
|
|
// ... = ... %3(s32)
|
|
|
|
/// rewrites to:
|
|
|
|
// %2:_(s64) = G_SEXTLOAD ...
|
|
|
|
// %4:_(s8) = G_TRUNC %2:_(s32)
|
|
|
|
// %3:_(s64) = G_ZEXT %2:_(s8)
|
|
|
|
// ... = ... %3(s64)
|
2019-06-18 04:56:31 +08:00
|
|
|
InsertInsnsWithoutSideEffectsBeforeUse(Builder, MI, *UseMO,
|
|
|
|
InsertTruncAt);
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// The use is (one of) the uses of the preferred use we chose earlier.
|
|
|
|
// We're going to update the load to def this value later so just erase
|
|
|
|
// the old extend.
|
2019-06-18 04:56:31 +08:00
|
|
|
Observer.erasingInstr(*UseMO->getParent());
|
|
|
|
UseMO->getParent()->eraseFromParent();
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The use isn't an extend. Truncate back to the type we originally loaded.
|
|
|
|
// This is free on many targets.
|
2019-06-18 04:56:31 +08:00
|
|
|
InsertInsnsWithoutSideEffectsBeforeUse(Builder, MI, *UseMO, InsertTruncAt);
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
}
|
2018-10-05 02:44:58 +08:00
|
|
|
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
MI.getOperand(0).setReg(ChosenDstReg);
|
[globalisel][combiner] Make the CombinerChangeObserver a MachineFunction::Delegate
Summary:
This allows us to register it with the MachineFunction delegate and be
notified automatically about erasure and creation of instructions. However,
we still need explicit notification for modifications such as those caused
by setReg() or replaceRegWith().
There is a catch with this though. The notification for creation is
delivered before any operands can be added. While appropriate for
scheduling combiner work. This is unfortunate for debug output since an
opcode by itself doesn't provide sufficient information on what happened.
As a result, the work list remembers the instructions (when debug output is
requested) and emits a more complete dump later.
Another nit is that the MachineFunction::Delegate provides const pointers
which is inconvenient since we want to use it to schedule future
modification. To resolve this GISelWorkList now has an optional pointer to
the MachineFunction which describes the scope of the work it is permitted
to schedule. If a given MachineInstr* is in this function then it is
permitted to schedule work to be performed on the MachineInstr's. An
alternative to this would be to remove the const from the
MachineFunction::Delegate interface, however delegates are not permitted
to modify the MachineInstr's they receive.
In addition to this, the observer has three interface changes.
* erasedInstr() is now erasingInstr() to indicate it is about to be erased
but still exists at the moment.
* changingInstr() and changedInstr() have been added to report changes
before and after they are made. This allows us to trace the changes
in the debug output.
* As a convenience changingAllUsesOfReg() and
finishedChangingAllUsesOfReg() will report changingInstr() and
changedInstr() for each use of a given register. This is primarily useful
for changes caused by MachineRegisterInfo::replaceRegWith()
With this in place, both combine rules have been updated to report their
changes to the observer.
Finally, make some cosmetic changes to the debug output and make Combiner
and CombinerHelp
Reviewers: aditya_nandakumar, bogner, volkan, rtereshin, javed.absar
Reviewed By: aditya_nandakumar
Subscribers: mgorny, rovka, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D52947
llvm-svn: 349167
2018-12-15 01:50:14 +08:00
|
|
|
Observer.changedInstr(MI);
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
}
|
|
|
|
|
2018-01-25 08:41:58 +08:00
|
|
|
bool CombinerHelper::tryCombine(MachineInstr &MI) {
|
Re-commit: [globalisel] Add a combiner helpers for extending loads and use them in a pre-legalize combiner for AArch64
Summary: Depends on D45541
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar, aemerson
Subscribers: aemerson, rengolin, mgorny, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D45543
The previous commit failed portions of the test-suite on GreenDragon due to
duplicate COPY instructions and iterator invalidation. Both issues have now
been fixed. To assist with this, a helper (cloneVirtualRegister) has been added
to MachineRegisterInfo that can be used to get another register that has the same
type and class/bank as an existing one.
llvm-svn: 343654
2018-10-03 10:12:17 +08:00
|
|
|
if (tryCombineCopy(MI))
|
|
|
|
return true;
|
|
|
|
return tryCombineExtendingLoads(MI);
|
2018-01-25 08:41:58 +08:00
|
|
|
}
|