2016-10-15 06:18:18 +08:00
|
|
|
//===-- llvm/CodeGen/GlobalISel/Legalizer.cpp -----------------------------===//
|
2016-07-23 04:03:43 +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-23 04:03:43 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2016-10-15 06:18:18 +08:00
|
|
|
/// \file This file implements the LegalizerHelper class to legalize individual
|
|
|
|
/// instructions and the LegalizePass wrapper pass for the primary
|
2016-07-23 04:03:43 +08:00
|
|
|
/// legalization.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2016-10-15 06:18:18 +08:00
|
|
|
#include "llvm/CodeGen/GlobalISel/Legalizer.h"
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
#include "llvm/ADT/PostOrderIterator.h"
|
2017-08-31 03:32:59 +08:00
|
|
|
#include "llvm/ADT/SetVector.h"
|
2019-01-16 08:40:37 +08:00
|
|
|
#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
|
|
|
|
#include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
|
2018-12-06 04:14:52 +08:00
|
|
|
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
|
2017-11-17 09:07:10 +08:00
|
|
|
#include "llvm/CodeGen/GlobalISel/GISelWorkList.h"
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
#include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h"
|
2016-10-15 06:18:18 +08:00
|
|
|
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
|
[globalisel] Add lost debug locations verifier
Summary:
This verifier tries to ensure that DebugLoc's don't just disappear as
we transform the MIR. It observes the instructions created, erased, and
changed and at checkpoints chosen by the client algorithm verifies the
locations affected by those changes.
In particular, it verifies that:
* Every DebugLoc for an erased/changing instruction is still present on
at least one new/changed instruction
* Failing that, that there is a line-0 location in the new/changed
instructions. It's not possible to confirm which locations were merged so
it conservatively assumes all unaccounted for locations are accounted
for by any line-0 location to avoid false positives.
If that fails, it prints the lost locations in the debug output along with
the instructions that should have accounted for them.
In theory, this is usable by the legalizer, combiner, selector and any other
pass that performs incremental changes to the MIR. However, it has so far
only really been tested on the legalizer (not including the artifact
combiner) where it has caught lots of lost locations, particularly in Custom
legalizations. There's only one example here as my initial testing was on an
out-of-tree target and I haven't done a pass over the in-tree targets yet.
Depends on D77575, D77446
Reviewers: bogner, aprantl, vsk
Subscribers: jvesely, nhaehnle, mgorny, rovka, hiraditya, volkan, kerbowa, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77576
2020-04-02 02:19:58 +08:00
|
|
|
#include "llvm/CodeGen/GlobalISel/LostDebugLocObserver.h"
|
2017-02-24 05:05:42 +08:00
|
|
|
#include "llvm/CodeGen/GlobalISel/Utils.h"
|
|
|
|
#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
|
2016-08-27 10:38:21 +08:00
|
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
|
|
|
#include "llvm/CodeGen/TargetPassConfig.h"
|
2017-11-17 09:07:10 +08:00
|
|
|
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
Sink all InitializePasses.h includes
This file lists every pass in LLVM, and is included by Pass.h, which is
very popular. Every time we add, remove, or rename a pass in LLVM, it
caused lots of recompilation.
I found this fact by looking at this table, which is sorted by the
number of times a file was changed over the last 100,000 git commits
multiplied by the number of object files that depend on it in the
current checkout:
recompiles touches affected_files header
342380 95 3604 llvm/include/llvm/ADT/STLExtras.h
314730 234 1345 llvm/include/llvm/InitializePasses.h
307036 118 2602 llvm/include/llvm/ADT/APInt.h
213049 59 3611 llvm/include/llvm/Support/MathExtras.h
170422 47 3626 llvm/include/llvm/Support/Compiler.h
162225 45 3605 llvm/include/llvm/ADT/Optional.h
158319 63 2513 llvm/include/llvm/ADT/Triple.h
140322 39 3598 llvm/include/llvm/ADT/StringRef.h
137647 59 2333 llvm/include/llvm/Support/Error.h
131619 73 1803 llvm/include/llvm/Support/FileSystem.h
Before this change, touching InitializePasses.h would cause 1345 files
to recompile. After this change, touching it only causes 550 compiles in
an incremental rebuild.
Reviewers: bkramer, asbirlea, bollu, jdoerfert
Differential Revision: https://reviews.llvm.org/D70211
2019-11-14 05:15:01 +08:00
|
|
|
#include "llvm/InitializePasses.h"
|
2016-07-23 04:03:43 +08:00
|
|
|
#include "llvm/Support/Debug.h"
|
2020-02-19 06:42:49 +08:00
|
|
|
#include "llvm/Support/Error.h"
|
2019-04-15 13:04:20 +08:00
|
|
|
#include "llvm/Target/TargetMachine.h"
|
2016-07-23 04:03:43 +08:00
|
|
|
|
2017-04-20 23:46:12 +08:00
|
|
|
#include <iterator>
|
|
|
|
|
2016-10-15 06:18:18 +08:00
|
|
|
#define DEBUG_TYPE "legalizer"
|
2016-07-23 04:03:43 +08:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
2019-01-16 08:40:37 +08:00
|
|
|
static cl::opt<bool>
|
|
|
|
EnableCSEInLegalizer("enable-cse-in-legalizer",
|
|
|
|
cl::desc("Should enable CSE in Legalizer"),
|
|
|
|
cl::Optional, cl::init(false));
|
|
|
|
|
[globalisel] Add lost debug locations verifier
Summary:
This verifier tries to ensure that DebugLoc's don't just disappear as
we transform the MIR. It observes the instructions created, erased, and
changed and at checkpoints chosen by the client algorithm verifies the
locations affected by those changes.
In particular, it verifies that:
* Every DebugLoc for an erased/changing instruction is still present on
at least one new/changed instruction
* Failing that, that there is a line-0 location in the new/changed
instructions. It's not possible to confirm which locations were merged so
it conservatively assumes all unaccounted for locations are accounted
for by any line-0 location to avoid false positives.
If that fails, it prints the lost locations in the debug output along with
the instructions that should have accounted for them.
In theory, this is usable by the legalizer, combiner, selector and any other
pass that performs incremental changes to the MIR. However, it has so far
only really been tested on the legalizer (not including the artifact
combiner) where it has caught lots of lost locations, particularly in Custom
legalizations. There's only one example here as my initial testing was on an
out-of-tree target and I haven't done a pass over the in-tree targets yet.
Depends on D77575, D77446
Reviewers: bogner, aprantl, vsk
Subscribers: jvesely, nhaehnle, mgorny, rovka, hiraditya, volkan, kerbowa, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77576
2020-04-02 02:19:58 +08:00
|
|
|
enum class DebugLocVerifyLevel {
|
|
|
|
None,
|
|
|
|
Legalizations,
|
|
|
|
LegalizationsAndArtifactCombiners,
|
|
|
|
};
|
|
|
|
#ifndef NDEBUG
|
|
|
|
static cl::opt<DebugLocVerifyLevel> VerifyDebugLocs(
|
|
|
|
"verify-legalizer-debug-locs",
|
|
|
|
cl::desc("Verify that debug locations are handled"),
|
2020-04-18 02:25:51 +08:00
|
|
|
cl::values(
|
|
|
|
clEnumValN(DebugLocVerifyLevel::None, "none", "No verification"),
|
|
|
|
clEnumValN(DebugLocVerifyLevel::Legalizations, "legalizations",
|
|
|
|
"Verify legalizations"),
|
|
|
|
clEnumValN(DebugLocVerifyLevel::LegalizationsAndArtifactCombiners,
|
|
|
|
"legalizations+artifactcombiners",
|
|
|
|
"Verify legalizations and artifact combines")),
|
[globalisel] Add lost debug locations verifier
Summary:
This verifier tries to ensure that DebugLoc's don't just disappear as
we transform the MIR. It observes the instructions created, erased, and
changed and at checkpoints chosen by the client algorithm verifies the
locations affected by those changes.
In particular, it verifies that:
* Every DebugLoc for an erased/changing instruction is still present on
at least one new/changed instruction
* Failing that, that there is a line-0 location in the new/changed
instructions. It's not possible to confirm which locations were merged so
it conservatively assumes all unaccounted for locations are accounted
for by any line-0 location to avoid false positives.
If that fails, it prints the lost locations in the debug output along with
the instructions that should have accounted for them.
In theory, this is usable by the legalizer, combiner, selector and any other
pass that performs incremental changes to the MIR. However, it has so far
only really been tested on the legalizer (not including the artifact
combiner) where it has caught lots of lost locations, particularly in Custom
legalizations. There's only one example here as my initial testing was on an
out-of-tree target and I haven't done a pass over the in-tree targets yet.
Depends on D77575, D77446
Reviewers: bogner, aprantl, vsk
Subscribers: jvesely, nhaehnle, mgorny, rovka, hiraditya, volkan, kerbowa, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77576
2020-04-02 02:19:58 +08:00
|
|
|
cl::init(DebugLocVerifyLevel::Legalizations));
|
|
|
|
#else
|
|
|
|
// Always disable it for release builds by preventing the observer from being
|
|
|
|
// installed.
|
|
|
|
static const DebugLocVerifyLevel VerifyDebugLocs = DebugLocVerifyLevel::None;
|
|
|
|
#endif
|
|
|
|
|
2016-10-15 06:18:18 +08:00
|
|
|
char Legalizer::ID = 0;
|
|
|
|
INITIALIZE_PASS_BEGIN(Legalizer, DEBUG_TYPE,
|
2016-08-27 10:38:21 +08:00
|
|
|
"Legalize the Machine IR a function's Machine IR", false,
|
|
|
|
false)
|
|
|
|
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
|
2019-01-16 08:40:37 +08:00
|
|
|
INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
|
2016-10-15 06:18:18 +08:00
|
|
|
INITIALIZE_PASS_END(Legalizer, DEBUG_TYPE,
|
2016-08-27 10:38:21 +08:00
|
|
|
"Legalize the Machine IR a function's Machine IR", false,
|
|
|
|
false)
|
2016-07-23 04:03:43 +08:00
|
|
|
|
GlobalISel: Remove redundant pass initialization
Summary:
All the GlobalISel passes are initialized when the target calls
initializeGlobalISel(), so we don't need to call the initializers
from the pass constructors.
Reviewers: qcolombet, t.p.northover, paquette, dsanders, aemerson, aditya_nandakumar
Reviewed By: aemerson
Subscribers: rovka, kristof.beyls, hiraditya, volkan, Petar.Avramovic, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D63235
llvm-svn: 363642
2019-06-18 10:05:06 +08:00
|
|
|
Legalizer::Legalizer() : MachineFunctionPass(ID) { }
|
2016-07-23 04:03:43 +08:00
|
|
|
|
2016-10-15 06:18:18 +08:00
|
|
|
void Legalizer::getAnalysisUsage(AnalysisUsage &AU) const {
|
2016-08-27 10:38:21 +08:00
|
|
|
AU.addRequired<TargetPassConfig>();
|
2019-01-16 08:40:37 +08:00
|
|
|
AU.addRequired<GISelCSEAnalysisWrapperPass>();
|
|
|
|
AU.addPreserved<GISelCSEAnalysisWrapperPass>();
|
2018-07-13 08:08:38 +08:00
|
|
|
getSelectionDAGFallbackAnalysisUsage(AU);
|
2016-08-27 10:38:21 +08:00
|
|
|
MachineFunctionPass::getAnalysisUsage(AU);
|
|
|
|
}
|
|
|
|
|
2016-10-15 06:18:18 +08:00
|
|
|
void Legalizer::init(MachineFunction &MF) {
|
2016-07-23 04:03:43 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
static bool isArtifact(const MachineInstr &MI) {
|
|
|
|
switch (MI.getOpcode()) {
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
case TargetOpcode::G_TRUNC:
|
|
|
|
case TargetOpcode::G_ZEXT:
|
|
|
|
case TargetOpcode::G_ANYEXT:
|
|
|
|
case TargetOpcode::G_SEXT:
|
|
|
|
case TargetOpcode::G_MERGE_VALUES:
|
|
|
|
case TargetOpcode::G_UNMERGE_VALUES:
|
2018-12-11 02:44:58 +08:00
|
|
|
case TargetOpcode::G_CONCAT_VECTORS:
|
|
|
|
case TargetOpcode::G_BUILD_VECTOR:
|
2019-02-05 07:41:59 +08:00
|
|
|
case TargetOpcode::G_EXTRACT:
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2018-12-06 04:14:52 +08:00
|
|
|
using InstListTy = GISelWorkList<256>;
|
|
|
|
using ArtifactListTy = GISelWorkList<128>;
|
|
|
|
|
2019-01-13 02:36:22 +08:00
|
|
|
namespace {
|
2018-12-06 04:14:52 +08:00
|
|
|
class LegalizerWorkListManager : public GISelChangeObserver {
|
|
|
|
InstListTy &InstList;
|
|
|
|
ArtifactListTy &ArtifactList;
|
2019-04-30 02:45:59 +08:00
|
|
|
#ifndef NDEBUG
|
|
|
|
SmallVector<MachineInstr *, 4> NewMIs;
|
|
|
|
#endif
|
2018-12-06 04:14:52 +08:00
|
|
|
|
|
|
|
public:
|
|
|
|
LegalizerWorkListManager(InstListTy &Insts, ArtifactListTy &Arts)
|
|
|
|
: InstList(Insts), ArtifactList(Arts) {}
|
|
|
|
|
2019-04-30 02:45:59 +08:00
|
|
|
void createdOrChangedInstr(MachineInstr &MI) {
|
2018-12-06 04:14:52 +08:00
|
|
|
// Only legalize pre-isel generic instructions.
|
|
|
|
// Legalization process could generate Target specific pseudo
|
|
|
|
// instructions with generic types. Don't record them
|
|
|
|
if (isPreISelGenericOpcode(MI.getOpcode())) {
|
|
|
|
if (isArtifact(MI))
|
|
|
|
ArtifactList.insert(&MI);
|
|
|
|
else
|
|
|
|
InstList.insert(&MI);
|
|
|
|
}
|
2019-04-30 02:45:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void createdInstr(MachineInstr &MI) override {
|
|
|
|
LLVM_DEBUG(NewMIs.push_back(&MI));
|
|
|
|
createdOrChangedInstr(MI);
|
|
|
|
}
|
|
|
|
|
|
|
|
void printNewInstrs() {
|
|
|
|
LLVM_DEBUG({
|
|
|
|
for (const auto *MI : NewMIs)
|
|
|
|
dbgs() << ".. .. New MI: " << *MI;
|
|
|
|
NewMIs.clear();
|
|
|
|
});
|
2018-12-06 04:14:52 +08:00
|
|
|
}
|
|
|
|
|
2019-01-16 08:40:37 +08:00
|
|
|
void erasingInstr(MachineInstr &MI) override {
|
2018-12-13 07:48:13 +08:00
|
|
|
LLVM_DEBUG(dbgs() << ".. .. Erasing: " << MI);
|
2018-12-06 04:14:52 +08:00
|
|
|
InstList.remove(&MI);
|
|
|
|
ArtifactList.remove(&MI);
|
|
|
|
}
|
|
|
|
|
2019-01-16 08:40:37 +08:00
|
|
|
void changingInstr(MachineInstr &MI) override {
|
2018-12-13 07:48:13 +08:00
|
|
|
LLVM_DEBUG(dbgs() << ".. .. Changing MI: " << MI);
|
|
|
|
}
|
|
|
|
|
2019-01-16 08:40:37 +08:00
|
|
|
void changedInstr(MachineInstr &MI) override {
|
2018-12-06 04:14:52 +08:00
|
|
|
// When insts change, we want to revisit them to legalize them again.
|
|
|
|
// We'll consider them the same as created.
|
2018-12-13 07:48:13 +08:00
|
|
|
LLVM_DEBUG(dbgs() << ".. .. Changed MI: " << MI);
|
2019-04-30 02:45:59 +08:00
|
|
|
createdOrChangedInstr(MI);
|
2018-12-06 04:14:52 +08:00
|
|
|
}
|
|
|
|
};
|
2019-01-13 02:36:22 +08:00
|
|
|
} // namespace
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
|
2019-12-13 00:35:16 +08:00
|
|
|
Legalizer::MFResult
|
|
|
|
Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
|
|
|
|
ArrayRef<GISelChangeObserver *> AuxObservers,
|
[globalisel] Add lost debug locations verifier
Summary:
This verifier tries to ensure that DebugLoc's don't just disappear as
we transform the MIR. It observes the instructions created, erased, and
changed and at checkpoints chosen by the client algorithm verifies the
locations affected by those changes.
In particular, it verifies that:
* Every DebugLoc for an erased/changing instruction is still present on
at least one new/changed instruction
* Failing that, that there is a line-0 location in the new/changed
instructions. It's not possible to confirm which locations were merged so
it conservatively assumes all unaccounted for locations are accounted
for by any line-0 location to avoid false positives.
If that fails, it prints the lost locations in the debug output along with
the instructions that should have accounted for them.
In theory, this is usable by the legalizer, combiner, selector and any other
pass that performs incremental changes to the MIR. However, it has so far
only really been tested on the legalizer (not including the artifact
combiner) where it has caught lots of lost locations, particularly in Custom
legalizations. There's only one example here as my initial testing was on an
out-of-tree target and I haven't done a pass over the in-tree targets yet.
Depends on D77575, D77446
Reviewers: bogner, aprantl, vsk
Subscribers: jvesely, nhaehnle, mgorny, rovka, hiraditya, volkan, kerbowa, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77576
2020-04-02 02:19:58 +08:00
|
|
|
LostDebugLocObserver &LocObserver,
|
2019-12-13 00:35:16 +08:00
|
|
|
MachineIRBuilder &MIRBuilder) {
|
2020-06-08 09:37:29 +08:00
|
|
|
MIRBuilder.setMF(MF);
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
MachineRegisterInfo &MRI = MF.getRegInfo();
|
2016-08-02 19:41:09 +08:00
|
|
|
|
2019-12-13 00:35:16 +08:00
|
|
|
// Populate worklists.
|
2019-01-16 08:40:37 +08:00
|
|
|
InstListTy InstList;
|
|
|
|
ArtifactListTy ArtifactList;
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
ReversePostOrderTraversal<MachineFunction *> RPOT(&MF);
|
|
|
|
// Perform legalization bottom up so we can DCE as we legalize.
|
|
|
|
// Traverse BB in RPOT and within each basic block, add insts top down,
|
|
|
|
// so when we pop_back_val in the legalization process, we traverse bottom-up.
|
|
|
|
for (auto *MBB : RPOT) {
|
|
|
|
if (MBB->empty())
|
|
|
|
continue;
|
|
|
|
for (MachineInstr &MI : *MBB) {
|
2016-08-02 19:41:09 +08:00
|
|
|
// Only legalize pre-isel generic instructions: others don't have types
|
|
|
|
// and are assumed to be legal.
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
if (!isPreISelGenericOpcode(MI.getOpcode()))
|
2016-08-02 19:41:09 +08:00
|
|
|
continue;
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
if (isArtifact(MI))
|
2019-02-15 09:37:54 +08:00
|
|
|
ArtifactList.deferred_insert(&MI);
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
else
|
2019-02-15 09:37:54 +08:00
|
|
|
InstList.deferred_insert(&MI);
|
2016-07-23 04:03:43 +08:00
|
|
|
}
|
2017-04-20 23:46:12 +08:00
|
|
|
}
|
2019-02-15 09:37:54 +08:00
|
|
|
ArtifactList.finalize();
|
|
|
|
InstList.finalize();
|
2019-01-25 07:11:25 +08:00
|
|
|
|
2019-12-13 00:35:16 +08:00
|
|
|
// This observer keeps the worklists updated.
|
2018-12-06 04:14:52 +08:00
|
|
|
LegalizerWorkListManager WorkListObserver(InstList, ArtifactList);
|
2019-12-13 00:35:16 +08:00
|
|
|
// We want both WorkListObserver as well as all the auxiliary observers (e.g.
|
|
|
|
// CSEInfo) to observe all changes. Use the wrapper observer.
|
2019-01-16 08:40:37 +08:00
|
|
|
GISelObserverWrapper WrapperObserver(&WorkListObserver);
|
2019-12-13 00:35:16 +08:00
|
|
|
for (GISelChangeObserver *Observer : AuxObservers)
|
|
|
|
WrapperObserver.addObserver(Observer);
|
|
|
|
|
2019-01-16 08:40:37 +08:00
|
|
|
// Now install the observer as the delegate to MF.
|
|
|
|
// This will keep all the observers notified about new insertions/deletions.
|
2020-02-19 06:42:49 +08:00
|
|
|
RAIIMFObsDelInstaller Installer(MF, WrapperObserver);
|
2019-12-13 00:35:16 +08:00
|
|
|
LegalizerHelper Helper(MF, LI, WrapperObserver, MIRBuilder);
|
|
|
|
LegalizationArtifactCombiner ArtCombiner(MIRBuilder, MRI, LI);
|
2019-01-16 08:40:37 +08:00
|
|
|
auto RemoveDeadInstFromLists = [&WrapperObserver](MachineInstr *DeadMI) {
|
|
|
|
WrapperObserver.erasingInstr(*DeadMI);
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
};
|
|
|
|
bool Changed = false;
|
[GlobalISel] Legalizer: Retry combining illegal artifacts as long as there new artifacts
Summary:
Currently, Legalizer aborts if it’s unable to legalize artifacts. However, it’s
possible to combine them after processing the rest of the instruction because
the legalization is likely to generate more artifacts that allow ArtifactCombiner
to combine away them.
Instead, move illegal artifacts to another list called RetryList and wait until all of the
instruction in InstList are legalized. After that, check if there is any new artifacts and
try to combine them again if that’s the case. If not, abort. The idea is similar to D59339,
but the approach is a bit different.
This patch fixes the issue described above, but the legalizer still may be unable to handle
some cases depending on when to legalize artifacts. So, in the long run, we probably need
a different legalization strategy that handles this dependency in a better way.
Reviewers: dsanders, aditya_nandakumar, qcolombet, arsenm, aemerson, paquette
Reviewed By: dsanders
Subscribers: jvesely, wdng, nhaehnle, rovka, javed.absar, hiraditya, Petar.Avramovic, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D65894
llvm-svn: 369805
2019-08-24 04:30:35 +08:00
|
|
|
SmallVector<MachineInstr *, 128> RetryList;
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
do {
|
2019-12-13 05:08:40 +08:00
|
|
|
LLVM_DEBUG(dbgs() << "=== New Iteration ===\n");
|
[GlobalISel] Legalizer: Retry combining illegal artifacts as long as there new artifacts
Summary:
Currently, Legalizer aborts if it’s unable to legalize artifacts. However, it’s
possible to combine them after processing the rest of the instruction because
the legalization is likely to generate more artifacts that allow ArtifactCombiner
to combine away them.
Instead, move illegal artifacts to another list called RetryList and wait until all of the
instruction in InstList are legalized. After that, check if there is any new artifacts and
try to combine them again if that’s the case. If not, abort. The idea is similar to D59339,
but the approach is a bit different.
This patch fixes the issue described above, but the legalizer still may be unable to handle
some cases depending on when to legalize artifacts. So, in the long run, we probably need
a different legalization strategy that handles this dependency in a better way.
Reviewers: dsanders, aditya_nandakumar, qcolombet, arsenm, aemerson, paquette
Reviewed By: dsanders
Subscribers: jvesely, wdng, nhaehnle, rovka, javed.absar, hiraditya, Petar.Avramovic, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D65894
llvm-svn: 369805
2019-08-24 04:30:35 +08:00
|
|
|
assert(RetryList.empty() && "Expected no instructions in RetryList");
|
|
|
|
unsigned NumArtifacts = ArtifactList.size();
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
while (!InstList.empty()) {
|
|
|
|
MachineInstr &MI = *InstList.pop_back_val();
|
2019-12-13 00:35:16 +08:00
|
|
|
assert(isPreISelGenericOpcode(MI.getOpcode()) &&
|
|
|
|
"Expecting generic opcode");
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
if (isTriviallyDead(MI, MRI)) {
|
2018-05-14 20:53:11 +08:00
|
|
|
LLVM_DEBUG(dbgs() << MI << "Is dead; erasing.\n");
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
MI.eraseFromParentAndMarkDBGValuesForRemoval();
|
2020-04-18 02:42:53 +08:00
|
|
|
LocObserver.checkpoint(false);
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
continue;
|
|
|
|
}
|
2016-08-31 04:51:25 +08:00
|
|
|
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
// Do the legalization for this instruction.
|
2021-05-26 07:54:20 +08:00
|
|
|
auto Res = Helper.legalizeInstrStep(MI, LocObserver);
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
// Error out if we couldn't legalize this instruction. We may want to
|
|
|
|
// fall back to DAG ISel instead in the future.
|
|
|
|
if (Res == LegalizerHelper::UnableToLegalize) {
|
[GlobalISel] Legalizer: Retry combining illegal artifacts as long as there new artifacts
Summary:
Currently, Legalizer aborts if it’s unable to legalize artifacts. However, it’s
possible to combine them after processing the rest of the instruction because
the legalization is likely to generate more artifacts that allow ArtifactCombiner
to combine away them.
Instead, move illegal artifacts to another list called RetryList and wait until all of the
instruction in InstList are legalized. After that, check if there is any new artifacts and
try to combine them again if that’s the case. If not, abort. The idea is similar to D59339,
but the approach is a bit different.
This patch fixes the issue described above, but the legalizer still may be unable to handle
some cases depending on when to legalize artifacts. So, in the long run, we probably need
a different legalization strategy that handles this dependency in a better way.
Reviewers: dsanders, aditya_nandakumar, qcolombet, arsenm, aemerson, paquette
Reviewed By: dsanders
Subscribers: jvesely, wdng, nhaehnle, rovka, javed.absar, hiraditya, Petar.Avramovic, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D65894
llvm-svn: 369805
2019-08-24 04:30:35 +08:00
|
|
|
// Move illegal artifacts to RetryList instead of aborting because
|
|
|
|
// legalizing InstList may generate artifacts that allow
|
|
|
|
// ArtifactCombiner to combine away them.
|
|
|
|
if (isArtifact(MI)) {
|
2019-12-13 05:08:40 +08:00
|
|
|
LLVM_DEBUG(dbgs() << ".. Not legalized, moving to artifacts retry\n");
|
[Legalizer] Making artifact combining order-independent
Legalization algorithm is complicated by two facts:
1) While regular instructions should be possible to legalize in
an isolated, per-instruction, context-free manner, legalization
artifacts can only be eliminated in pairs, which could be deeply, and
ultimately arbitrary nested: { [ () ] }, where which paranthesis kind
depicts an artifact kind, like extend, unmerge, etc. Such structure
can only be fully eliminated by simple local combines if they are
attempted in a particular order (inside out), or alternatively by
repeated scans each eliminating only one innermost pair, resulting in
O(n^2) complexity.
2) Some artifacts might in fact be regular instructions that could (and
sometimes should) be legalized by the target-specific rules. Which
means failure to eliminate all artifacts on the first iteration is
not a failure, they need to be tried as instructions, which may
produce more artifacts, including the ones that are in fact regular
instructions, resulting in a non-constant number of iterations
required to finish the process.
I trust the recently introduced termination condition (no new artifacts
were created during as-a-regular-instruction-retrial of artifacts not
eliminated on the previous iteration) to be efficient in providing
termination, but only performing the legalization in full if and only if
at each step such chains of artifacts are successfully eliminated in
full as well.
Which is currently not guaranteed, as the artifact combines are applied
only once and in an arbitrary order that has to do with the order of
creation or insertion of artifacts into their worklist, which is a no
particular order.
In this patch I make a small change to the artifact combiner, making it
to re-insert into the worklist immediate (modulo a look-through copies)
artifact users of each vreg that changes its definition due to an
artifact combine.
Here the first scan through the artifacts worklist, while not
being done in any guaranteed order, only needs to find the innermost
pair(s) of artifacts that could be immediately combined out. After that
the process follows def-use chains, making them shorter at each step, thus
combining everything that can be combined in O(n) time.
Reviewers: volkan, aditya_nandakumar, qcolombet, paquette, aemerson, dsanders
Reviewed By: aditya_nandakumar, paquette
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D71448
2019-12-13 05:20:41 +08:00
|
|
|
assert(NumArtifacts == 0 &&
|
|
|
|
"Artifacts are only expected in instruction list starting the "
|
|
|
|
"second iteration, but each iteration starting second must "
|
|
|
|
"start with an empty artifacts list");
|
|
|
|
(void)NumArtifacts;
|
[GlobalISel] Legalizer: Retry combining illegal artifacts as long as there new artifacts
Summary:
Currently, Legalizer aborts if it’s unable to legalize artifacts. However, it’s
possible to combine them after processing the rest of the instruction because
the legalization is likely to generate more artifacts that allow ArtifactCombiner
to combine away them.
Instead, move illegal artifacts to another list called RetryList and wait until all of the
instruction in InstList are legalized. After that, check if there is any new artifacts and
try to combine them again if that’s the case. If not, abort. The idea is similar to D59339,
but the approach is a bit different.
This patch fixes the issue described above, but the legalizer still may be unable to handle
some cases depending on when to legalize artifacts. So, in the long run, we probably need
a different legalization strategy that handles this dependency in a better way.
Reviewers: dsanders, aditya_nandakumar, qcolombet, arsenm, aemerson, paquette
Reviewed By: dsanders
Subscribers: jvesely, wdng, nhaehnle, rovka, javed.absar, hiraditya, Petar.Avramovic, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D65894
llvm-svn: 369805
2019-08-24 04:30:35 +08:00
|
|
|
RetryList.push_back(&MI);
|
|
|
|
continue;
|
|
|
|
}
|
2019-12-13 00:35:16 +08:00
|
|
|
Helper.MIRBuilder.stopObservingChanges();
|
|
|
|
return {Changed, &MI};
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
}
|
2019-04-30 02:45:59 +08:00
|
|
|
WorkListObserver.printNewInstrs();
|
[globalisel] Add lost debug locations verifier
Summary:
This verifier tries to ensure that DebugLoc's don't just disappear as
we transform the MIR. It observes the instructions created, erased, and
changed and at checkpoints chosen by the client algorithm verifies the
locations affected by those changes.
In particular, it verifies that:
* Every DebugLoc for an erased/changing instruction is still present on
at least one new/changed instruction
* Failing that, that there is a line-0 location in the new/changed
instructions. It's not possible to confirm which locations were merged so
it conservatively assumes all unaccounted for locations are accounted
for by any line-0 location to avoid false positives.
If that fails, it prints the lost locations in the debug output along with
the instructions that should have accounted for them.
In theory, this is usable by the legalizer, combiner, selector and any other
pass that performs incremental changes to the MIR. However, it has so far
only really been tested on the legalizer (not including the artifact
combiner) where it has caught lots of lost locations, particularly in Custom
legalizations. There's only one example here as my initial testing was on an
out-of-tree target and I haven't done a pass over the in-tree targets yet.
Depends on D77575, D77446
Reviewers: bogner, aprantl, vsk
Subscribers: jvesely, nhaehnle, mgorny, rovka, hiraditya, volkan, kerbowa, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77576
2020-04-02 02:19:58 +08:00
|
|
|
LocObserver.checkpoint();
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
Changed |= Res == LegalizerHelper::Legalized;
|
|
|
|
}
|
[GlobalISel] Legalizer: Retry combining illegal artifacts as long as there new artifacts
Summary:
Currently, Legalizer aborts if it’s unable to legalize artifacts. However, it’s
possible to combine them after processing the rest of the instruction because
the legalization is likely to generate more artifacts that allow ArtifactCombiner
to combine away them.
Instead, move illegal artifacts to another list called RetryList and wait until all of the
instruction in InstList are legalized. After that, check if there is any new artifacts and
try to combine them again if that’s the case. If not, abort. The idea is similar to D59339,
but the approach is a bit different.
This patch fixes the issue described above, but the legalizer still may be unable to handle
some cases depending on when to legalize artifacts. So, in the long run, we probably need
a different legalization strategy that handles this dependency in a better way.
Reviewers: dsanders, aditya_nandakumar, qcolombet, arsenm, aemerson, paquette
Reviewed By: dsanders
Subscribers: jvesely, wdng, nhaehnle, rovka, javed.absar, hiraditya, Petar.Avramovic, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D65894
llvm-svn: 369805
2019-08-24 04:30:35 +08:00
|
|
|
// Try to combine the instructions in RetryList again if there
|
|
|
|
// are new artifacts. If not, stop legalizing.
|
|
|
|
if (!RetryList.empty()) {
|
[Legalizer] Making artifact combining order-independent
Legalization algorithm is complicated by two facts:
1) While regular instructions should be possible to legalize in
an isolated, per-instruction, context-free manner, legalization
artifacts can only be eliminated in pairs, which could be deeply, and
ultimately arbitrary nested: { [ () ] }, where which paranthesis kind
depicts an artifact kind, like extend, unmerge, etc. Such structure
can only be fully eliminated by simple local combines if they are
attempted in a particular order (inside out), or alternatively by
repeated scans each eliminating only one innermost pair, resulting in
O(n^2) complexity.
2) Some artifacts might in fact be regular instructions that could (and
sometimes should) be legalized by the target-specific rules. Which
means failure to eliminate all artifacts on the first iteration is
not a failure, they need to be tried as instructions, which may
produce more artifacts, including the ones that are in fact regular
instructions, resulting in a non-constant number of iterations
required to finish the process.
I trust the recently introduced termination condition (no new artifacts
were created during as-a-regular-instruction-retrial of artifacts not
eliminated on the previous iteration) to be efficient in providing
termination, but only performing the legalization in full if and only if
at each step such chains of artifacts are successfully eliminated in
full as well.
Which is currently not guaranteed, as the artifact combines are applied
only once and in an arbitrary order that has to do with the order of
creation or insertion of artifacts into their worklist, which is a no
particular order.
In this patch I make a small change to the artifact combiner, making it
to re-insert into the worklist immediate (modulo a look-through copies)
artifact users of each vreg that changes its definition due to an
artifact combine.
Here the first scan through the artifacts worklist, while not
being done in any guaranteed order, only needs to find the innermost
pair(s) of artifacts that could be immediately combined out. After that
the process follows def-use chains, making them shorter at each step, thus
combining everything that can be combined in O(n) time.
Reviewers: volkan, aditya_nandakumar, qcolombet, paquette, aemerson, dsanders
Reviewed By: aditya_nandakumar, paquette
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D71448
2019-12-13 05:20:41 +08:00
|
|
|
if (!ArtifactList.empty()) {
|
[GlobalISel] Legalizer: Retry combining illegal artifacts as long as there new artifacts
Summary:
Currently, Legalizer aborts if it’s unable to legalize artifacts. However, it’s
possible to combine them after processing the rest of the instruction because
the legalization is likely to generate more artifacts that allow ArtifactCombiner
to combine away them.
Instead, move illegal artifacts to another list called RetryList and wait until all of the
instruction in InstList are legalized. After that, check if there is any new artifacts and
try to combine them again if that’s the case. If not, abort. The idea is similar to D59339,
but the approach is a bit different.
This patch fixes the issue described above, but the legalizer still may be unable to handle
some cases depending on when to legalize artifacts. So, in the long run, we probably need
a different legalization strategy that handles this dependency in a better way.
Reviewers: dsanders, aditya_nandakumar, qcolombet, arsenm, aemerson, paquette
Reviewed By: dsanders
Subscribers: jvesely, wdng, nhaehnle, rovka, javed.absar, hiraditya, Petar.Avramovic, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D65894
llvm-svn: 369805
2019-08-24 04:30:35 +08:00
|
|
|
while (!RetryList.empty())
|
|
|
|
ArtifactList.insert(RetryList.pop_back_val());
|
|
|
|
} else {
|
2019-12-13 05:08:40 +08:00
|
|
|
LLVM_DEBUG(dbgs() << "No new artifacts created, not retrying!\n");
|
2019-12-13 00:35:16 +08:00
|
|
|
Helper.MIRBuilder.stopObservingChanges();
|
|
|
|
return {Changed, RetryList.front()};
|
[GlobalISel] Legalizer: Retry combining illegal artifacts as long as there new artifacts
Summary:
Currently, Legalizer aborts if it’s unable to legalize artifacts. However, it’s
possible to combine them after processing the rest of the instruction because
the legalization is likely to generate more artifacts that allow ArtifactCombiner
to combine away them.
Instead, move illegal artifacts to another list called RetryList and wait until all of the
instruction in InstList are legalized. After that, check if there is any new artifacts and
try to combine them again if that’s the case. If not, abort. The idea is similar to D59339,
but the approach is a bit different.
This patch fixes the issue described above, but the legalizer still may be unable to handle
some cases depending on when to legalize artifacts. So, in the long run, we probably need
a different legalization strategy that handles this dependency in a better way.
Reviewers: dsanders, aditya_nandakumar, qcolombet, arsenm, aemerson, paquette
Reviewed By: dsanders
Subscribers: jvesely, wdng, nhaehnle, rovka, javed.absar, hiraditya, Petar.Avramovic, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D65894
llvm-svn: 369805
2019-08-24 04:30:35 +08:00
|
|
|
}
|
|
|
|
}
|
[globalisel] Add lost debug locations verifier
Summary:
This verifier tries to ensure that DebugLoc's don't just disappear as
we transform the MIR. It observes the instructions created, erased, and
changed and at checkpoints chosen by the client algorithm verifies the
locations affected by those changes.
In particular, it verifies that:
* Every DebugLoc for an erased/changing instruction is still present on
at least one new/changed instruction
* Failing that, that there is a line-0 location in the new/changed
instructions. It's not possible to confirm which locations were merged so
it conservatively assumes all unaccounted for locations are accounted
for by any line-0 location to avoid false positives.
If that fails, it prints the lost locations in the debug output along with
the instructions that should have accounted for them.
In theory, this is usable by the legalizer, combiner, selector and any other
pass that performs incremental changes to the MIR. However, it has so far
only really been tested on the legalizer (not including the artifact
combiner) where it has caught lots of lost locations, particularly in Custom
legalizations. There's only one example here as my initial testing was on an
out-of-tree target and I haven't done a pass over the in-tree targets yet.
Depends on D77575, D77446
Reviewers: bogner, aprantl, vsk
Subscribers: jvesely, nhaehnle, mgorny, rovka, hiraditya, volkan, kerbowa, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77576
2020-04-02 02:19:58 +08:00
|
|
|
LocObserver.checkpoint();
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
while (!ArtifactList.empty()) {
|
|
|
|
MachineInstr &MI = *ArtifactList.pop_back_val();
|
2019-12-13 00:35:16 +08:00
|
|
|
assert(isPreISelGenericOpcode(MI.getOpcode()) &&
|
|
|
|
"Expecting generic opcode");
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
if (isTriviallyDead(MI, MRI)) {
|
2018-12-13 05:32:01 +08:00
|
|
|
LLVM_DEBUG(dbgs() << MI << "Is dead\n");
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
RemoveDeadInstFromLists(&MI);
|
|
|
|
MI.eraseFromParentAndMarkDBGValuesForRemoval();
|
2020-04-18 02:42:53 +08:00
|
|
|
LocObserver.checkpoint(false);
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
SmallVector<MachineInstr *, 4> DeadInstructions;
|
2019-12-13 05:08:40 +08:00
|
|
|
LLVM_DEBUG(dbgs() << "Trying to combine: " << MI);
|
2019-03-28 01:47:42 +08:00
|
|
|
if (ArtCombiner.tryCombineInstruction(MI, DeadInstructions,
|
|
|
|
WrapperObserver)) {
|
2019-04-30 02:45:59 +08:00
|
|
|
WorkListObserver.printNewInstrs();
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
for (auto *DeadMI : DeadInstructions) {
|
2020-08-24 03:02:50 +08:00
|
|
|
LLVM_DEBUG(dbgs() << "Is dead: " << *DeadMI);
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
RemoveDeadInstFromLists(DeadMI);
|
|
|
|
DeadMI->eraseFromParentAndMarkDBGValuesForRemoval();
|
|
|
|
}
|
2020-04-18 02:39:54 +08:00
|
|
|
LocObserver.checkpoint(
|
|
|
|
VerifyDebugLocs ==
|
|
|
|
DebugLocVerifyLevel::LegalizationsAndArtifactCombiners);
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
Changed = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// If this was not an artifact (that could be combined away), this might
|
|
|
|
// need special handling. Add it to InstList, so when it's processed
|
|
|
|
// there, it has to be legal or specially handled.
|
2019-12-13 05:08:40 +08:00
|
|
|
else {
|
|
|
|
LLVM_DEBUG(dbgs() << ".. Not combined, moving to instructions list\n");
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
InstList.insert(&MI);
|
2019-12-13 05:08:40 +08:00
|
|
|
}
|
2016-08-31 04:51:25 +08:00
|
|
|
}
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
} while (!InstList.empty());
|
|
|
|
|
2019-12-13 00:35:16 +08:00
|
|
|
return {Changed, /*FailedOn*/ nullptr};
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
|
|
|
|
// If the ISel pipeline failed, do not bother running that pass.
|
|
|
|
if (MF.getProperties().hasProperty(
|
|
|
|
MachineFunctionProperties::Property::FailedISel))
|
|
|
|
return false;
|
|
|
|
LLVM_DEBUG(dbgs() << "Legalize Machine IR for: " << MF.getName() << '\n');
|
|
|
|
init(MF);
|
|
|
|
const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
|
|
|
|
GISelCSEAnalysisWrapper &Wrapper =
|
|
|
|
getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
|
|
|
|
MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
|
|
|
|
|
|
|
|
const size_t NumBlocks = MF.size();
|
|
|
|
|
|
|
|
std::unique_ptr<MachineIRBuilder> MIRBuilder;
|
|
|
|
GISelCSEInfo *CSEInfo = nullptr;
|
|
|
|
bool EnableCSE = EnableCSEInLegalizer.getNumOccurrences()
|
|
|
|
? EnableCSEInLegalizer
|
|
|
|
: TPC.isGISelCSEEnabled();
|
|
|
|
if (EnableCSE) {
|
|
|
|
MIRBuilder = std::make_unique<CSEMIRBuilder>();
|
|
|
|
CSEInfo = &Wrapper.get(TPC.getCSEConfig());
|
|
|
|
MIRBuilder->setCSEInfo(CSEInfo);
|
|
|
|
} else
|
|
|
|
MIRBuilder = std::make_unique<MachineIRBuilder>();
|
|
|
|
|
|
|
|
SmallVector<GISelChangeObserver *, 1> AuxObservers;
|
|
|
|
if (EnableCSE && CSEInfo) {
|
|
|
|
// We want CSEInfo in addition to WorkListObserver to observe all changes.
|
|
|
|
AuxObservers.push_back(CSEInfo);
|
|
|
|
}
|
2020-02-19 06:42:49 +08:00
|
|
|
assert(!CSEInfo || !errorToBool(CSEInfo->verify()));
|
[globalisel] Add lost debug locations verifier
Summary:
This verifier tries to ensure that DebugLoc's don't just disappear as
we transform the MIR. It observes the instructions created, erased, and
changed and at checkpoints chosen by the client algorithm verifies the
locations affected by those changes.
In particular, it verifies that:
* Every DebugLoc for an erased/changing instruction is still present on
at least one new/changed instruction
* Failing that, that there is a line-0 location in the new/changed
instructions. It's not possible to confirm which locations were merged so
it conservatively assumes all unaccounted for locations are accounted
for by any line-0 location to avoid false positives.
If that fails, it prints the lost locations in the debug output along with
the instructions that should have accounted for them.
In theory, this is usable by the legalizer, combiner, selector and any other
pass that performs incremental changes to the MIR. However, it has so far
only really been tested on the legalizer (not including the artifact
combiner) where it has caught lots of lost locations, particularly in Custom
legalizations. There's only one example here as my initial testing was on an
out-of-tree target and I haven't done a pass over the in-tree targets yet.
Depends on D77575, D77446
Reviewers: bogner, aprantl, vsk
Subscribers: jvesely, nhaehnle, mgorny, rovka, hiraditya, volkan, kerbowa, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77576
2020-04-02 02:19:58 +08:00
|
|
|
LostDebugLocObserver LocObserver(DEBUG_TYPE);
|
|
|
|
if (VerifyDebugLocs > DebugLocVerifyLevel::None)
|
|
|
|
AuxObservers.push_back(&LocObserver);
|
2019-12-13 00:35:16 +08:00
|
|
|
|
|
|
|
const LegalizerInfo &LI = *MF.getSubtarget().getLegalizerInfo();
|
[globalisel] Add lost debug locations verifier
Summary:
This verifier tries to ensure that DebugLoc's don't just disappear as
we transform the MIR. It observes the instructions created, erased, and
changed and at checkpoints chosen by the client algorithm verifies the
locations affected by those changes.
In particular, it verifies that:
* Every DebugLoc for an erased/changing instruction is still present on
at least one new/changed instruction
* Failing that, that there is a line-0 location in the new/changed
instructions. It's not possible to confirm which locations were merged so
it conservatively assumes all unaccounted for locations are accounted
for by any line-0 location to avoid false positives.
If that fails, it prints the lost locations in the debug output along with
the instructions that should have accounted for them.
In theory, this is usable by the legalizer, combiner, selector and any other
pass that performs incremental changes to the MIR. However, it has so far
only really been tested on the legalizer (not including the artifact
combiner) where it has caught lots of lost locations, particularly in Custom
legalizations. There's only one example here as my initial testing was on an
out-of-tree target and I haven't done a pass over the in-tree targets yet.
Depends on D77575, D77446
Reviewers: bogner, aprantl, vsk
Subscribers: jvesely, nhaehnle, mgorny, rovka, hiraditya, volkan, kerbowa, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77576
2020-04-02 02:19:58 +08:00
|
|
|
MFResult Result =
|
|
|
|
legalizeMachineFunction(MF, LI, AuxObservers, LocObserver, *MIRBuilder);
|
2019-12-13 00:35:16 +08:00
|
|
|
|
|
|
|
if (Result.FailedOn) {
|
|
|
|
reportGISelFailure(MF, TPC, MORE, "gisel-legalize",
|
|
|
|
"unable to legalize instruction", *Result.FailedOn);
|
|
|
|
return false;
|
|
|
|
}
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
// For now don't support if new blocks are inserted - we would need to fix the
|
2019-12-13 00:35:16 +08:00
|
|
|
// outer loop for that.
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
if (MF.size() != NumBlocks) {
|
|
|
|
MachineOptimizationRemarkMissed R("gisel-legalize", "GISelFailure",
|
2017-12-16 06:22:58 +08:00
|
|
|
MF.getFunction().getSubprogram(),
|
[GISel]: Rework legalization algorithm for better elimination of
artifacts along with DCE
Legalization Artifacts are all those insts that are there to make the
type system happy. Currently, the target needs to say all combinations
of extends and truncs are legal and there's no way of verifying that
post legalization, we only have *truly* legal instructions. This patch
changes roughly the legalization algorithm to process all illegal insts
at one go, and then process all truncs/extends that were added to
satisfy the type constraints separately trying to combine trivial cases
until they converge. This has the added benefit that, the target
legalizerinfo can only say which truncs and extends are okay and the
artifact combiner would combine away other exts and truncs.
Updated legalization algorithm to roughly the following pseudo code.
WorkList Insts, Artifacts;
collect_all_insts_and_artifacts(Insts, Artifacts);
do {
for (Inst in Insts)
legalizeInstrStep(Inst, Insts, Artifacts);
for (Artifact in Artifacts)
tryCombineArtifact(Artifact, Insts, Artifacts);
} while(!Insts.empty());
Also, wrote a simple wrapper equivalent to SetVector, except for
erasing, it avoids moving all elements over by one and instead just
nulls them out.
llvm-svn: 318210
2017-11-15 06:42:19 +08:00
|
|
|
/*MBB=*/nullptr);
|
|
|
|
R << "inserting blocks is not supported yet";
|
|
|
|
reportGISelFailure(MF, TPC, MORE, R);
|
|
|
|
return false;
|
2016-08-31 04:51:25 +08:00
|
|
|
}
|
[globalisel] Add lost debug locations verifier
Summary:
This verifier tries to ensure that DebugLoc's don't just disappear as
we transform the MIR. It observes the instructions created, erased, and
changed and at checkpoints chosen by the client algorithm verifies the
locations affected by those changes.
In particular, it verifies that:
* Every DebugLoc for an erased/changing instruction is still present on
at least one new/changed instruction
* Failing that, that there is a line-0 location in the new/changed
instructions. It's not possible to confirm which locations were merged so
it conservatively assumes all unaccounted for locations are accounted
for by any line-0 location to avoid false positives.
If that fails, it prints the lost locations in the debug output along with
the instructions that should have accounted for them.
In theory, this is usable by the legalizer, combiner, selector and any other
pass that performs incremental changes to the MIR. However, it has so far
only really been tested on the legalizer (not including the artifact
combiner) where it has caught lots of lost locations, particularly in Custom
legalizations. There's only one example here as my initial testing was on an
out-of-tree target and I haven't done a pass over the in-tree targets yet.
Depends on D77575, D77446
Reviewers: bogner, aprantl, vsk
Subscribers: jvesely, nhaehnle, mgorny, rovka, hiraditya, volkan, kerbowa, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77576
2020-04-02 02:19:58 +08:00
|
|
|
|
|
|
|
if (LocObserver.getNumLostDebugLocs()) {
|
|
|
|
MachineOptimizationRemarkMissed R("gisel-legalize", "LostDebugLoc",
|
|
|
|
MF.getFunction().getSubprogram(),
|
|
|
|
/*MBB=*/&*MF.begin());
|
|
|
|
R << "lost "
|
|
|
|
<< ore::NV("NumLostDebugLocs", LocObserver.getNumLostDebugLocs())
|
|
|
|
<< " debug locations during pass";
|
|
|
|
reportGISelWarning(MF, TPC, MORE, R);
|
|
|
|
// Example remark:
|
|
|
|
// --- !Missed
|
|
|
|
// Pass: gisel-legalize
|
|
|
|
// Name: GISelFailure
|
|
|
|
// DebugLoc: { File: '.../legalize-urem.mir', Line: 1, Column: 0 }
|
|
|
|
// Function: test_urem_s32
|
|
|
|
// Args:
|
|
|
|
// - String: 'lost '
|
|
|
|
// - NumLostDebugLocs: '1'
|
|
|
|
// - String: ' debug locations during pass'
|
|
|
|
// ...
|
|
|
|
}
|
|
|
|
|
2020-02-19 06:42:49 +08:00
|
|
|
// If for some reason CSE was not enabled, make sure that we invalidate the
|
|
|
|
// CSEInfo object (as we currently declare that the analysis is preserved).
|
|
|
|
// The next time get on the wrapper is called, it will force it to recompute
|
|
|
|
// the analysis.
|
|
|
|
if (!EnableCSE)
|
|
|
|
Wrapper.setComputed(false);
|
2019-12-13 00:35:16 +08:00
|
|
|
return Result.Changed;
|
2016-07-23 04:03:43 +08:00
|
|
|
}
|