2016-12-22 07:26:20 +08:00
|
|
|
//===- GlobalISelEmitter.cpp - Generate an instruction selector -----------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
/// \file
|
|
|
|
/// This tablegen backend emits code for use by the GlobalISel instruction
|
|
|
|
/// selector. See include/llvm/CodeGen/TargetGlobalISel.td.
|
|
|
|
///
|
|
|
|
/// This file analyzes the patterns recognized by the SelectionDAGISel tablegen
|
|
|
|
/// backend, filters out the ones that are unsupported, maps
|
|
|
|
/// SelectionDAG-specific constructs to their GlobalISel counterpart
|
|
|
|
/// (when applicable: MVT to LLT; SDNode to generic Instruction).
|
|
|
|
///
|
|
|
|
/// Not all patterns are supported: pass the tablegen invocation
|
|
|
|
/// "-warn-on-skipped-patterns" to emit a warning when a pattern is skipped,
|
|
|
|
/// as well as why.
|
|
|
|
///
|
|
|
|
/// The generated file defines a single method:
|
|
|
|
/// bool <Target>InstructionSelector::selectImpl(MachineInstr &I) const;
|
|
|
|
/// intended to be used in InstructionSelector::select as the first-step
|
|
|
|
/// selector for the patterns that don't require complex C++.
|
|
|
|
///
|
|
|
|
/// FIXME: We'll probably want to eventually define a base
|
|
|
|
/// "TargetGenInstructionSelector" class.
|
|
|
|
///
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "CodeGenDAGPatterns.h"
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
#include "SubtargetFeatureInfo.h"
|
2016-12-22 07:26:20 +08:00
|
|
|
#include "llvm/ADT/Optional.h"
|
[globalisel][tablegen] Add experimental support for OperandWithDefaultOps, PredicateOperand, and OptionalDefOperand
Summary:
As far as instruction selection is concerned, all three appear to be same thing.
Support for these operands is experimental since AArch64 doesn't make use
of them and the in-tree targets that do use them (AMDGPU for
OperandWithDefaultOps, AMDGPU/ARM/Hexagon/Lanai for PredicateOperand, and ARM
for OperandWithDefaultOps) are not using tablegen-erated GlobalISel yet.
Reviewers: rovka, aditya_nandakumar, t.p.northover, qcolombet, ab
Reviewed By: rovka
Subscribers: inglorion, aemerson, rengolin, mehdi_amini, dberris, kristof.beyls, igorb, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D31135
llvm-svn: 300037
2017-04-12 16:23:08 +08:00
|
|
|
#include "llvm/ADT/SmallSet.h"
|
2016-12-22 07:26:20 +08:00
|
|
|
#include "llvm/ADT/Statistic.h"
|
|
|
|
#include "llvm/CodeGen/MachineValueType.h"
|
|
|
|
#include "llvm/Support/CommandLine.h"
|
2017-02-10 12:00:17 +08:00
|
|
|
#include "llvm/Support/Error.h"
|
Recommit: [globalisel] Change LLT constructor string into an LLT-based object that knows how to generate it.
Summary:
This will allow future patches to inspect the details of the LLT. The implementation is now split between
the Support and CodeGen libraries to allow TableGen to use this class without introducing layering concerns.
Thanks to Ahmed Bougacha for finding a reasonable way to avoid the layering issue and providing the version of this patch without that problem.
The problem with the previous commit appears to have been that TableGen was including CodeGen/LowLevelType.h instead of Support/LowLevelTypeImpl.h.
Reviewers: t.p.northover, qcolombet, rovka, aditya_nandakumar, ab, javed.absar
Subscribers: arsenm, nhaehnle, mgorny, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30046
llvm-svn: 297241
2017-03-08 07:20:35 +08:00
|
|
|
#include "llvm/Support/LowLevelTypeImpl.h"
|
2017-02-21 17:19:41 +08:00
|
|
|
#include "llvm/Support/ScopedPrinter.h"
|
2016-12-22 07:26:20 +08:00
|
|
|
#include "llvm/TableGen/Error.h"
|
|
|
|
#include "llvm/TableGen/Record.h"
|
|
|
|
#include "llvm/TableGen/TableGenBackend.h"
|
|
|
|
#include <string>
|
2017-03-15 05:32:08 +08:00
|
|
|
#include <numeric>
|
2016-12-22 07:26:20 +08:00
|
|
|
using namespace llvm;
|
|
|
|
|
|
|
|
#define DEBUG_TYPE "gisel-emitter"
|
|
|
|
|
|
|
|
STATISTIC(NumPatternTotal, "Total number of patterns");
|
2017-02-20 22:31:27 +08:00
|
|
|
STATISTIC(NumPatternImported, "Number of patterns imported from SelectionDAG");
|
|
|
|
STATISTIC(NumPatternImportsSkipped, "Number of SelectionDAG imports skipped");
|
2016-12-22 07:26:20 +08:00
|
|
|
STATISTIC(NumPatternEmitted, "Number of patterns emitted");
|
|
|
|
|
2017-03-27 21:15:13 +08:00
|
|
|
cl::OptionCategory GlobalISelEmitterCat("Options for -gen-global-isel");
|
|
|
|
|
2016-12-22 07:26:20 +08:00
|
|
|
static cl::opt<bool> WarnOnSkippedPatterns(
|
|
|
|
"warn-on-skipped-patterns",
|
|
|
|
cl::desc("Explain why a pattern was skipped for inclusion "
|
|
|
|
"in the GlobalISel selector"),
|
2017-03-27 21:15:13 +08:00
|
|
|
cl::init(false), cl::cat(GlobalISelEmitterCat));
|
2016-12-22 07:26:20 +08:00
|
|
|
|
2017-03-16 04:18:38 +08:00
|
|
|
namespace {
|
2016-12-22 07:26:20 +08:00
|
|
|
//===- Helper functions ---------------------------------------------------===//
|
|
|
|
|
Recommit: [globalisel] Change LLT constructor string into an LLT-based object that knows how to generate it.
Summary:
This will allow future patches to inspect the details of the LLT. The implementation is now split between
the Support and CodeGen libraries to allow TableGen to use this class without introducing layering concerns.
Thanks to Ahmed Bougacha for finding a reasonable way to avoid the layering issue and providing the version of this patch without that problem.
The problem with the previous commit appears to have been that TableGen was including CodeGen/LowLevelType.h instead of Support/LowLevelTypeImpl.h.
Reviewers: t.p.northover, qcolombet, rovka, aditya_nandakumar, ab, javed.absar
Subscribers: arsenm, nhaehnle, mgorny, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30046
llvm-svn: 297241
2017-03-08 07:20:35 +08:00
|
|
|
/// This class stands in for LLT wherever we want to tablegen-erate an
|
|
|
|
/// equivalent at compiler run-time.
|
|
|
|
class LLTCodeGen {
|
|
|
|
private:
|
|
|
|
LLT Ty;
|
|
|
|
|
|
|
|
public:
|
|
|
|
LLTCodeGen(const LLT &Ty) : Ty(Ty) {}
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
std::string getCxxEnumValue() const {
|
|
|
|
std::string Str;
|
|
|
|
raw_string_ostream OS(Str);
|
|
|
|
|
|
|
|
emitCxxEnumValue(OS);
|
|
|
|
return OS.str();
|
|
|
|
}
|
|
|
|
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
void emitCxxEnumValue(raw_ostream &OS) const {
|
|
|
|
if (Ty.isScalar()) {
|
|
|
|
OS << "GILLT_s" << Ty.getSizeInBits();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (Ty.isVector()) {
|
|
|
|
OS << "GILLT_v" << Ty.getNumElements() << "s" << Ty.getScalarSizeInBits();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
llvm_unreachable("Unhandled LLT");
|
|
|
|
}
|
|
|
|
|
Recommit: [globalisel] Change LLT constructor string into an LLT-based object that knows how to generate it.
Summary:
This will allow future patches to inspect the details of the LLT. The implementation is now split between
the Support and CodeGen libraries to allow TableGen to use this class without introducing layering concerns.
Thanks to Ahmed Bougacha for finding a reasonable way to avoid the layering issue and providing the version of this patch without that problem.
The problem with the previous commit appears to have been that TableGen was including CodeGen/LowLevelType.h instead of Support/LowLevelTypeImpl.h.
Reviewers: t.p.northover, qcolombet, rovka, aditya_nandakumar, ab, javed.absar
Subscribers: arsenm, nhaehnle, mgorny, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30046
llvm-svn: 297241
2017-03-08 07:20:35 +08:00
|
|
|
void emitCxxConstructorCall(raw_ostream &OS) const {
|
|
|
|
if (Ty.isScalar()) {
|
|
|
|
OS << "LLT::scalar(" << Ty.getSizeInBits() << ")";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (Ty.isVector()) {
|
2017-06-28 21:50:04 +08:00
|
|
|
OS << "LLT::vector(" << Ty.getNumElements() << ", "
|
|
|
|
<< Ty.getScalarSizeInBits() << ")";
|
Recommit: [globalisel] Change LLT constructor string into an LLT-based object that knows how to generate it.
Summary:
This will allow future patches to inspect the details of the LLT. The implementation is now split between
the Support and CodeGen libraries to allow TableGen to use this class without introducing layering concerns.
Thanks to Ahmed Bougacha for finding a reasonable way to avoid the layering issue and providing the version of this patch without that problem.
The problem with the previous commit appears to have been that TableGen was including CodeGen/LowLevelType.h instead of Support/LowLevelTypeImpl.h.
Reviewers: t.p.northover, qcolombet, rovka, aditya_nandakumar, ab, javed.absar
Subscribers: arsenm, nhaehnle, mgorny, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30046
llvm-svn: 297241
2017-03-08 07:20:35 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
llvm_unreachable("Unhandled LLT");
|
|
|
|
}
|
2017-03-15 05:32:08 +08:00
|
|
|
|
|
|
|
const LLT &get() const { return Ty; }
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
|
|
|
|
/// This ordering is used for std::unique() and std::sort(). There's no
|
|
|
|
/// particular logic behind the order.
|
|
|
|
bool operator<(const LLTCodeGen &Other) const {
|
|
|
|
if (!Ty.isValid())
|
|
|
|
return Other.Ty.isValid();
|
|
|
|
if (Ty.isScalar()) {
|
|
|
|
if (!Other.Ty.isValid())
|
|
|
|
return false;
|
|
|
|
if (Other.Ty.isScalar())
|
|
|
|
return Ty.getSizeInBits() < Other.Ty.getSizeInBits();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (Ty.isVector()) {
|
|
|
|
if (!Other.Ty.isValid() || Other.Ty.isScalar())
|
|
|
|
return false;
|
|
|
|
if (Other.Ty.isVector()) {
|
|
|
|
if (Ty.getNumElements() < Other.Ty.getNumElements())
|
|
|
|
return true;
|
|
|
|
if (Ty.getNumElements() > Other.Ty.getNumElements())
|
|
|
|
return false;
|
|
|
|
return Ty.getSizeInBits() < Other.Ty.getSizeInBits();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
llvm_unreachable("Unhandled LLT");
|
|
|
|
}
|
2017-03-15 05:32:08 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class InstructionMatcher;
|
2016-12-22 07:26:20 +08:00
|
|
|
/// Convert an MVT to an equivalent LLT if possible, or the invalid LLT() for
|
|
|
|
/// MVTs that don't map cleanly to an LLT (e.g., iPTR, *any, ...).
|
Recommit: [globalisel] Change LLT constructor string into an LLT-based object that knows how to generate it.
Summary:
This will allow future patches to inspect the details of the LLT. The implementation is now split between
the Support and CodeGen libraries to allow TableGen to use this class without introducing layering concerns.
Thanks to Ahmed Bougacha for finding a reasonable way to avoid the layering issue and providing the version of this patch without that problem.
The problem with the previous commit appears to have been that TableGen was including CodeGen/LowLevelType.h instead of Support/LowLevelTypeImpl.h.
Reviewers: t.p.northover, qcolombet, rovka, aditya_nandakumar, ab, javed.absar
Subscribers: arsenm, nhaehnle, mgorny, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30046
llvm-svn: 297241
2017-03-08 07:20:35 +08:00
|
|
|
static Optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT) {
|
2016-12-22 07:26:20 +08:00
|
|
|
MVT VT(SVT);
|
Recommit: [globalisel] Change LLT constructor string into an LLT-based object that knows how to generate it.
Summary:
This will allow future patches to inspect the details of the LLT. The implementation is now split between
the Support and CodeGen libraries to allow TableGen to use this class without introducing layering concerns.
Thanks to Ahmed Bougacha for finding a reasonable way to avoid the layering issue and providing the version of this patch without that problem.
The problem with the previous commit appears to have been that TableGen was including CodeGen/LowLevelType.h instead of Support/LowLevelTypeImpl.h.
Reviewers: t.p.northover, qcolombet, rovka, aditya_nandakumar, ab, javed.absar
Subscribers: arsenm, nhaehnle, mgorny, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30046
llvm-svn: 297241
2017-03-08 07:20:35 +08:00
|
|
|
if (VT.isVector() && VT.getVectorNumElements() != 1)
|
2017-06-28 21:50:04 +08:00
|
|
|
return LLTCodeGen(
|
|
|
|
LLT::vector(VT.getVectorNumElements(), VT.getScalarSizeInBits()));
|
Recommit: [globalisel] Change LLT constructor string into an LLT-based object that knows how to generate it.
Summary:
This will allow future patches to inspect the details of the LLT. The implementation is now split between
the Support and CodeGen libraries to allow TableGen to use this class without introducing layering concerns.
Thanks to Ahmed Bougacha for finding a reasonable way to avoid the layering issue and providing the version of this patch without that problem.
The problem with the previous commit appears to have been that TableGen was including CodeGen/LowLevelType.h instead of Support/LowLevelTypeImpl.h.
Reviewers: t.p.northover, qcolombet, rovka, aditya_nandakumar, ab, javed.absar
Subscribers: arsenm, nhaehnle, mgorny, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30046
llvm-svn: 297241
2017-03-08 07:20:35 +08:00
|
|
|
if (VT.isInteger() || VT.isFloatingPoint())
|
|
|
|
return LLTCodeGen(LLT::scalar(VT.getSizeInBits()));
|
|
|
|
return None;
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
|
|
|
|
2017-04-13 17:45:37 +08:00
|
|
|
static std::string explainPredicates(const TreePatternNode *N) {
|
|
|
|
std::string Explanation = "";
|
|
|
|
StringRef Separator = "";
|
|
|
|
for (const auto &P : N->getPredicateFns()) {
|
|
|
|
Explanation +=
|
|
|
|
(Separator + P.getOrigPatFragRecord()->getRecord()->getName()).str();
|
|
|
|
if (P.isAlwaysTrue())
|
|
|
|
Explanation += " always-true";
|
|
|
|
if (P.isImmediatePattern())
|
|
|
|
Explanation += " immediate";
|
|
|
|
}
|
|
|
|
return Explanation;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string explainOperator(Record *Operator) {
|
|
|
|
if (Operator->isSubClassOf("SDNode"))
|
2017-06-01 03:01:11 +08:00
|
|
|
return (" (" + Operator->getValueAsString("Opcode") + ")").str();
|
2017-04-13 17:45:37 +08:00
|
|
|
|
|
|
|
if (Operator->isSubClassOf("Intrinsic"))
|
|
|
|
return (" (Operator is an Intrinsic, " + Operator->getName() + ")").str();
|
|
|
|
|
|
|
|
return " (Operator not understood)";
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Helper function to let the emitter report skip reason error messages.
|
|
|
|
static Error failedImport(const Twine &Reason) {
|
|
|
|
return make_error<StringError>(Reason, inconvertibleErrorCode());
|
|
|
|
}
|
|
|
|
|
|
|
|
static Error isTrivialOperatorNode(const TreePatternNode *N) {
|
|
|
|
std::string Explanation = "";
|
|
|
|
std::string Separator = "";
|
|
|
|
if (N->isLeaf()) {
|
2017-05-24 04:02:48 +08:00
|
|
|
if (isa<IntInit>(N->getLeafValue()))
|
2017-05-24 03:33:16 +08:00
|
|
|
return Error::success();
|
|
|
|
|
2017-04-13 17:45:37 +08:00
|
|
|
Explanation = "Is a leaf";
|
|
|
|
Separator = ", ";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (N->hasAnyPredicate()) {
|
|
|
|
Explanation = Separator + "Has a predicate (" + explainPredicates(N) + ")";
|
|
|
|
Separator = ", ";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (N->getTransformFn()) {
|
|
|
|
Explanation += Separator + "Has a transform function";
|
|
|
|
Separator = ", ";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!N->isLeaf() && !N->hasAnyPredicate() && !N->getTransformFn())
|
|
|
|
return Error::success();
|
|
|
|
|
|
|
|
return failedImport(Explanation);
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
|
|
|
|
2017-06-20 20:36:34 +08:00
|
|
|
static Record *getInitValueAsRegClass(Init *V) {
|
|
|
|
if (DefInit *VDefInit = dyn_cast<DefInit>(V)) {
|
|
|
|
if (VDefInit->getDef()->isSubClassOf("RegisterOperand"))
|
|
|
|
return VDefInit->getDef()->getValueAsDef("RegClass");
|
|
|
|
if (VDefInit->getDef()->isSubClassOf("RegisterClass"))
|
|
|
|
return VDefInit->getDef();
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
std::string
|
|
|
|
getNameForFeatureBitset(const std::vector<Record *> &FeatureBitset) {
|
|
|
|
std::string Name = "GIFBS";
|
|
|
|
for (const auto &Feature : FeatureBitset)
|
|
|
|
Name += ("_" + Feature->getName()).str();
|
|
|
|
return Name;
|
|
|
|
}
|
2017-07-20 17:25:44 +08:00
|
|
|
|
|
|
|
//===- MatchTable Helpers -------------------------------------------------===//
|
|
|
|
|
|
|
|
class MatchTable;
|
|
|
|
|
|
|
|
/// A record to be stored in a MatchTable.
|
|
|
|
///
|
|
|
|
/// This class represents any and all output that may be required to emit the
|
|
|
|
/// MatchTable. Instances are most often configured to represent an opcode or
|
|
|
|
/// value that will be emitted to the table with some formatting but it can also
|
|
|
|
/// represent commas, comments, and other formatting instructions.
|
|
|
|
struct MatchTableRecord {
|
|
|
|
enum RecordFlagsBits {
|
|
|
|
MTRF_None = 0x0,
|
|
|
|
/// Causes EmitStr to be formatted as comment when emitted.
|
|
|
|
MTRF_Comment = 0x1,
|
|
|
|
/// Causes the record value to be followed by a comma when emitted.
|
|
|
|
MTRF_CommaFollows = 0x2,
|
|
|
|
/// Causes the record value to be followed by a line break when emitted.
|
|
|
|
MTRF_LineBreakFollows = 0x4,
|
|
|
|
/// Indicates that the record defines a label and causes an additional
|
|
|
|
/// comment to be emitted containing the index of the label.
|
|
|
|
MTRF_Label = 0x8,
|
|
|
|
/// Causes the record to be emitted as the index of the label specified by
|
|
|
|
/// LabelID along with a comment indicating where that label is.
|
|
|
|
MTRF_JumpTarget = 0x10,
|
|
|
|
/// Causes the formatter to add a level of indentation before emitting the
|
|
|
|
/// record.
|
|
|
|
MTRF_Indent = 0x20,
|
|
|
|
/// Causes the formatter to remove a level of indentation after emitting the
|
|
|
|
/// record.
|
|
|
|
MTRF_Outdent = 0x40,
|
|
|
|
};
|
|
|
|
|
|
|
|
/// When MTRF_Label or MTRF_JumpTarget is used, indicates a label id to
|
|
|
|
/// reference or define.
|
|
|
|
unsigned LabelID;
|
|
|
|
/// The string to emit. Depending on the MTRF_* flags it may be a comment, a
|
|
|
|
/// value, a label name.
|
|
|
|
std::string EmitStr;
|
|
|
|
|
|
|
|
private:
|
|
|
|
/// The number of MatchTable elements described by this record. Comments are 0
|
|
|
|
/// while values are typically 1. Values >1 may occur when we need to emit
|
|
|
|
/// values that exceed the size of a MatchTable element.
|
|
|
|
unsigned NumElements;
|
|
|
|
|
|
|
|
public:
|
|
|
|
/// A bitfield of RecordFlagsBits flags.
|
|
|
|
unsigned Flags;
|
|
|
|
|
|
|
|
MatchTableRecord(Optional<unsigned> LabelID_, StringRef EmitStr,
|
|
|
|
unsigned NumElements, unsigned Flags)
|
|
|
|
: LabelID(LabelID_.hasValue() ? LabelID_.getValue() : ~0u),
|
|
|
|
EmitStr(EmitStr), NumElements(NumElements), Flags(Flags) {
|
|
|
|
assert((!LabelID_.hasValue() || LabelID != ~0u) &&
|
|
|
|
"This value is reserved for non-labels");
|
|
|
|
}
|
|
|
|
|
|
|
|
void emit(raw_ostream &OS, bool LineBreakNextAfterThis,
|
|
|
|
const MatchTable &Table) const;
|
|
|
|
unsigned size() const { return NumElements; }
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Holds the contents of a generated MatchTable to enable formatting and the
|
|
|
|
/// necessary index tracking needed to support GIM_Try.
|
|
|
|
class MatchTable {
|
|
|
|
/// An unique identifier for the table. The generated table will be named
|
|
|
|
/// MatchTable${ID}.
|
|
|
|
unsigned ID;
|
|
|
|
/// The records that make up the table. Also includes comments describing the
|
|
|
|
/// values being emitted and line breaks to format it.
|
|
|
|
std::vector<MatchTableRecord> Contents;
|
|
|
|
/// The currently defined labels.
|
|
|
|
DenseMap<unsigned, unsigned> LabelMap;
|
|
|
|
/// Tracks the sum of MatchTableRecord::NumElements as the table is built.
|
|
|
|
unsigned CurrentSize;
|
|
|
|
|
2017-07-27 19:03:45 +08:00
|
|
|
/// A unique identifier for a MatchTable label.
|
|
|
|
static unsigned CurrentLabelID;
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
public:
|
|
|
|
static MatchTableRecord LineBreak;
|
|
|
|
static MatchTableRecord Comment(StringRef Comment) {
|
|
|
|
return MatchTableRecord(None, Comment, 0, MatchTableRecord::MTRF_Comment);
|
|
|
|
}
|
|
|
|
static MatchTableRecord Opcode(StringRef Opcode, int IndentAdjust = 0) {
|
|
|
|
unsigned ExtraFlags = 0;
|
|
|
|
if (IndentAdjust > 0)
|
|
|
|
ExtraFlags |= MatchTableRecord::MTRF_Indent;
|
|
|
|
if (IndentAdjust < 0)
|
|
|
|
ExtraFlags |= MatchTableRecord::MTRF_Outdent;
|
|
|
|
|
|
|
|
return MatchTableRecord(None, Opcode, 1,
|
|
|
|
MatchTableRecord::MTRF_CommaFollows | ExtraFlags);
|
|
|
|
}
|
|
|
|
static MatchTableRecord NamedValue(StringRef NamedValue) {
|
|
|
|
return MatchTableRecord(None, NamedValue, 1,
|
|
|
|
MatchTableRecord::MTRF_CommaFollows);
|
|
|
|
}
|
|
|
|
static MatchTableRecord NamedValue(StringRef Namespace,
|
|
|
|
StringRef NamedValue) {
|
|
|
|
return MatchTableRecord(None, (Namespace + "::" + NamedValue).str(), 1,
|
|
|
|
MatchTableRecord::MTRF_CommaFollows);
|
|
|
|
}
|
|
|
|
static MatchTableRecord IntValue(int64_t IntValue) {
|
|
|
|
return MatchTableRecord(None, llvm::to_string(IntValue), 1,
|
|
|
|
MatchTableRecord::MTRF_CommaFollows);
|
|
|
|
}
|
|
|
|
static MatchTableRecord Label(unsigned LabelID) {
|
|
|
|
return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 0,
|
|
|
|
MatchTableRecord::MTRF_Label |
|
|
|
|
MatchTableRecord::MTRF_Comment |
|
|
|
|
MatchTableRecord::MTRF_LineBreakFollows);
|
|
|
|
}
|
|
|
|
static MatchTableRecord JumpTarget(unsigned LabelID) {
|
2017-07-27 19:03:45 +08:00
|
|
|
return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 1,
|
2017-07-20 17:25:44 +08:00
|
|
|
MatchTableRecord::MTRF_JumpTarget |
|
|
|
|
MatchTableRecord::MTRF_Comment |
|
|
|
|
MatchTableRecord::MTRF_CommaFollows);
|
|
|
|
}
|
|
|
|
|
|
|
|
MatchTable(unsigned ID) : ID(ID), CurrentSize(0) {}
|
|
|
|
|
|
|
|
void push_back(const MatchTableRecord &Value) {
|
|
|
|
if (Value.Flags & MatchTableRecord::MTRF_Label)
|
|
|
|
defineLabel(Value.LabelID);
|
|
|
|
Contents.push_back(Value);
|
|
|
|
CurrentSize += Value.size();
|
|
|
|
}
|
|
|
|
|
2017-07-27 19:03:45 +08:00
|
|
|
unsigned allocateLabelID() const { return CurrentLabelID++; }
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void defineLabel(unsigned LabelID) {
|
2017-07-27 19:03:45 +08:00
|
|
|
LabelMap.insert(std::make_pair(LabelID, CurrentSize));
|
2017-07-20 17:25:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned getLabelIndex(unsigned LabelID) const {
|
|
|
|
const auto I = LabelMap.find(LabelID);
|
|
|
|
assert(I != LabelMap.end() && "Use of undeclared label");
|
|
|
|
return I->second;
|
|
|
|
}
|
|
|
|
|
2017-07-27 19:03:45 +08:00
|
|
|
void emitUse(raw_ostream &OS) const { OS << "MatchTable" << ID; }
|
|
|
|
|
|
|
|
void emitDeclaration(raw_ostream &OS) const {
|
2017-07-20 17:25:44 +08:00
|
|
|
unsigned Indentation = 4;
|
2017-07-27 20:47:31 +08:00
|
|
|
OS << " constexpr static int64_t MatchTable" << ID << "[] = {";
|
2017-07-20 17:25:44 +08:00
|
|
|
LineBreak.emit(OS, true, *this);
|
|
|
|
OS << std::string(Indentation, ' ');
|
|
|
|
|
|
|
|
for (auto I = Contents.begin(), E = Contents.end(); I != E;
|
|
|
|
++I) {
|
|
|
|
bool LineBreakIsNext = false;
|
|
|
|
const auto &NextI = std::next(I);
|
|
|
|
|
|
|
|
if (NextI != E) {
|
|
|
|
if (NextI->EmitStr == "" &&
|
|
|
|
NextI->Flags == MatchTableRecord::MTRF_LineBreakFollows)
|
|
|
|
LineBreakIsNext = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (I->Flags & MatchTableRecord::MTRF_Indent)
|
|
|
|
Indentation += 2;
|
|
|
|
|
|
|
|
I->emit(OS, LineBreakIsNext, *this);
|
|
|
|
if (I->Flags & MatchTableRecord::MTRF_LineBreakFollows)
|
|
|
|
OS << std::string(Indentation, ' ');
|
|
|
|
|
|
|
|
if (I->Flags & MatchTableRecord::MTRF_Outdent)
|
|
|
|
Indentation -= 2;
|
|
|
|
}
|
|
|
|
OS << "};\n";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-07-27 19:03:45 +08:00
|
|
|
unsigned MatchTable::CurrentLabelID = 0;
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
MatchTableRecord MatchTable::LineBreak = {
|
|
|
|
None, "" /* Emit String */, 0 /* Elements */,
|
|
|
|
MatchTableRecord::MTRF_LineBreakFollows};
|
|
|
|
|
|
|
|
void MatchTableRecord::emit(raw_ostream &OS, bool LineBreakIsNextAfterThis,
|
|
|
|
const MatchTable &Table) const {
|
|
|
|
bool UseLineComment =
|
|
|
|
LineBreakIsNextAfterThis | (Flags & MTRF_LineBreakFollows);
|
|
|
|
if (Flags & (MTRF_JumpTarget | MTRF_CommaFollows))
|
|
|
|
UseLineComment = false;
|
|
|
|
|
|
|
|
if (Flags & MTRF_Comment)
|
|
|
|
OS << (UseLineComment ? "// " : "/*");
|
|
|
|
|
|
|
|
OS << EmitStr;
|
|
|
|
if (Flags & MTRF_Label)
|
|
|
|
OS << ": @" << Table.getLabelIndex(LabelID);
|
|
|
|
|
|
|
|
if (Flags & MTRF_Comment && !UseLineComment)
|
|
|
|
OS << "*/";
|
|
|
|
|
|
|
|
if (Flags & MTRF_JumpTarget) {
|
|
|
|
if (Flags & MTRF_Comment)
|
|
|
|
OS << " ";
|
|
|
|
OS << Table.getLabelIndex(LabelID);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Flags & MTRF_CommaFollows) {
|
|
|
|
OS << ",";
|
|
|
|
if (!LineBreakIsNextAfterThis && !(Flags & MTRF_LineBreakFollows))
|
|
|
|
OS << " ";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Flags & MTRF_LineBreakFollows)
|
|
|
|
OS << "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
MatchTable &operator<<(MatchTable &Table, const MatchTableRecord &Value) {
|
|
|
|
Table.push_back(Value);
|
|
|
|
return Table;
|
|
|
|
}
|
|
|
|
|
2016-12-22 07:26:20 +08:00
|
|
|
//===- Matchers -----------------------------------------------------------===//
|
|
|
|
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
class OperandMatcher;
|
2017-03-16 04:18:38 +08:00
|
|
|
class MatchAction;
|
|
|
|
|
|
|
|
/// Generates code to check that a match rule matches.
|
|
|
|
class RuleMatcher {
|
|
|
|
/// A list of matchers that all need to succeed for the current rule to match.
|
|
|
|
/// FIXME: This currently supports a single match position but could be
|
|
|
|
/// extended to support multiple positions to support div/rem fusion or
|
|
|
|
/// load-multiple instructions.
|
|
|
|
std::vector<std::unique_ptr<InstructionMatcher>> Matchers;
|
|
|
|
|
|
|
|
/// A list of actions that need to be taken when all predicates in this rule
|
|
|
|
/// have succeeded.
|
|
|
|
std::vector<std::unique_ptr<MatchAction>> Actions;
|
|
|
|
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
/// A map of instruction matchers to the local variables created by
|
2017-07-06 18:06:12 +08:00
|
|
|
/// emitCaptureOpcodes().
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
std::map<const InstructionMatcher *, unsigned> InsnVariableIDs;
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
|
|
|
|
/// ID for the next instruction variable defined with defineInsnVar()
|
|
|
|
unsigned NextInsnVarID;
|
|
|
|
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
std::vector<Record *> RequiredFeatures;
|
|
|
|
|
2017-03-16 04:18:38 +08:00
|
|
|
public:
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
RuleMatcher()
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
: Matchers(), Actions(), InsnVariableIDs(), NextInsnVarID(0) {}
|
2017-03-21 03:56:52 +08:00
|
|
|
RuleMatcher(RuleMatcher &&Other) = default;
|
|
|
|
RuleMatcher &operator=(RuleMatcher &&Other) = default;
|
2017-03-16 04:18:38 +08:00
|
|
|
|
|
|
|
InstructionMatcher &addInstructionMatcher();
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
void addRequiredFeature(Record *Feature);
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
const std::vector<Record *> &getRequiredFeatures() const;
|
2017-03-16 04:18:38 +08:00
|
|
|
|
|
|
|
template <class Kind, class... Args> Kind &addAction(Args &&... args);
|
|
|
|
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
/// Define an instruction without emitting any code to do so.
|
|
|
|
/// This is used for the root of the match.
|
|
|
|
unsigned implicitlyDefineInsnVar(const InstructionMatcher &Matcher);
|
|
|
|
/// Define an instruction and emit corresponding state-machine opcodes.
|
2017-07-20 17:25:44 +08:00
|
|
|
unsigned defineInsnVar(MatchTable &Table, const InstructionMatcher &Matcher,
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
unsigned InsnVarID, unsigned OpIdx);
|
|
|
|
unsigned getInsnVarID(const InstructionMatcher &InsnMatcher) const;
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitCaptureOpcodes(MatchTable &Table);
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
|
2017-07-27 19:03:45 +08:00
|
|
|
void emit(MatchTable &Table);
|
2017-03-16 04:18:38 +08:00
|
|
|
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
/// Compare the priority of this object and B.
|
|
|
|
///
|
|
|
|
/// Returns true if this object is more important than B.
|
|
|
|
bool isHigherPriorityThan(const RuleMatcher &B) const;
|
2017-03-16 04:18:38 +08:00
|
|
|
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
/// Report the maximum number of temporary operands needed by the rule
|
|
|
|
/// matcher.
|
|
|
|
unsigned countRendererFns() const;
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
// FIXME: Remove this as soon as possible
|
|
|
|
InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); }
|
2017-03-16 04:18:38 +08:00
|
|
|
};
|
|
|
|
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
template <class PredicateTy> class PredicateListMatcher {
|
|
|
|
private:
|
|
|
|
typedef std::vector<std::unique_ptr<PredicateTy>> PredicateVec;
|
|
|
|
PredicateVec Predicates;
|
2016-12-22 07:26:20 +08:00
|
|
|
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
public:
|
|
|
|
/// Construct a new operand predicate and add it to the matcher.
|
|
|
|
template <class Kind, class... Args>
|
|
|
|
Kind &addPredicate(Args&&... args) {
|
2017-01-27 06:07:37 +08:00
|
|
|
Predicates.emplace_back(
|
|
|
|
llvm::make_unique<Kind>(std::forward<Args>(args)...));
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
return *static_cast<Kind *>(Predicates.back().get());
|
|
|
|
}
|
|
|
|
|
2017-06-28 21:50:04 +08:00
|
|
|
typename PredicateVec::const_iterator predicates_begin() const {
|
|
|
|
return Predicates.begin();
|
|
|
|
}
|
|
|
|
typename PredicateVec::const_iterator predicates_end() const {
|
|
|
|
return Predicates.end();
|
|
|
|
}
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
iterator_range<typename PredicateVec::const_iterator> predicates() const {
|
|
|
|
return make_range(predicates_begin(), predicates_end());
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
2017-06-28 21:50:04 +08:00
|
|
|
typename PredicateVec::size_type predicates_size() const {
|
|
|
|
return Predicates.size();
|
|
|
|
}
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
|
2017-07-06 18:06:12 +08:00
|
|
|
/// Emit MatchTable opcodes that tests whether all the predicates are met.
|
2017-01-27 06:07:37 +08:00
|
|
|
template <class... Args>
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitPredicateListOpcodes(MatchTable &Table, Args &&... args) const {
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
if (Predicates.empty()) {
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Comment("No predicates") << MatchTable::LineBreak;
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
for (const auto &Predicate : predicates())
|
2017-07-20 17:25:44 +08:00
|
|
|
Predicate->emitPredicateOpcodes(Table, std::forward<Args>(args)...);
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
}
|
2016-12-22 07:26:20 +08:00
|
|
|
};
|
|
|
|
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
/// Generates code to check a predicate of an operand.
|
|
|
|
///
|
|
|
|
/// Typical predicates include:
|
|
|
|
/// * Operand is a particular register.
|
|
|
|
/// * Operand is assigned a particular register bank.
|
|
|
|
/// * Operand is an MBB.
|
|
|
|
class OperandPredicateMatcher {
|
|
|
|
public:
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
/// This enum is used for RTTI and also defines the priority that is given to
|
|
|
|
/// the predicate when generating the matcher code. Kinds with higher priority
|
|
|
|
/// must be tested first.
|
|
|
|
///
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
/// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
|
|
|
|
/// but OPM_Int must have priority over OPM_RegBank since constant integers
|
|
|
|
/// are represented by a virtual register defined by a G_CONSTANT instruction.
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
enum PredicateKind {
|
2017-03-15 05:32:08 +08:00
|
|
|
OPM_ComplexPattern,
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
OPM_Instruction,
|
2017-07-11 16:57:29 +08:00
|
|
|
OPM_IntrinsicID,
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
OPM_Int,
|
2017-05-24 03:33:16 +08:00
|
|
|
OPM_LiteralInt,
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
OPM_LLT,
|
|
|
|
OPM_RegBank,
|
|
|
|
OPM_MBB,
|
|
|
|
};
|
|
|
|
|
|
|
|
protected:
|
|
|
|
PredicateKind Kind;
|
|
|
|
|
|
|
|
public:
|
|
|
|
OperandPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
virtual ~OperandPredicateMatcher() {}
|
|
|
|
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
PredicateKind getKind() const { return Kind; }
|
|
|
|
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
/// Return the OperandMatcher for the specified operand or nullptr if there
|
|
|
|
/// isn't one by that name in this operand predicate matcher.
|
|
|
|
///
|
|
|
|
/// InstructionOperandMatcher is the only subclass that can return non-null
|
|
|
|
/// for this.
|
|
|
|
virtual Optional<const OperandMatcher *>
|
2017-04-04 21:52:00 +08:00
|
|
|
getOptionalOperand(StringRef SymbolicName) const {
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
assert(!SymbolicName.empty() && "Cannot lookup unnamed operand");
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2017-07-06 18:06:12 +08:00
|
|
|
/// Emit MatchTable opcodes to capture instructions into the MIs table.
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
///
|
2017-07-06 18:06:12 +08:00
|
|
|
/// Only InstructionOperandMatcher needs to do anything for this method the
|
|
|
|
/// rest just walk the tree.
|
2017-07-20 17:25:44 +08:00
|
|
|
virtual void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
2017-07-06 18:06:12 +08:00
|
|
|
unsigned InsnVarID, unsigned OpIdx) const {}
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
|
2017-07-06 18:06:12 +08:00
|
|
|
/// Emit MatchTable opcodes that check the predicate for the given operand.
|
2017-07-20 17:25:44 +08:00
|
|
|
virtual void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
unsigned InsnVarID,
|
|
|
|
unsigned OpIdx) const = 0;
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
|
|
|
|
/// Compare the priority of this object and B.
|
|
|
|
///
|
|
|
|
/// Returns true if this object is more important than B.
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
virtual bool isHigherPriorityThan(const OperandPredicateMatcher &B) const {
|
|
|
|
return Kind < B.Kind;
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
};
|
2017-03-15 05:32:08 +08:00
|
|
|
|
|
|
|
/// Report the maximum number of temporary operands needed by the predicate
|
|
|
|
/// matcher.
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
virtual unsigned countRendererFns() const { return 0; }
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Generates code to check that an operand is a particular LLT.
|
|
|
|
class LLTOperandMatcher : public OperandPredicateMatcher {
|
|
|
|
protected:
|
Recommit: [globalisel] Change LLT constructor string into an LLT-based object that knows how to generate it.
Summary:
This will allow future patches to inspect the details of the LLT. The implementation is now split between
the Support and CodeGen libraries to allow TableGen to use this class without introducing layering concerns.
Thanks to Ahmed Bougacha for finding a reasonable way to avoid the layering issue and providing the version of this patch without that problem.
The problem with the previous commit appears to have been that TableGen was including CodeGen/LowLevelType.h instead of Support/LowLevelTypeImpl.h.
Reviewers: t.p.northover, qcolombet, rovka, aditya_nandakumar, ab, javed.absar
Subscribers: arsenm, nhaehnle, mgorny, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30046
llvm-svn: 297241
2017-03-08 07:20:35 +08:00
|
|
|
LLTCodeGen Ty;
|
2016-12-22 07:26:20 +08:00
|
|
|
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
public:
|
Recommit: [globalisel] Change LLT constructor string into an LLT-based object that knows how to generate it.
Summary:
This will allow future patches to inspect the details of the LLT. The implementation is now split between
the Support and CodeGen libraries to allow TableGen to use this class without introducing layering concerns.
Thanks to Ahmed Bougacha for finding a reasonable way to avoid the layering issue and providing the version of this patch without that problem.
The problem with the previous commit appears to have been that TableGen was including CodeGen/LowLevelType.h instead of Support/LowLevelTypeImpl.h.
Reviewers: t.p.northover, qcolombet, rovka, aditya_nandakumar, ab, javed.absar
Subscribers: arsenm, nhaehnle, mgorny, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30046
llvm-svn: 297241
2017-03-08 07:20:35 +08:00
|
|
|
LLTOperandMatcher(const LLTCodeGen &Ty)
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
: OperandPredicateMatcher(OPM_LLT), Ty(Ty) {}
|
|
|
|
|
|
|
|
static bool classof(const OperandPredicateMatcher *P) {
|
|
|
|
return P->getKind() == OPM_LLT;
|
|
|
|
}
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
unsigned InsnVarID, unsigned OpIdx) const override {
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIM_CheckType") << MatchTable::Comment("MI")
|
|
|
|
<< MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
|
|
|
|
<< MatchTable::IntValue(OpIdx) << MatchTable::Comment("Type")
|
|
|
|
<< MatchTable::NamedValue(Ty.getCxxEnumValue())
|
|
|
|
<< MatchTable::LineBreak;
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-03-15 05:32:08 +08:00
|
|
|
/// Generates code to check that an operand is a particular target constant.
|
|
|
|
class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
|
|
|
|
protected:
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
const OperandMatcher &Operand;
|
2017-03-15 05:32:08 +08:00
|
|
|
const Record &TheDef;
|
|
|
|
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
unsigned getAllocatedTemporariesBaseID() const;
|
|
|
|
|
2017-03-15 05:32:08 +08:00
|
|
|
public:
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
ComplexPatternOperandMatcher(const OperandMatcher &Operand,
|
|
|
|
const Record &TheDef)
|
|
|
|
: OperandPredicateMatcher(OPM_ComplexPattern), Operand(Operand),
|
|
|
|
TheDef(TheDef) {}
|
|
|
|
|
|
|
|
static bool classof(const OperandPredicateMatcher *P) {
|
|
|
|
return P->getKind() == OPM_ComplexPattern;
|
|
|
|
}
|
2017-03-15 05:32:08 +08:00
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
unsigned InsnVarID, unsigned OpIdx) const override {
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
unsigned ID = getAllocatedTemporariesBaseID();
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIM_CheckComplexPattern")
|
|
|
|
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
|
|
|
|
<< MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
|
|
|
|
<< MatchTable::Comment("Renderer") << MatchTable::IntValue(ID)
|
|
|
|
<< MatchTable::NamedValue(("GICP_" + TheDef.getName()).str())
|
|
|
|
<< MatchTable::LineBreak;
|
2017-03-15 05:32:08 +08:00
|
|
|
}
|
|
|
|
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
unsigned countRendererFns() const override {
|
|
|
|
return 1;
|
2017-03-15 05:32:08 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
/// Generates code to check that an operand is in a particular register bank.
|
|
|
|
class RegisterBankOperandMatcher : public OperandPredicateMatcher {
|
|
|
|
protected:
|
2016-12-22 07:26:20 +08:00
|
|
|
const CodeGenRegisterClass &RC;
|
|
|
|
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
public:
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
RegisterBankOperandMatcher(const CodeGenRegisterClass &RC)
|
|
|
|
: OperandPredicateMatcher(OPM_RegBank), RC(RC) {}
|
|
|
|
|
|
|
|
static bool classof(const OperandPredicateMatcher *P) {
|
|
|
|
return P->getKind() == OPM_RegBank;
|
|
|
|
}
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
unsigned InsnVarID, unsigned OpIdx) const override {
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIM_CheckRegBankForClass")
|
|
|
|
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
|
|
|
|
<< MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
|
|
|
|
<< MatchTable::Comment("RC")
|
|
|
|
<< MatchTable::NamedValue(RC.getQualifiedName() + "RegClassID")
|
|
|
|
<< MatchTable::LineBreak;
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
/// Generates code to check that an operand is a basic block.
|
|
|
|
class MBBOperandMatcher : public OperandPredicateMatcher {
|
|
|
|
public:
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
MBBOperandMatcher() : OperandPredicateMatcher(OPM_MBB) {}
|
|
|
|
|
|
|
|
static bool classof(const OperandPredicateMatcher *P) {
|
|
|
|
return P->getKind() == OPM_MBB;
|
|
|
|
}
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
unsigned InsnVarID, unsigned OpIdx) const override {
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIM_CheckIsMBB") << MatchTable::Comment("MI")
|
|
|
|
<< MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
|
|
|
|
<< MatchTable::IntValue(OpIdx) << MatchTable::LineBreak;
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-05-24 03:33:16 +08:00
|
|
|
/// Generates code to check that an operand is a G_CONSTANT with a particular
|
|
|
|
/// int.
|
|
|
|
class ConstantIntOperandMatcher : public OperandPredicateMatcher {
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
protected:
|
|
|
|
int64_t Value;
|
|
|
|
|
|
|
|
public:
|
2017-05-24 03:33:16 +08:00
|
|
|
ConstantIntOperandMatcher(int64_t Value)
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
: OperandPredicateMatcher(OPM_Int), Value(Value) {}
|
|
|
|
|
|
|
|
static bool classof(const OperandPredicateMatcher *P) {
|
|
|
|
return P->getKind() == OPM_Int;
|
|
|
|
}
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
unsigned InsnVarID, unsigned OpIdx) const override {
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIM_CheckConstantInt")
|
|
|
|
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
|
|
|
|
<< MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
|
|
|
|
<< MatchTable::IntValue(Value) << MatchTable::LineBreak;
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-05-24 03:33:16 +08:00
|
|
|
/// Generates code to check that an operand is a raw int (where MO.isImm() or
|
|
|
|
/// MO.isCImm() is true).
|
|
|
|
class LiteralIntOperandMatcher : public OperandPredicateMatcher {
|
|
|
|
protected:
|
|
|
|
int64_t Value;
|
|
|
|
|
|
|
|
public:
|
|
|
|
LiteralIntOperandMatcher(int64_t Value)
|
|
|
|
: OperandPredicateMatcher(OPM_LiteralInt), Value(Value) {}
|
|
|
|
|
|
|
|
static bool classof(const OperandPredicateMatcher *P) {
|
|
|
|
return P->getKind() == OPM_LiteralInt;
|
|
|
|
}
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
unsigned InsnVarID, unsigned OpIdx) const override {
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIM_CheckLiteralInt")
|
|
|
|
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
|
|
|
|
<< MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
|
|
|
|
<< MatchTable::IntValue(Value) << MatchTable::LineBreak;
|
2017-05-24 03:33:16 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-07-11 16:57:29 +08:00
|
|
|
/// Generates code to check that an operand is an intrinsic ID.
|
|
|
|
class IntrinsicIDOperandMatcher : public OperandPredicateMatcher {
|
|
|
|
protected:
|
|
|
|
const CodeGenIntrinsic *II;
|
|
|
|
|
|
|
|
public:
|
|
|
|
IntrinsicIDOperandMatcher(const CodeGenIntrinsic *II)
|
|
|
|
: OperandPredicateMatcher(OPM_IntrinsicID), II(II) {}
|
|
|
|
|
|
|
|
static bool classof(const OperandPredicateMatcher *P) {
|
|
|
|
return P->getKind() == OPM_IntrinsicID;
|
|
|
|
}
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
2017-07-11 16:57:29 +08:00
|
|
|
unsigned InsnVarID, unsigned OpIdx) const override {
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIM_CheckIntrinsicID")
|
|
|
|
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
|
|
|
|
<< MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
|
|
|
|
<< MatchTable::NamedValue("Intrinsic::" + II->EnumName)
|
|
|
|
<< MatchTable::LineBreak;
|
2017-07-11 16:57:29 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
/// Generates code to check that a set of predicates match for a particular
|
|
|
|
/// operand.
|
|
|
|
class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
|
|
|
|
protected:
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
InstructionMatcher &Insn;
|
2016-12-22 07:26:20 +08:00
|
|
|
unsigned OpIdx;
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
std::string SymbolicName;
|
2016-12-22 07:26:20 +08:00
|
|
|
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
/// The index of the first temporary variable allocated to this operand. The
|
|
|
|
/// number of allocated temporaries can be found with
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
/// countRendererFns().
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
unsigned AllocatedTemporariesBaseID;
|
|
|
|
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
public:
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
OperandMatcher(InstructionMatcher &Insn, unsigned OpIdx,
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
const std::string &SymbolicName,
|
|
|
|
unsigned AllocatedTemporariesBaseID)
|
|
|
|
: Insn(Insn), OpIdx(OpIdx), SymbolicName(SymbolicName),
|
|
|
|
AllocatedTemporariesBaseID(AllocatedTemporariesBaseID) {}
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
|
|
|
bool hasSymbolicName() const { return !SymbolicName.empty(); }
|
|
|
|
const StringRef getSymbolicName() const { return SymbolicName; }
|
2017-03-29 23:37:18 +08:00
|
|
|
void setSymbolicName(StringRef Name) {
|
|
|
|
assert(SymbolicName.empty() && "Operand already has a symbolic name");
|
|
|
|
SymbolicName = Name;
|
|
|
|
}
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
unsigned getOperandIndex() const { return OpIdx; }
|
|
|
|
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
std::string getOperandExpr(unsigned InsnVarID) const {
|
|
|
|
return "State.MIs[" + llvm::to_string(InsnVarID) + "]->getOperand(" +
|
|
|
|
llvm::to_string(OpIdx) + ")";
|
2017-02-20 23:30:43 +08:00
|
|
|
}
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
Optional<const OperandMatcher *>
|
|
|
|
getOptionalOperand(StringRef DesiredSymbolicName) const {
|
|
|
|
assert(!DesiredSymbolicName.empty() && "Cannot lookup unnamed operand");
|
|
|
|
if (DesiredSymbolicName == SymbolicName)
|
|
|
|
return this;
|
|
|
|
for (const auto &OP : predicates()) {
|
|
|
|
const auto &MaybeOperand = OP->getOptionalOperand(DesiredSymbolicName);
|
|
|
|
if (MaybeOperand.hasValue())
|
|
|
|
return MaybeOperand.getValue();
|
|
|
|
}
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
InstructionMatcher &getInstructionMatcher() const { return Insn; }
|
|
|
|
|
2017-07-06 18:06:12 +08:00
|
|
|
/// Emit MatchTable opcodes to capture instructions into the MIs table.
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
2017-07-06 18:06:12 +08:00
|
|
|
unsigned InsnVarID) const {
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
for (const auto &Predicate : predicates())
|
2017-07-20 17:25:44 +08:00
|
|
|
Predicate->emitCaptureOpcodes(Table, Rule, InsnVarID, OpIdx);
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
}
|
|
|
|
|
2017-07-06 18:06:12 +08:00
|
|
|
/// Emit MatchTable opcodes that test whether the instruction named in
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
/// InsnVarID matches all the predicates and all the operands.
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
unsigned InsnVarID) const {
|
2017-07-20 17:25:44 +08:00
|
|
|
std::string Comment;
|
|
|
|
raw_string_ostream CommentOS(Comment);
|
|
|
|
CommentOS << "MIs[" << InsnVarID << "] ";
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
if (SymbolicName.empty())
|
2017-07-20 17:25:44 +08:00
|
|
|
CommentOS << "Operand " << OpIdx;
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
else
|
2017-07-20 17:25:44 +08:00
|
|
|
CommentOS << SymbolicName;
|
|
|
|
Table << MatchTable::Comment(CommentOS.str()) << MatchTable::LineBreak;
|
|
|
|
|
|
|
|
emitPredicateListOpcodes(Table, Rule, InsnVarID, OpIdx);
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
}
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
|
|
|
|
/// Compare the priority of this object and B.
|
|
|
|
///
|
|
|
|
/// Returns true if this object is more important than B.
|
|
|
|
bool isHigherPriorityThan(const OperandMatcher &B) const {
|
|
|
|
// Operand matchers involving more predicates have higher priority.
|
|
|
|
if (predicates_size() > B.predicates_size())
|
|
|
|
return true;
|
|
|
|
if (predicates_size() < B.predicates_size())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// This assumes that predicates are added in a consistent order.
|
|
|
|
for (const auto &Predicate : zip(predicates(), B.predicates())) {
|
|
|
|
if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
|
|
|
|
return true;
|
|
|
|
if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
};
|
2017-03-15 05:32:08 +08:00
|
|
|
|
|
|
|
/// Report the maximum number of temporary operands needed by the operand
|
|
|
|
/// matcher.
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
unsigned countRendererFns() const {
|
2017-03-15 05:32:08 +08:00
|
|
|
return std::accumulate(
|
|
|
|
predicates().begin(), predicates().end(), 0,
|
|
|
|
[](unsigned A,
|
|
|
|
const std::unique_ptr<OperandPredicateMatcher> &Predicate) {
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
return A + Predicate->countRendererFns();
|
2017-03-15 05:32:08 +08:00
|
|
|
});
|
|
|
|
}
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
|
|
|
|
unsigned getAllocatedTemporariesBaseID() const {
|
|
|
|
return AllocatedTemporariesBaseID;
|
|
|
|
}
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
};
|
|
|
|
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
unsigned ComplexPatternOperandMatcher::getAllocatedTemporariesBaseID() const {
|
|
|
|
return Operand.getAllocatedTemporariesBaseID();
|
|
|
|
}
|
|
|
|
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
/// Generates code to check a predicate on an instruction.
|
|
|
|
///
|
|
|
|
/// Typical predicates include:
|
|
|
|
/// * The opcode of the instruction is a particular value.
|
|
|
|
/// * The nsw/nuw flag is/isn't set.
|
|
|
|
class InstructionPredicateMatcher {
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
protected:
|
|
|
|
/// This enum is used for RTTI and also defines the priority that is given to
|
|
|
|
/// the predicate when generating the matcher code. Kinds with higher priority
|
|
|
|
/// must be tested first.
|
|
|
|
enum PredicateKind {
|
|
|
|
IPM_Opcode,
|
|
|
|
};
|
|
|
|
|
|
|
|
PredicateKind Kind;
|
|
|
|
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
public:
|
2017-02-24 22:53:35 +08:00
|
|
|
InstructionPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
virtual ~InstructionPredicateMatcher() {}
|
|
|
|
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
PredicateKind getKind() const { return Kind; }
|
|
|
|
|
2017-07-06 18:06:12 +08:00
|
|
|
/// Emit MatchTable opcodes that test whether the instruction named in
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
/// InsnVarID matches the predicate.
|
2017-07-20 17:25:44 +08:00
|
|
|
virtual void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
unsigned InsnVarID) const = 0;
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
|
|
|
|
/// Compare the priority of this object and B.
|
|
|
|
///
|
|
|
|
/// Returns true if this object is more important than B.
|
2017-06-28 21:50:04 +08:00
|
|
|
virtual bool
|
|
|
|
isHigherPriorityThan(const InstructionPredicateMatcher &B) const {
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
return Kind < B.Kind;
|
|
|
|
};
|
2017-03-15 05:32:08 +08:00
|
|
|
|
|
|
|
/// Report the maximum number of temporary operands needed by the predicate
|
|
|
|
/// matcher.
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
virtual unsigned countRendererFns() const { return 0; }
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Generates code to check the opcode of an instruction.
|
|
|
|
class InstructionOpcodeMatcher : public InstructionPredicateMatcher {
|
|
|
|
protected:
|
|
|
|
const CodeGenInstruction *I;
|
|
|
|
|
|
|
|
public:
|
2017-02-24 22:53:35 +08:00
|
|
|
InstructionOpcodeMatcher(const CodeGenInstruction *I)
|
|
|
|
: InstructionPredicateMatcher(IPM_Opcode), I(I) {}
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
static bool classof(const InstructionPredicateMatcher *P) {
|
|
|
|
return P->getKind() == IPM_Opcode;
|
|
|
|
}
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
unsigned InsnVarID) const override {
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIM_CheckOpcode") << MatchTable::Comment("MI")
|
|
|
|
<< MatchTable::IntValue(InsnVarID)
|
|
|
|
<< MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
|
|
|
|
<< MatchTable::LineBreak;
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
}
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
|
|
|
|
/// Compare the priority of this object and B.
|
|
|
|
///
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
/// Returns true if this object is more important than B.
|
2017-06-28 21:50:04 +08:00
|
|
|
bool
|
|
|
|
isHigherPriorityThan(const InstructionPredicateMatcher &B) const override {
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
if (InstructionPredicateMatcher::isHigherPriorityThan(B))
|
|
|
|
return true;
|
|
|
|
if (B.InstructionPredicateMatcher::isHigherPriorityThan(*this))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Prioritize opcodes for cosmetic reasons in the generated source. Although
|
|
|
|
// this is cosmetic at the moment, we may want to drive a similar ordering
|
|
|
|
// using instruction frequency information to improve compile time.
|
|
|
|
if (const InstructionOpcodeMatcher *BO =
|
|
|
|
dyn_cast<InstructionOpcodeMatcher>(&B))
|
|
|
|
return I->TheDef->getName() < BO->I->TheDef->getName();
|
|
|
|
|
|
|
|
return false;
|
|
|
|
};
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Generates code to check that a set of predicates and operands match for a
|
|
|
|
/// particular instruction.
|
|
|
|
///
|
|
|
|
/// Typical predicates include:
|
|
|
|
/// * Has a specific opcode.
|
|
|
|
/// * Has an nsw/nuw flag or doesn't.
|
|
|
|
class InstructionMatcher
|
|
|
|
: public PredicateListMatcher<InstructionPredicateMatcher> {
|
|
|
|
protected:
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
typedef std::vector<std::unique_ptr<OperandMatcher>> OperandVec;
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
|
|
|
/// The operands to match. All rendered operands must be present even if the
|
|
|
|
/// condition is always true.
|
|
|
|
OperandVec Operands;
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
|
|
|
|
public:
|
|
|
|
/// Add an operand to the matcher.
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName,
|
|
|
|
unsigned AllocatedTemporariesBaseID) {
|
|
|
|
Operands.emplace_back(new OperandMatcher(*this, OpIdx, SymbolicName,
|
|
|
|
AllocatedTemporariesBaseID));
|
|
|
|
return *Operands.back();
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
}
|
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
OperandMatcher &getOperand(unsigned OpIdx) {
|
|
|
|
auto I = std::find_if(Operands.begin(), Operands.end(),
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
[&OpIdx](const std::unique_ptr<OperandMatcher> &X) {
|
|
|
|
return X->getOperandIndex() == OpIdx;
|
2017-03-29 23:37:18 +08:00
|
|
|
});
|
|
|
|
if (I != Operands.end())
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
return **I;
|
2017-03-29 23:37:18 +08:00
|
|
|
llvm_unreachable("Failed to lookup operand");
|
|
|
|
}
|
|
|
|
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
Optional<const OperandMatcher *>
|
|
|
|
getOptionalOperand(StringRef SymbolicName) const {
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
assert(!SymbolicName.empty() && "Cannot lookup unnamed operand");
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
for (const auto &Operand : Operands) {
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
const auto &OM = Operand->getOptionalOperand(SymbolicName);
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
if (OM.hasValue())
|
|
|
|
return OM.getValue();
|
|
|
|
}
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2017-04-04 21:52:00 +08:00
|
|
|
const OperandMatcher &getOperand(StringRef SymbolicName) const {
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
Optional<const OperandMatcher *>OM = getOptionalOperand(SymbolicName);
|
|
|
|
if (OM.hasValue())
|
|
|
|
return *OM.getValue();
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
llvm_unreachable("Failed to lookup operand");
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned getNumOperands() const { return Operands.size(); }
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
OperandVec::iterator operands_begin() { return Operands.begin(); }
|
|
|
|
OperandVec::iterator operands_end() { return Operands.end(); }
|
|
|
|
iterator_range<OperandVec::iterator> operands() {
|
|
|
|
return make_range(operands_begin(), operands_end());
|
|
|
|
}
|
2017-03-29 23:37:18 +08:00
|
|
|
OperandVec::const_iterator operands_begin() const { return Operands.begin(); }
|
|
|
|
OperandVec::const_iterator operands_end() const { return Operands.end(); }
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
iterator_range<OperandVec::const_iterator> operands() const {
|
|
|
|
return make_range(operands_begin(), operands_end());
|
|
|
|
}
|
|
|
|
|
2017-07-06 18:06:12 +08:00
|
|
|
/// Emit MatchTable opcodes to check the shape of the match and capture
|
|
|
|
/// instructions into the MIs table.
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
2017-07-06 18:06:12 +08:00
|
|
|
unsigned InsnID) {
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIM_CheckNumOperands")
|
|
|
|
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnID)
|
|
|
|
<< MatchTable::Comment("Expected")
|
|
|
|
<< MatchTable::IntValue(getNumOperands()) << MatchTable::LineBreak;
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
for (const auto &Operand : Operands)
|
2017-07-20 17:25:44 +08:00
|
|
|
Operand->emitCaptureOpcodes(Table, Rule, InsnID);
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
}
|
|
|
|
|
2017-07-06 18:06:12 +08:00
|
|
|
/// Emit MatchTable opcodes that test whether the instruction named in
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
/// InsnVarName matches all the predicates and all the operands.
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
unsigned InsnVarID) const {
|
2017-07-20 17:25:44 +08:00
|
|
|
emitPredicateListOpcodes(Table, Rule, InsnVarID);
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
for (const auto &Operand : Operands)
|
2017-07-20 17:25:44 +08:00
|
|
|
Operand->emitPredicateOpcodes(Table, Rule, InsnVarID);
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
|
|
|
|
/// Compare the priority of this object and B.
|
|
|
|
///
|
|
|
|
/// Returns true if this object is more important than B.
|
|
|
|
bool isHigherPriorityThan(const InstructionMatcher &B) const {
|
|
|
|
// Instruction matchers involving more operands have higher priority.
|
|
|
|
if (Operands.size() > B.Operands.size())
|
|
|
|
return true;
|
|
|
|
if (Operands.size() < B.Operands.size())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for (const auto &Predicate : zip(predicates(), B.predicates())) {
|
|
|
|
if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
|
|
|
|
return true;
|
|
|
|
if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto &Operand : zip(Operands, B.Operands)) {
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
if (std::get<0>(Operand)->isHigherPriorityThan(*std::get<1>(Operand)))
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
return true;
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
if (std::get<1>(Operand)->isHigherPriorityThan(*std::get<0>(Operand)))
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
};
|
2017-03-15 05:32:08 +08:00
|
|
|
|
|
|
|
/// Report the maximum number of temporary operands needed by the instruction
|
|
|
|
/// matcher.
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
unsigned countRendererFns() const {
|
2017-03-15 05:32:08 +08:00
|
|
|
return std::accumulate(predicates().begin(), predicates().end(), 0,
|
|
|
|
[](unsigned A,
|
|
|
|
const std::unique_ptr<InstructionPredicateMatcher>
|
|
|
|
&Predicate) {
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
return A + Predicate->countRendererFns();
|
2017-03-15 05:32:08 +08:00
|
|
|
}) +
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
std::accumulate(
|
|
|
|
Operands.begin(), Operands.end(), 0,
|
|
|
|
[](unsigned A, const std::unique_ptr<OperandMatcher> &Operand) {
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
return A + Operand->countRendererFns();
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
});
|
2017-03-15 05:32:08 +08:00
|
|
|
}
|
2016-12-22 07:26:20 +08:00
|
|
|
};
|
|
|
|
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
/// Generates code to check that the operand is a register defined by an
|
|
|
|
/// instruction that matches the given instruction matcher.
|
|
|
|
///
|
|
|
|
/// For example, the pattern:
|
|
|
|
/// (set $dst, (G_MUL (G_ADD $src1, $src2), $src3))
|
|
|
|
/// would use an InstructionOperandMatcher for operand 1 of the G_MUL to match
|
|
|
|
/// the:
|
|
|
|
/// (G_ADD $src1, $src2)
|
|
|
|
/// subpattern.
|
|
|
|
class InstructionOperandMatcher : public OperandPredicateMatcher {
|
|
|
|
protected:
|
|
|
|
std::unique_ptr<InstructionMatcher> InsnMatcher;
|
|
|
|
|
|
|
|
public:
|
|
|
|
InstructionOperandMatcher()
|
|
|
|
: OperandPredicateMatcher(OPM_Instruction),
|
|
|
|
InsnMatcher(new InstructionMatcher()) {}
|
|
|
|
|
|
|
|
static bool classof(const OperandPredicateMatcher *P) {
|
|
|
|
return P->getKind() == OPM_Instruction;
|
|
|
|
}
|
|
|
|
|
|
|
|
InstructionMatcher &getInsnMatcher() const { return *InsnMatcher; }
|
|
|
|
|
|
|
|
Optional<const OperandMatcher *>
|
|
|
|
getOptionalOperand(StringRef SymbolicName) const override {
|
|
|
|
assert(!SymbolicName.empty() && "Cannot lookup unnamed operand");
|
|
|
|
return InsnMatcher->getOptionalOperand(SymbolicName);
|
|
|
|
}
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
2017-07-06 18:06:12 +08:00
|
|
|
unsigned InsnID, unsigned OpIdx) const override {
|
2017-07-20 17:25:44 +08:00
|
|
|
unsigned InsnVarID = Rule.defineInsnVar(Table, *InsnMatcher, InsnID, OpIdx);
|
|
|
|
InsnMatcher->emitCaptureOpcodes(Table, Rule, InsnVarID);
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
}
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
unsigned InsnVarID_,
|
|
|
|
unsigned OpIdx_) const override {
|
|
|
|
unsigned InsnVarID = Rule.getInsnVarID(*InsnMatcher);
|
2017-07-20 17:25:44 +08:00
|
|
|
InsnMatcher->emitPredicateOpcodes(Table, Rule, InsnVarID);
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-02-01 18:53:10 +08:00
|
|
|
//===- Actions ------------------------------------------------------------===//
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
class OperandRenderer {
|
|
|
|
public:
|
2017-06-27 18:11:39 +08:00
|
|
|
enum RendererKind {
|
|
|
|
OR_Copy,
|
|
|
|
OR_CopySubReg,
|
|
|
|
OR_Imm,
|
|
|
|
OR_Register,
|
|
|
|
OR_ComplexPattern
|
|
|
|
};
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
|
|
|
protected:
|
|
|
|
RendererKind Kind;
|
|
|
|
|
|
|
|
public:
|
|
|
|
OperandRenderer(RendererKind Kind) : Kind(Kind) {}
|
|
|
|
virtual ~OperandRenderer() {}
|
|
|
|
|
|
|
|
RendererKind getKind() const { return Kind; }
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
virtual void emitRenderOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) const = 0;
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/// A CopyRenderer emits code to copy a single operand from an existing
|
|
|
|
/// instruction to the one being built.
|
|
|
|
class CopyRenderer : public OperandRenderer {
|
|
|
|
protected:
|
2017-07-05 17:39:33 +08:00
|
|
|
unsigned NewInsnID;
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
/// The matcher for the instruction that this operand is copied from.
|
|
|
|
/// This provides the facility for looking up an a operand by it's name so
|
|
|
|
/// that it can be used as a source for the instruction being built.
|
|
|
|
const InstructionMatcher &Matched;
|
|
|
|
/// The name of the operand.
|
|
|
|
const StringRef SymbolicName;
|
|
|
|
|
|
|
|
public:
|
2017-07-05 17:39:33 +08:00
|
|
|
CopyRenderer(unsigned NewInsnID, const InstructionMatcher &Matched,
|
|
|
|
StringRef SymbolicName)
|
|
|
|
: OperandRenderer(OR_Copy), NewInsnID(NewInsnID), Matched(Matched),
|
|
|
|
SymbolicName(SymbolicName) {}
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
|
|
|
static bool classof(const OperandRenderer *R) {
|
|
|
|
return R->getKind() == OR_Copy;
|
|
|
|
}
|
|
|
|
|
|
|
|
const StringRef getSymbolicName() const { return SymbolicName; }
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
const OperandMatcher &Operand = Matched.getOperand(SymbolicName);
|
2017-07-05 17:39:33 +08:00
|
|
|
unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIR_Copy") << MatchTable::Comment("NewInsnID")
|
|
|
|
<< MatchTable::IntValue(NewInsnID) << MatchTable::Comment("OldInsnID")
|
|
|
|
<< MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
|
|
|
|
<< MatchTable::IntValue(Operand.getOperandIndex())
|
|
|
|
<< MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-06-27 18:11:39 +08:00
|
|
|
/// A CopySubRegRenderer emits code to copy a single register operand from an
|
|
|
|
/// existing instruction to the one being built and indicate that only a
|
|
|
|
/// subregister should be copied.
|
|
|
|
class CopySubRegRenderer : public OperandRenderer {
|
|
|
|
protected:
|
2017-07-05 17:39:33 +08:00
|
|
|
unsigned NewInsnID;
|
2017-06-27 18:11:39 +08:00
|
|
|
/// The matcher for the instruction that this operand is copied from.
|
|
|
|
/// This provides the facility for looking up an a operand by it's name so
|
|
|
|
/// that it can be used as a source for the instruction being built.
|
|
|
|
const InstructionMatcher &Matched;
|
|
|
|
/// The name of the operand.
|
|
|
|
const StringRef SymbolicName;
|
|
|
|
/// The subregister to extract.
|
|
|
|
const CodeGenSubRegIndex *SubReg;
|
|
|
|
|
|
|
|
public:
|
2017-07-05 17:39:33 +08:00
|
|
|
CopySubRegRenderer(unsigned NewInsnID, const InstructionMatcher &Matched,
|
|
|
|
StringRef SymbolicName, const CodeGenSubRegIndex *SubReg)
|
|
|
|
: OperandRenderer(OR_CopySubReg), NewInsnID(NewInsnID), Matched(Matched),
|
2017-06-27 18:11:39 +08:00
|
|
|
SymbolicName(SymbolicName), SubReg(SubReg) {}
|
|
|
|
|
|
|
|
static bool classof(const OperandRenderer *R) {
|
|
|
|
return R->getKind() == OR_CopySubReg;
|
|
|
|
}
|
|
|
|
|
|
|
|
const StringRef getSymbolicName() const { return SymbolicName; }
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
|
2017-06-27 18:11:39 +08:00
|
|
|
const OperandMatcher &Operand = Matched.getOperand(SymbolicName);
|
2017-07-05 17:39:33 +08:00
|
|
|
unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIR_CopySubReg")
|
|
|
|
<< MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
|
|
|
|
<< MatchTable::Comment("OldInsnID")
|
|
|
|
<< MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
|
|
|
|
<< MatchTable::IntValue(Operand.getOperandIndex())
|
|
|
|
<< MatchTable::Comment("SubRegIdx")
|
|
|
|
<< MatchTable::IntValue(SubReg->EnumValue)
|
|
|
|
<< MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
|
2017-06-27 18:11:39 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
/// Adds a specific physical register to the instruction being built.
|
|
|
|
/// This is typically useful for WZR/XZR on AArch64.
|
|
|
|
class AddRegisterRenderer : public OperandRenderer {
|
|
|
|
protected:
|
2017-07-05 17:39:33 +08:00
|
|
|
unsigned InsnID;
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
const Record *RegisterDef;
|
|
|
|
|
|
|
|
public:
|
2017-07-05 17:39:33 +08:00
|
|
|
AddRegisterRenderer(unsigned InsnID, const Record *RegisterDef)
|
|
|
|
: OperandRenderer(OR_Register), InsnID(InsnID), RegisterDef(RegisterDef) {
|
|
|
|
}
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
|
|
|
static bool classof(const OperandRenderer *R) {
|
|
|
|
return R->getKind() == OR_Register;
|
|
|
|
}
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
|
|
|
|
Table << MatchTable::Opcode("GIR_AddRegister")
|
|
|
|
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
|
|
|
|
<< MatchTable::NamedValue(
|
|
|
|
(RegisterDef->getValue("Namespace")
|
|
|
|
? RegisterDef->getValueAsString("Namespace")
|
|
|
|
: ""),
|
|
|
|
RegisterDef->getName())
|
|
|
|
<< MatchTable::LineBreak;
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
[globalisel][tablegen] Add experimental support for OperandWithDefaultOps, PredicateOperand, and OptionalDefOperand
Summary:
As far as instruction selection is concerned, all three appear to be same thing.
Support for these operands is experimental since AArch64 doesn't make use
of them and the in-tree targets that do use them (AMDGPU for
OperandWithDefaultOps, AMDGPU/ARM/Hexagon/Lanai for PredicateOperand, and ARM
for OperandWithDefaultOps) are not using tablegen-erated GlobalISel yet.
Reviewers: rovka, aditya_nandakumar, t.p.northover, qcolombet, ab
Reviewed By: rovka
Subscribers: inglorion, aemerson, rengolin, mehdi_amini, dberris, kristof.beyls, igorb, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D31135
llvm-svn: 300037
2017-04-12 16:23:08 +08:00
|
|
|
/// Adds a specific immediate to the instruction being built.
|
|
|
|
class ImmRenderer : public OperandRenderer {
|
|
|
|
protected:
|
2017-07-05 17:39:33 +08:00
|
|
|
unsigned InsnID;
|
[globalisel][tablegen] Add experimental support for OperandWithDefaultOps, PredicateOperand, and OptionalDefOperand
Summary:
As far as instruction selection is concerned, all three appear to be same thing.
Support for these operands is experimental since AArch64 doesn't make use
of them and the in-tree targets that do use them (AMDGPU for
OperandWithDefaultOps, AMDGPU/ARM/Hexagon/Lanai for PredicateOperand, and ARM
for OperandWithDefaultOps) are not using tablegen-erated GlobalISel yet.
Reviewers: rovka, aditya_nandakumar, t.p.northover, qcolombet, ab
Reviewed By: rovka
Subscribers: inglorion, aemerson, rengolin, mehdi_amini, dberris, kristof.beyls, igorb, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D31135
llvm-svn: 300037
2017-04-12 16:23:08 +08:00
|
|
|
int64_t Imm;
|
|
|
|
|
|
|
|
public:
|
2017-07-05 17:39:33 +08:00
|
|
|
ImmRenderer(unsigned InsnID, int64_t Imm)
|
|
|
|
: OperandRenderer(OR_Imm), InsnID(InsnID), Imm(Imm) {}
|
[globalisel][tablegen] Add experimental support for OperandWithDefaultOps, PredicateOperand, and OptionalDefOperand
Summary:
As far as instruction selection is concerned, all three appear to be same thing.
Support for these operands is experimental since AArch64 doesn't make use
of them and the in-tree targets that do use them (AMDGPU for
OperandWithDefaultOps, AMDGPU/ARM/Hexagon/Lanai for PredicateOperand, and ARM
for OperandWithDefaultOps) are not using tablegen-erated GlobalISel yet.
Reviewers: rovka, aditya_nandakumar, t.p.northover, qcolombet, ab
Reviewed By: rovka
Subscribers: inglorion, aemerson, rengolin, mehdi_amini, dberris, kristof.beyls, igorb, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D31135
llvm-svn: 300037
2017-04-12 16:23:08 +08:00
|
|
|
|
|
|
|
static bool classof(const OperandRenderer *R) {
|
|
|
|
return R->getKind() == OR_Imm;
|
|
|
|
}
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
|
|
|
|
Table << MatchTable::Opcode("GIR_AddImm") << MatchTable::Comment("InsnID")
|
|
|
|
<< MatchTable::IntValue(InsnID) << MatchTable::Comment("Imm")
|
|
|
|
<< MatchTable::IntValue(Imm) << MatchTable::LineBreak;
|
[globalisel][tablegen] Add experimental support for OperandWithDefaultOps, PredicateOperand, and OptionalDefOperand
Summary:
As far as instruction selection is concerned, all three appear to be same thing.
Support for these operands is experimental since AArch64 doesn't make use
of them and the in-tree targets that do use them (AMDGPU for
OperandWithDefaultOps, AMDGPU/ARM/Hexagon/Lanai for PredicateOperand, and ARM
for OperandWithDefaultOps) are not using tablegen-erated GlobalISel yet.
Reviewers: rovka, aditya_nandakumar, t.p.northover, qcolombet, ab
Reviewed By: rovka
Subscribers: inglorion, aemerson, rengolin, mehdi_amini, dberris, kristof.beyls, igorb, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D31135
llvm-svn: 300037
2017-04-12 16:23:08 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
/// Adds operands by calling a renderer function supplied by the ComplexPattern
|
|
|
|
/// matcher function.
|
2017-03-15 05:32:08 +08:00
|
|
|
class RenderComplexPatternOperand : public OperandRenderer {
|
|
|
|
private:
|
2017-07-05 17:39:33 +08:00
|
|
|
unsigned InsnID;
|
2017-03-15 05:32:08 +08:00
|
|
|
const Record &TheDef;
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
/// The name of the operand.
|
|
|
|
const StringRef SymbolicName;
|
|
|
|
/// The renderer number. This must be unique within a rule since it's used to
|
|
|
|
/// identify a temporary variable to hold the renderer function.
|
|
|
|
unsigned RendererID;
|
2017-03-15 05:32:08 +08:00
|
|
|
|
|
|
|
unsigned getNumOperands() const {
|
|
|
|
return TheDef.getValueAsDag("Operands")->getNumArgs();
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2017-07-05 17:39:33 +08:00
|
|
|
RenderComplexPatternOperand(unsigned InsnID, const Record &TheDef,
|
|
|
|
StringRef SymbolicName, unsigned RendererID)
|
|
|
|
: OperandRenderer(OR_ComplexPattern), InsnID(InsnID), TheDef(TheDef),
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
SymbolicName(SymbolicName), RendererID(RendererID) {}
|
2017-03-15 05:32:08 +08:00
|
|
|
|
|
|
|
static bool classof(const OperandRenderer *R) {
|
|
|
|
return R->getKind() == OR_ComplexPattern;
|
|
|
|
}
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
|
|
|
|
Table << MatchTable::Opcode("GIR_ComplexRenderer")
|
|
|
|
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
|
|
|
|
<< MatchTable::Comment("RendererID")
|
|
|
|
<< MatchTable::IntValue(RendererID) << MatchTable::LineBreak;
|
2017-03-15 05:32:08 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-02-04 08:47:10 +08:00
|
|
|
/// An action taken when all Matcher predicates succeeded for a parent rule.
|
|
|
|
///
|
|
|
|
/// Typical actions include:
|
|
|
|
/// * Changing the opcode of an instruction.
|
|
|
|
/// * Adding an operand to an instruction.
|
2017-02-01 18:53:10 +08:00
|
|
|
class MatchAction {
|
|
|
|
public:
|
|
|
|
virtual ~MatchAction() {}
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
/// Emit the MatchTable opcodes to implement the action.
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
///
|
2017-07-05 17:39:33 +08:00
|
|
|
/// \param RecycleInsnID If given, it's an instruction to recycle. The
|
|
|
|
/// requirements on the instruction vary from action to
|
|
|
|
/// action.
|
2017-07-20 17:25:44 +08:00
|
|
|
virtual void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
|
|
|
unsigned RecycleInsnID) const = 0;
|
2017-02-01 18:53:10 +08:00
|
|
|
};
|
|
|
|
|
2017-02-04 08:47:08 +08:00
|
|
|
/// Generates a comment describing the matched rule being acted upon.
|
|
|
|
class DebugCommentAction : public MatchAction {
|
|
|
|
private:
|
|
|
|
const PatternToMatch &P;
|
|
|
|
|
|
|
|
public:
|
|
|
|
DebugCommentAction(const PatternToMatch &P) : P(P) {}
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
|
|
|
unsigned RecycleInsnID) const override {
|
|
|
|
Table << MatchTable::Comment(llvm::to_string(*P.getSrcPattern()) + " => " +
|
|
|
|
llvm::to_string(*P.getDstPattern()))
|
|
|
|
<< MatchTable::LineBreak;
|
2017-02-04 08:47:08 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
/// Generates code to build an instruction or mutate an existing instruction
|
|
|
|
/// into the desired instruction when this is possible.
|
|
|
|
class BuildMIAction : public MatchAction {
|
2017-02-01 18:53:10 +08:00
|
|
|
private:
|
2017-07-05 17:39:33 +08:00
|
|
|
unsigned InsnID;
|
2016-12-22 07:26:20 +08:00
|
|
|
const CodeGenInstruction *I;
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
const InstructionMatcher &Matched;
|
|
|
|
std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers;
|
|
|
|
|
|
|
|
/// True if the instruction can be built solely by mutating the opcode.
|
|
|
|
bool canMutate() const {
|
2017-04-30 01:30:09 +08:00
|
|
|
if (OperandRenderers.size() != Matched.getNumOperands())
|
|
|
|
return false;
|
|
|
|
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
for (const auto &Renderer : enumerate(OperandRenderers)) {
|
2017-03-14 00:24:10 +08:00
|
|
|
if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) {
|
2017-04-22 22:31:28 +08:00
|
|
|
const OperandMatcher &OM = Matched.getOperand(Copy->getSymbolicName());
|
|
|
|
if (&Matched != &OM.getInstructionMatcher() ||
|
|
|
|
OM.getOperandIndex() != Renderer.index())
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
return false;
|
|
|
|
} else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2016-12-22 07:26:20 +08:00
|
|
|
|
2017-02-01 18:53:10 +08:00
|
|
|
public:
|
2017-07-05 17:39:33 +08:00
|
|
|
BuildMIAction(unsigned InsnID, const CodeGenInstruction *I,
|
2017-06-20 20:36:34 +08:00
|
|
|
const InstructionMatcher &Matched)
|
2017-07-05 17:39:33 +08:00
|
|
|
: InsnID(InsnID), I(I), Matched(Matched) {}
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
|
|
|
template <class Kind, class... Args>
|
|
|
|
Kind &addRenderer(Args&&... args) {
|
|
|
|
OperandRenderers.emplace_back(
|
|
|
|
llvm::make_unique<Kind>(std::forward<Args>(args)...));
|
|
|
|
return *static_cast<Kind *>(OperandRenderers.back().get());
|
|
|
|
}
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
|
|
|
unsigned RecycleInsnID) const override {
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
if (canMutate()) {
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIR_MutateOpcode")
|
|
|
|
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
|
|
|
|
<< MatchTable::Comment("RecycleInsnID")
|
|
|
|
<< MatchTable::IntValue(RecycleInsnID)
|
|
|
|
<< MatchTable::Comment("Opcode")
|
|
|
|
<< MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
|
|
|
|
<< MatchTable::LineBreak;
|
2017-03-21 05:58:23 +08:00
|
|
|
|
|
|
|
if (!I->ImplicitDefs.empty() || !I->ImplicitUses.empty()) {
|
|
|
|
for (auto Def : I->ImplicitDefs) {
|
2017-05-02 17:40:49 +08:00
|
|
|
auto Namespace = Def->getValue("Namespace")
|
|
|
|
? Def->getValueAsString("Namespace")
|
|
|
|
: "";
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIR_AddImplicitDef")
|
|
|
|
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
|
|
|
|
<< MatchTable::NamedValue(Namespace, Def->getName())
|
|
|
|
<< MatchTable::LineBreak;
|
2017-03-21 05:58:23 +08:00
|
|
|
}
|
|
|
|
for (auto Use : I->ImplicitUses) {
|
2017-05-02 17:40:49 +08:00
|
|
|
auto Namespace = Use->getValue("Namespace")
|
|
|
|
? Use->getValueAsString("Namespace")
|
|
|
|
: "";
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIR_AddImplicitUse")
|
|
|
|
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
|
|
|
|
<< MatchTable::NamedValue(Namespace, Use->getName())
|
|
|
|
<< MatchTable::LineBreak;
|
2017-03-21 05:58:23 +08:00
|
|
|
}
|
|
|
|
}
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
return;
|
|
|
|
}
|
2017-02-01 18:53:10 +08:00
|
|
|
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
// TODO: Simple permutation looks like it could be almost as common as
|
|
|
|
// mutation due to commutative operations.
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIR_BuildMI") << MatchTable::Comment("InsnID")
|
|
|
|
<< MatchTable::IntValue(InsnID) << MatchTable::Comment("Opcode")
|
|
|
|
<< MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
|
|
|
|
<< MatchTable::LineBreak;
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
for (const auto &Renderer : OperandRenderers)
|
2017-07-20 17:25:44 +08:00
|
|
|
Renderer->emitRenderOpcodes(Table, Rule);
|
2017-07-05 17:39:33 +08:00
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIR_MergeMemOperands")
|
|
|
|
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
|
|
|
|
<< MatchTable::LineBreak << MatchTable::Opcode("GIR_EraseFromParent")
|
|
|
|
<< MatchTable::Comment("InsnID")
|
|
|
|
<< MatchTable::IntValue(RecycleInsnID) << MatchTable::LineBreak;
|
2017-06-20 20:36:34 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Generates code to constrain the operands of an output instruction to the
|
|
|
|
/// register classes specified by the definition of that instruction.
|
|
|
|
class ConstrainOperandsToDefinitionAction : public MatchAction {
|
2017-07-05 17:39:33 +08:00
|
|
|
unsigned InsnID;
|
2017-06-20 20:36:34 +08:00
|
|
|
|
|
|
|
public:
|
2017-07-05 17:39:33 +08:00
|
|
|
ConstrainOperandsToDefinitionAction(unsigned InsnID) : InsnID(InsnID) {}
|
2017-06-20 20:36:34 +08:00
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
|
|
|
unsigned RecycleInsnID) const override {
|
|
|
|
Table << MatchTable::Opcode("GIR_ConstrainSelectedInstOperands")
|
|
|
|
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
|
|
|
|
<< MatchTable::LineBreak;
|
2017-06-20 20:36:34 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Generates code to constrain the specified operand of an output instruction
|
|
|
|
/// to the specified register class.
|
|
|
|
class ConstrainOperandToRegClassAction : public MatchAction {
|
2017-07-05 17:39:33 +08:00
|
|
|
unsigned InsnID;
|
2017-06-20 20:36:34 +08:00
|
|
|
unsigned OpIdx;
|
|
|
|
const CodeGenRegisterClass &RC;
|
|
|
|
|
|
|
|
public:
|
2017-07-05 17:39:33 +08:00
|
|
|
ConstrainOperandToRegClassAction(unsigned InsnID, unsigned OpIdx,
|
2017-06-20 20:36:34 +08:00
|
|
|
const CodeGenRegisterClass &RC)
|
2017-07-05 17:39:33 +08:00
|
|
|
: InsnID(InsnID), OpIdx(OpIdx), RC(RC) {}
|
2017-06-20 20:36:34 +08:00
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
|
|
|
|
unsigned RecycleInsnID) const override {
|
|
|
|
Table << MatchTable::Opcode("GIR_ConstrainOperandRC")
|
|
|
|
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
|
|
|
|
<< MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
|
|
|
|
<< MatchTable::Comment("RC " + RC.getName())
|
|
|
|
<< MatchTable::IntValue(RC.EnumValue) << MatchTable::LineBreak;
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-03-16 04:18:38 +08:00
|
|
|
InstructionMatcher &RuleMatcher::addInstructionMatcher() {
|
|
|
|
Matchers.emplace_back(new InstructionMatcher());
|
|
|
|
return *Matchers.back();
|
|
|
|
}
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
void RuleMatcher::addRequiredFeature(Record *Feature) {
|
|
|
|
RequiredFeatures.push_back(Feature);
|
|
|
|
}
|
|
|
|
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
const std::vector<Record *> &RuleMatcher::getRequiredFeatures() const {
|
|
|
|
return RequiredFeatures;
|
|
|
|
}
|
|
|
|
|
2017-03-16 04:18:38 +08:00
|
|
|
template <class Kind, class... Args>
|
|
|
|
Kind &RuleMatcher::addAction(Args &&... args) {
|
|
|
|
Actions.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
|
|
|
|
return *static_cast<Kind *>(Actions.back().get());
|
|
|
|
}
|
2016-12-22 07:26:20 +08:00
|
|
|
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
unsigned
|
|
|
|
RuleMatcher::implicitlyDefineInsnVar(const InstructionMatcher &Matcher) {
|
|
|
|
unsigned NewInsnVarID = NextInsnVarID++;
|
|
|
|
InsnVariableIDs[&Matcher] = NewInsnVarID;
|
|
|
|
return NewInsnVarID;
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
}
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
unsigned RuleMatcher::defineInsnVar(MatchTable &Table,
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
const InstructionMatcher &Matcher,
|
|
|
|
unsigned InsnID, unsigned OpIdx) {
|
|
|
|
unsigned NewInsnVarID = implicitlyDefineInsnVar(Matcher);
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIM_RecordInsn")
|
|
|
|
<< MatchTable::Comment("DefineMI") << MatchTable::IntValue(NewInsnVarID)
|
|
|
|
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnID)
|
|
|
|
<< MatchTable::Comment("OpIdx") << MatchTable::IntValue(OpIdx)
|
|
|
|
<< MatchTable::Comment("MIs[" + llvm::to_string(NewInsnVarID) + "]")
|
|
|
|
<< MatchTable::LineBreak;
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
return NewInsnVarID;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned RuleMatcher::getInsnVarID(const InstructionMatcher &InsnMatcher) const {
|
|
|
|
const auto &I = InsnVariableIDs.find(&InsnMatcher);
|
|
|
|
if (I != InsnVariableIDs.end())
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
return I->second;
|
|
|
|
llvm_unreachable("Matched Insn was not captured in a local variable");
|
|
|
|
}
|
|
|
|
|
2017-07-06 18:06:12 +08:00
|
|
|
/// Emit MatchTable opcodes to check the shape of the match and capture
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
/// instructions into local variables.
|
2017-07-20 17:25:44 +08:00
|
|
|
void RuleMatcher::emitCaptureOpcodes(MatchTable &Table) {
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
unsigned InsnVarID = implicitlyDefineInsnVar(*Matchers.front());
|
2017-07-20 17:25:44 +08:00
|
|
|
Matchers.front()->emitCaptureOpcodes(Table, *this, InsnVarID);
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
}
|
|
|
|
|
2017-07-27 19:03:45 +08:00
|
|
|
void RuleMatcher::emit(MatchTable &Table) {
|
2017-03-16 04:18:38 +08:00
|
|
|
if (Matchers.empty())
|
|
|
|
llvm_unreachable("Unexpected empty matcher!");
|
|
|
|
|
|
|
|
// The representation supports rules that require multiple roots such as:
|
|
|
|
// %ptr(p0) = ...
|
|
|
|
// %elt0(s32) = G_LOAD %ptr
|
|
|
|
// %1(p0) = G_ADD %ptr, 4
|
|
|
|
// %elt1(s32) = G_LOAD p0 %1
|
|
|
|
// which could be usefully folded into:
|
|
|
|
// %ptr(p0) = ...
|
|
|
|
// %elt0(s32), %elt1(s32) = TGT_LOAD_PAIR %ptr
|
|
|
|
// on some targets but we don't need to make use of that yet.
|
|
|
|
assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
|
2017-07-27 19:03:45 +08:00
|
|
|
unsigned LabelID = Table.allocateLabelID();
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIM_Try", +1)
|
2017-07-27 19:03:45 +08:00
|
|
|
<< MatchTable::Comment("On fail goto") << MatchTable::JumpTarget(LabelID)
|
2017-07-20 17:25:44 +08:00
|
|
|
<< MatchTable::LineBreak;
|
|
|
|
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
if (!RequiredFeatures.empty()) {
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIM_CheckFeatures")
|
|
|
|
<< MatchTable::NamedValue(getNameForFeatureBitset(RequiredFeatures))
|
|
|
|
<< MatchTable::LineBreak;
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
}
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
emitCaptureOpcodes(Table);
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
Matchers.front()->emitPredicateOpcodes(Table, *this,
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
getInsnVarID(*Matchers.front()));
|
|
|
|
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
// We must also check if it's safe to fold the matched instructions.
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
if (InsnVariableIDs.size() >= 2) {
|
2017-05-25 09:51:53 +08:00
|
|
|
// Invert the map to create stable ordering (by var names)
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
SmallVector<unsigned, 2> InsnIDs;
|
|
|
|
for (const auto &Pair : InsnVariableIDs) {
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
// Skip the root node since it isn't moving anywhere. Everything else is
|
|
|
|
// sinking to meet it.
|
|
|
|
if (Pair.first == Matchers.front().get())
|
|
|
|
continue;
|
|
|
|
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
InsnIDs.push_back(Pair.second);
|
2017-05-25 09:51:53 +08:00
|
|
|
}
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
std::sort(InsnIDs.begin(), InsnIDs.end());
|
2017-05-25 09:51:53 +08:00
|
|
|
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
for (const auto &InsnID : InsnIDs) {
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
// Reject the difficult cases until we have a more accurate check.
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIM_CheckIsSafeToFold")
|
|
|
|
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
|
|
|
|
<< MatchTable::LineBreak;
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
|
|
|
|
// FIXME: Emit checks to determine it's _actually_ safe to fold and/or
|
|
|
|
// account for unsafe cases.
|
|
|
|
//
|
|
|
|
// Example:
|
|
|
|
// MI1--> %0 = ...
|
|
|
|
// %1 = ... %0
|
|
|
|
// MI0--> %2 = ... %0
|
|
|
|
// It's not safe to erase MI1. We currently handle this by not
|
|
|
|
// erasing %0 (even when it's dead).
|
|
|
|
//
|
|
|
|
// Example:
|
|
|
|
// MI1--> %0 = load volatile @a
|
|
|
|
// %1 = load volatile @a
|
|
|
|
// MI0--> %2 = ... %0
|
|
|
|
// It's not safe to sink %0's def past %1. We currently handle
|
|
|
|
// this by rejecting all loads.
|
|
|
|
//
|
|
|
|
// Example:
|
|
|
|
// MI1--> %0 = load @a
|
|
|
|
// %1 = store @a
|
|
|
|
// MI0--> %2 = ... %0
|
|
|
|
// It's not safe to sink %0's def past %1. We currently handle
|
|
|
|
// this by rejecting all loads.
|
|
|
|
//
|
|
|
|
// Example:
|
|
|
|
// G_CONDBR %cond, @BB1
|
|
|
|
// BB0:
|
|
|
|
// MI1--> %0 = load @a
|
|
|
|
// G_BR @BB1
|
|
|
|
// BB1:
|
|
|
|
// MI0--> %2 = ... %0
|
|
|
|
// It's not always safe to sink %0 across control flow. In this
|
|
|
|
// case it may introduce a memory fault. We currentl handle this
|
|
|
|
// by rejecting all loads.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-05 17:39:33 +08:00
|
|
|
for (const auto &MA : Actions)
|
2017-07-20 17:25:44 +08:00
|
|
|
MA->emitActionOpcodes(Table, *this, 0);
|
|
|
|
Table << MatchTable::Opcode("GIR_Done", -1) << MatchTable::LineBreak
|
2017-07-27 19:03:45 +08:00
|
|
|
<< MatchTable::Label(LabelID);
|
2017-03-16 04:18:38 +08:00
|
|
|
}
|
2016-12-22 07:26:20 +08:00
|
|
|
|
2017-03-16 04:18:38 +08:00
|
|
|
bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const {
|
|
|
|
// Rules involving more match roots have higher priority.
|
|
|
|
if (Matchers.size() > B.Matchers.size())
|
|
|
|
return true;
|
|
|
|
if (Matchers.size() < B.Matchers.size())
|
|
|
|
return false;
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
|
2017-03-16 04:18:38 +08:00
|
|
|
for (const auto &Matcher : zip(Matchers, B.Matchers)) {
|
|
|
|
if (std::get<0>(Matcher)->isHigherPriorityThan(*std::get<1>(Matcher)))
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
return true;
|
2017-03-16 04:18:38 +08:00
|
|
|
if (std::get<1>(Matcher)->isHigherPriorityThan(*std::get<0>(Matcher)))
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
return false;
|
2017-03-15 05:32:08 +08:00
|
|
|
}
|
2017-03-16 04:18:38 +08:00
|
|
|
|
|
|
|
return false;
|
2017-03-16 06:50:47 +08:00
|
|
|
}
|
2016-12-22 07:26:20 +08:00
|
|
|
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
unsigned RuleMatcher::countRendererFns() const {
|
2017-03-16 04:18:38 +08:00
|
|
|
return std::accumulate(
|
|
|
|
Matchers.begin(), Matchers.end(), 0,
|
|
|
|
[](unsigned A, const std::unique_ptr<InstructionMatcher> &Matcher) {
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
return A + Matcher->countRendererFns();
|
2017-03-16 04:18:38 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-12-22 07:26:20 +08:00
|
|
|
//===- GlobalISelEmitter class --------------------------------------------===//
|
|
|
|
|
2017-02-10 12:00:17 +08:00
|
|
|
class GlobalISelEmitter {
|
|
|
|
public:
|
|
|
|
explicit GlobalISelEmitter(RecordKeeper &RK);
|
|
|
|
void run(raw_ostream &OS);
|
|
|
|
|
|
|
|
private:
|
|
|
|
const RecordKeeper &RK;
|
|
|
|
const CodeGenDAGPatterns CGP;
|
|
|
|
const CodeGenTarget &Target;
|
2017-06-27 18:11:39 +08:00
|
|
|
CodeGenRegBank CGRegs;
|
2017-02-10 12:00:17 +08:00
|
|
|
|
|
|
|
/// Keep track of the equivalence between SDNodes and Instruction.
|
|
|
|
/// This is defined using 'GINodeEquiv' in the target description.
|
|
|
|
DenseMap<Record *, const CodeGenInstruction *> NodeEquivs;
|
|
|
|
|
2017-03-15 05:32:08 +08:00
|
|
|
/// Keep track of the equivalence between ComplexPattern's and
|
|
|
|
/// GIComplexOperandMatcher. Map entries are specified by subclassing
|
|
|
|
/// GIComplexPatternEquiv.
|
|
|
|
DenseMap<const Record *, const Record *> ComplexPatternEquivs;
|
|
|
|
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
// Map of predicates to their subtarget features.
|
2017-04-30 01:30:09 +08:00
|
|
|
SubtargetFeatureInfoMap SubtargetFeatures;
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
|
2017-02-10 12:00:17 +08:00
|
|
|
void gatherNodeEquivs();
|
2017-03-16 04:18:38 +08:00
|
|
|
const CodeGenInstruction *findNodeEquiv(Record *N) const;
|
2017-02-10 12:00:17 +08:00
|
|
|
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
Error importRulePredicates(RuleMatcher &M, ArrayRef<Init *> Predicates);
|
2017-03-29 23:37:18 +08:00
|
|
|
Expected<InstructionMatcher &>
|
2017-03-30 17:36:33 +08:00
|
|
|
createAndImportSelDAGMatcher(InstructionMatcher &InsnMatcher,
|
2017-07-11 18:40:18 +08:00
|
|
|
const TreePatternNode *Src,
|
|
|
|
unsigned &TempOpIdx) const;
|
2017-03-30 17:36:33 +08:00
|
|
|
Error importChildMatcher(InstructionMatcher &InsnMatcher,
|
2017-05-24 03:33:16 +08:00
|
|
|
const TreePatternNode *SrcChild, unsigned OpIdx,
|
2017-03-30 17:36:33 +08:00
|
|
|
unsigned &TempOpIdx) const;
|
2017-06-27 18:11:39 +08:00
|
|
|
Expected<BuildMIAction &>
|
|
|
|
createAndImportInstructionRenderer(RuleMatcher &M, const TreePatternNode *Dst,
|
|
|
|
const InstructionMatcher &InsnMatcher);
|
2017-03-30 17:36:33 +08:00
|
|
|
Error importExplicitUseRenderer(BuildMIAction &DstMIBuilder,
|
|
|
|
TreePatternNode *DstChild,
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
const InstructionMatcher &InsnMatcher) const;
|
2017-05-17 16:57:28 +08:00
|
|
|
Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder,
|
|
|
|
DagInit *DefaultOps) const;
|
2017-03-30 17:36:33 +08:00
|
|
|
Error
|
2017-03-29 23:37:18 +08:00
|
|
|
importImplicitDefRenderers(BuildMIAction &DstMIBuilder,
|
|
|
|
const std::vector<Record *> &ImplicitDefs) const;
|
|
|
|
|
2017-02-10 12:00:17 +08:00
|
|
|
/// Analyze pattern \p P, returning a matcher for it if possible.
|
|
|
|
/// Otherwise, return an Error explaining why we don't support it.
|
|
|
|
Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
|
|
|
|
void declareSubtargetFeature(Record *Predicate);
|
2017-02-10 12:00:17 +08:00
|
|
|
};
|
|
|
|
|
2016-12-22 07:26:20 +08:00
|
|
|
void GlobalISelEmitter::gatherNodeEquivs() {
|
|
|
|
assert(NodeEquivs.empty());
|
|
|
|
for (Record *Equiv : RK.getAllDerivedDefinitions("GINodeEquiv"))
|
|
|
|
NodeEquivs[Equiv->getValueAsDef("Node")] =
|
|
|
|
&Target.getInstruction(Equiv->getValueAsDef("I"));
|
2017-03-15 05:32:08 +08:00
|
|
|
|
|
|
|
assert(ComplexPatternEquivs.empty());
|
|
|
|
for (Record *Equiv : RK.getAllDerivedDefinitions("GIComplexPatternEquiv")) {
|
|
|
|
Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
|
|
|
|
if (!SelDAGEquiv)
|
|
|
|
continue;
|
|
|
|
ComplexPatternEquivs[SelDAGEquiv] = Equiv;
|
|
|
|
}
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
|
|
|
|
2017-03-16 04:18:38 +08:00
|
|
|
const CodeGenInstruction *GlobalISelEmitter::findNodeEquiv(Record *N) const {
|
2016-12-22 07:26:20 +08:00
|
|
|
return NodeEquivs.lookup(N);
|
|
|
|
}
|
|
|
|
|
|
|
|
GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
|
2017-06-27 18:11:39 +08:00
|
|
|
: RK(RK), CGP(RK), Target(CGP.getTargetInfo()), CGRegs(RK) {}
|
2016-12-22 07:26:20 +08:00
|
|
|
|
|
|
|
//===- Emitter ------------------------------------------------------------===//
|
|
|
|
|
2017-03-30 17:36:33 +08:00
|
|
|
Error
|
2017-03-29 23:37:18 +08:00
|
|
|
GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
ArrayRef<Init *> Predicates) {
|
|
|
|
for (const Init *Predicate : Predicates) {
|
|
|
|
const DefInit *PredicateDef = static_cast<const DefInit *>(Predicate);
|
|
|
|
declareSubtargetFeature(PredicateDef->getDef());
|
|
|
|
M.addRequiredFeature(PredicateDef->getDef());
|
|
|
|
}
|
|
|
|
|
2017-03-30 17:36:33 +08:00
|
|
|
return Error::success();
|
2017-03-29 23:37:18 +08:00
|
|
|
}
|
2016-12-22 07:26:20 +08:00
|
|
|
|
2017-07-11 18:40:18 +08:00
|
|
|
Expected<InstructionMatcher &>
|
|
|
|
GlobalISelEmitter::createAndImportSelDAGMatcher(InstructionMatcher &InsnMatcher,
|
|
|
|
const TreePatternNode *Src,
|
|
|
|
unsigned &TempOpIdx) const {
|
2017-07-06 16:12:20 +08:00
|
|
|
const CodeGenInstruction *SrcGIOrNull = nullptr;
|
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
// Start with the defined operands (i.e., the results of the root operator).
|
|
|
|
if (Src->getExtTypes().size() > 1)
|
|
|
|
return failedImport("Src pattern has multiple results");
|
2016-12-22 07:26:20 +08:00
|
|
|
|
2017-05-24 03:33:16 +08:00
|
|
|
if (Src->isLeaf()) {
|
|
|
|
Init *SrcInit = Src->getLeafValue();
|
2017-05-24 04:02:48 +08:00
|
|
|
if (isa<IntInit>(SrcInit)) {
|
2017-05-24 03:33:16 +08:00
|
|
|
InsnMatcher.addPredicate<InstructionOpcodeMatcher>(
|
|
|
|
&Target.getInstruction(RK.getDef("G_CONSTANT")));
|
|
|
|
} else
|
2017-06-28 21:50:04 +08:00
|
|
|
return failedImport(
|
|
|
|
"Unable to deduce gMIR opcode to handle Src (which is a leaf)");
|
2017-05-24 03:33:16 +08:00
|
|
|
} else {
|
2017-07-06 16:12:20 +08:00
|
|
|
SrcGIOrNull = findNodeEquiv(Src->getOperator());
|
2017-05-24 03:33:16 +08:00
|
|
|
if (!SrcGIOrNull)
|
|
|
|
return failedImport("Pattern operator lacks an equivalent Instruction" +
|
|
|
|
explainOperator(Src->getOperator()));
|
|
|
|
auto &SrcGI = *SrcGIOrNull;
|
2016-12-22 07:26:20 +08:00
|
|
|
|
2017-05-24 03:33:16 +08:00
|
|
|
// The operators look good: match the opcode
|
|
|
|
InsnMatcher.addPredicate<InstructionOpcodeMatcher>(&SrcGI);
|
|
|
|
}
|
2016-12-22 07:26:20 +08:00
|
|
|
|
|
|
|
unsigned OpIdx = 0;
|
|
|
|
for (const EEVT::TypeSet &Ty : Src->getExtTypes()) {
|
|
|
|
auto OpTyOrNone = MVTToLLT(Ty.getConcrete());
|
2017-03-29 23:37:18 +08:00
|
|
|
|
2016-12-22 07:26:20 +08:00
|
|
|
if (!OpTyOrNone)
|
2017-03-29 23:37:18 +08:00
|
|
|
return failedImport(
|
|
|
|
"Result of Src pattern operator has an unsupported type");
|
2016-12-22 07:26:20 +08:00
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
// Results don't have a name unless they are the root node. The caller will
|
|
|
|
// set the name if appropriate.
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
|
[globalisel] Re-factor ISel matchers into a hierarchy. NFC
Summary:
This should make it possible to easily add everything needed to import all
the existing SelectionDAG rules. It should also serve the likely
kinds of GlobalISel rules (some of which are not currently representable
in SelectionDAG) once we've nailed down the tablegen definition for that.
The hierarchy is as follows:
MatcherRule - A matching rule. Currently used to emit C++ ISel code but will
| also be used to emit test cases and tablegen definitions in the
| near future.
|- Instruction(s) - Represents the instruction to be matched.
|- Instruction Predicate(s) - Test the opcode, arithmetic flags, etc. of an
| instruction.
\- Operand(s) - Represents a particular operand of the instruction. In the
| future, there may be subclasses to test the same predicates
| on multiple operands (including for variadic instructions).
\ Operand Predicate(s) - Test the type, register bank, etc. of an operand.
This is where the ComplexPattern equivalent
will be represented. It's also
nested-instruction matching will live as a
predicate that follows the DefUse chain to the
Def and tests a MatcherRule from that position.
Support for multiple instruction matchers in a rule has been retained from
the existing code but has been adjusted to assert when it is used.
Previously it would silently drop all but the first instruction matcher.
The tablegen-erated file is not functionally changed but has more
parentheses and no longer attempts to format the if-statements since
keeping track of the indentation is tricky in the presence of the matcher
hierarchy. It would be nice to have CMakes tablegen() run the output
through clang-format (when available) so we don't have to complicate
TableGen with pretty-printing.
It's also worth mentioning that this hierarchy will also be able to emit
TableGen definitions and test cases in the near future. This is the reason
for favouring explicit emit*() calls rather than the << operator.
Reviewers: aditya_nandakumar, rovka, t.p.northover, qcolombet, ab
Reviewed By: ab
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D28942
llvm-svn: 293172
2017-01-26 19:10:14 +08:00
|
|
|
OM.addPredicate<LLTOperandMatcher>(*OpTyOrNone);
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
|
|
|
|
2017-05-24 03:33:16 +08:00
|
|
|
if (Src->isLeaf()) {
|
|
|
|
Init *SrcInit = Src->getLeafValue();
|
|
|
|
if (IntInit *SrcIntInit = dyn_cast<IntInit>(SrcInit)) {
|
|
|
|
OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
|
|
|
|
OM.addPredicate<LiteralIntOperandMatcher>(SrcIntInit->getValue());
|
|
|
|
} else
|
2017-06-28 21:50:04 +08:00
|
|
|
return failedImport(
|
|
|
|
"Unable to deduce gMIR opcode to handle Src (which is a leaf)");
|
2017-05-24 03:33:16 +08:00
|
|
|
} else {
|
2017-07-06 16:12:20 +08:00
|
|
|
assert(SrcGIOrNull &&
|
|
|
|
"Expected to have already found an equivalent Instruction");
|
2017-05-24 03:33:16 +08:00
|
|
|
// Match the used operands (i.e. the children of the operator).
|
|
|
|
for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {
|
2017-07-06 16:12:20 +08:00
|
|
|
TreePatternNode *SrcChild = Src->getChild(i);
|
|
|
|
|
|
|
|
// For G_INTRINSIC, the operand immediately following the defs is an
|
|
|
|
// intrinsic ID.
|
|
|
|
if (SrcGIOrNull->TheDef->getName() == "G_INTRINSIC" && i == 0) {
|
2017-07-11 16:57:29 +08:00
|
|
|
if (const CodeGenIntrinsic *II = Src->getIntrinsicInfo(CGP)) {
|
2017-07-06 16:12:20 +08:00
|
|
|
OperandMatcher &OM =
|
|
|
|
InsnMatcher.addOperand(OpIdx++, SrcChild->getName(), TempOpIdx);
|
2017-07-11 16:57:29 +08:00
|
|
|
OM.addPredicate<IntrinsicIDOperandMatcher>(II);
|
2017-07-06 16:12:20 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
return failedImport("Expected IntInit containing instrinsic ID)");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (auto Error =
|
|
|
|
importChildMatcher(InsnMatcher, SrcChild, OpIdx++, TempOpIdx))
|
2017-05-24 03:33:16 +08:00
|
|
|
return std::move(Error);
|
|
|
|
}
|
2017-03-29 23:37:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return InsnMatcher;
|
|
|
|
}
|
|
|
|
|
2017-03-30 17:36:33 +08:00
|
|
|
Error GlobalISelEmitter::importChildMatcher(InstructionMatcher &InsnMatcher,
|
2017-05-24 03:33:16 +08:00
|
|
|
const TreePatternNode *SrcChild,
|
2017-03-30 17:36:33 +08:00
|
|
|
unsigned OpIdx,
|
|
|
|
unsigned &TempOpIdx) const {
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
OperandMatcher &OM =
|
|
|
|
InsnMatcher.addOperand(OpIdx, SrcChild->getName(), TempOpIdx);
|
2017-03-29 23:37:18 +08:00
|
|
|
|
|
|
|
if (SrcChild->hasAnyPredicate())
|
2017-04-13 17:45:37 +08:00
|
|
|
return failedImport("Src pattern child has predicate (" +
|
|
|
|
explainPredicates(SrcChild) + ")");
|
2017-03-29 23:37:18 +08:00
|
|
|
|
|
|
|
ArrayRef<EEVT::TypeSet> ChildTypes = SrcChild->getExtTypes();
|
|
|
|
if (ChildTypes.size() != 1)
|
|
|
|
return failedImport("Src pattern child has multiple results");
|
|
|
|
|
|
|
|
// Check MBB's before the type check since they are not a known type.
|
|
|
|
if (!SrcChild->isLeaf()) {
|
|
|
|
if (SrcChild->getOperator()->isSubClassOf("SDNode")) {
|
|
|
|
auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild->getOperator());
|
|
|
|
if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
|
|
|
|
OM.addPredicate<MBBOperandMatcher>();
|
2017-03-30 17:36:33 +08:00
|
|
|
return Error::success();
|
2017-03-29 23:37:18 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto OpTyOrNone = MVTToLLT(ChildTypes.front().getConcrete());
|
|
|
|
if (!OpTyOrNone)
|
2017-07-06 16:12:20 +08:00
|
|
|
return failedImport("Src operand has an unsupported type (" + to_string(*SrcChild) + ")");
|
2017-03-29 23:37:18 +08:00
|
|
|
OM.addPredicate<LLTOperandMatcher>(*OpTyOrNone);
|
|
|
|
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
// Check for nested instructions.
|
|
|
|
if (!SrcChild->isLeaf()) {
|
|
|
|
// Map the node to a gMIR instruction.
|
|
|
|
InstructionOperandMatcher &InsnOperand =
|
|
|
|
OM.addPredicate<InstructionOperandMatcher>();
|
2017-07-11 18:40:18 +08:00
|
|
|
auto InsnMatcherOrError = createAndImportSelDAGMatcher(
|
|
|
|
InsnOperand.getInsnMatcher(), SrcChild, TempOpIdx);
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
if (auto Error = InsnMatcherOrError.takeError())
|
|
|
|
return Error;
|
|
|
|
|
|
|
|
return Error::success();
|
|
|
|
}
|
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
// Check for constant immediates.
|
|
|
|
if (auto *ChildInt = dyn_cast<IntInit>(SrcChild->getLeafValue())) {
|
2017-05-24 03:33:16 +08:00
|
|
|
OM.addPredicate<ConstantIntOperandMatcher>(ChildInt->getValue());
|
2017-03-30 17:36:33 +08:00
|
|
|
return Error::success();
|
2017-03-29 23:37:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check for def's like register classes or ComplexPattern's.
|
|
|
|
if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
|
|
|
|
auto *ChildRec = ChildDefInit->getDef();
|
|
|
|
|
|
|
|
// Check for register classes.
|
2017-06-20 20:36:34 +08:00
|
|
|
if (ChildRec->isSubClassOf("RegisterClass") ||
|
|
|
|
ChildRec->isSubClassOf("RegisterOperand")) {
|
2017-04-22 23:53:21 +08:00
|
|
|
OM.addPredicate<RegisterBankOperandMatcher>(
|
2017-06-20 20:36:34 +08:00
|
|
|
Target.getRegisterClass(getInitValueAsRegClass(ChildDefInit)));
|
2017-04-22 23:53:21 +08:00
|
|
|
return Error::success();
|
|
|
|
}
|
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
// Check for ComplexPattern's.
|
|
|
|
if (ChildRec->isSubClassOf("ComplexPattern")) {
|
|
|
|
const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
|
|
|
|
if (ComplexPattern == ComplexPatternEquivs.end())
|
2017-04-13 17:45:37 +08:00
|
|
|
return failedImport("SelectionDAG ComplexPattern (" +
|
|
|
|
ChildRec->getName() + ") not mapped to GlobalISel");
|
2017-03-29 23:37:18 +08:00
|
|
|
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
OM.addPredicate<ComplexPatternOperandMatcher>(OM,
|
|
|
|
*ComplexPattern->second);
|
|
|
|
TempOpIdx++;
|
2017-03-30 17:36:33 +08:00
|
|
|
return Error::success();
|
2017-03-29 23:37:18 +08:00
|
|
|
}
|
|
|
|
|
2017-04-13 17:45:37 +08:00
|
|
|
if (ChildRec->isSubClassOf("ImmLeaf")) {
|
|
|
|
return failedImport(
|
|
|
|
"Src pattern child def is an unsupported tablegen class (ImmLeaf)");
|
|
|
|
}
|
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
return failedImport(
|
|
|
|
"Src pattern child def is an unsupported tablegen class");
|
|
|
|
}
|
|
|
|
|
|
|
|
return failedImport("Src pattern child is an unsupported kind");
|
|
|
|
}
|
|
|
|
|
2017-03-30 17:36:33 +08:00
|
|
|
Error GlobalISelEmitter::importExplicitUseRenderer(
|
2017-03-29 23:37:18 +08:00
|
|
|
BuildMIAction &DstMIBuilder, TreePatternNode *DstChild,
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
const InstructionMatcher &InsnMatcher) const {
|
2017-03-29 23:37:18 +08:00
|
|
|
// The only non-leaf child we accept is 'bb': it's an operator because
|
|
|
|
// BasicBlockSDNode isn't inline, but in MI it's just another operand.
|
|
|
|
if (!DstChild->isLeaf()) {
|
|
|
|
if (DstChild->getOperator()->isSubClassOf("SDNode")) {
|
|
|
|
auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator());
|
|
|
|
if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
|
2017-07-05 17:39:33 +08:00
|
|
|
DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher,
|
2017-03-29 23:37:18 +08:00
|
|
|
DstChild->getName());
|
2017-03-30 17:36:33 +08:00
|
|
|
return Error::success();
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
|
|
|
}
|
2017-03-29 23:37:18 +08:00
|
|
|
return failedImport("Dst pattern child isn't a leaf node or an MBB");
|
|
|
|
}
|
2016-12-22 07:26:20 +08:00
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
// Otherwise, we're looking for a bog-standard RegisterClass operand.
|
|
|
|
if (DstChild->hasAnyPredicate())
|
2017-04-13 17:45:37 +08:00
|
|
|
return failedImport("Dst pattern child has predicate (" +
|
|
|
|
explainPredicates(DstChild) + ")");
|
2016-12-22 07:26:20 +08:00
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild->getLeafValue())) {
|
|
|
|
auto *ChildRec = ChildDefInit->getDef();
|
|
|
|
|
|
|
|
ArrayRef<EEVT::TypeSet> ChildTypes = DstChild->getExtTypes();
|
2016-12-22 07:26:20 +08:00
|
|
|
if (ChildTypes.size() != 1)
|
2017-03-29 23:37:18 +08:00
|
|
|
return failedImport("Dst pattern child has multiple results");
|
2016-12-22 07:26:20 +08:00
|
|
|
|
|
|
|
auto OpTyOrNone = MVTToLLT(ChildTypes.front().getConcrete());
|
|
|
|
if (!OpTyOrNone)
|
2017-03-29 23:37:18 +08:00
|
|
|
return failedImport("Dst operand has an unsupported type");
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
if (ChildRec->isSubClassOf("Register")) {
|
2017-07-05 17:39:33 +08:00
|
|
|
DstMIBuilder.addRenderer<AddRegisterRenderer>(0, ChildRec);
|
2017-03-30 17:36:33 +08:00
|
|
|
return Error::success();
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
}
|
|
|
|
|
2017-04-22 23:53:21 +08:00
|
|
|
if (ChildRec->isSubClassOf("RegisterClass") ||
|
|
|
|
ChildRec->isSubClassOf("RegisterOperand")) {
|
2017-07-05 17:39:33 +08:00
|
|
|
DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher,
|
|
|
|
DstChild->getName());
|
2017-03-30 17:36:33 +08:00
|
|
|
return Error::success();
|
2017-03-29 23:37:18 +08:00
|
|
|
}
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
if (ChildRec->isSubClassOf("ComplexPattern")) {
|
|
|
|
const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
|
|
|
|
if (ComplexPattern == ComplexPatternEquivs.end())
|
|
|
|
return failedImport(
|
|
|
|
"SelectionDAG ComplexPattern not mapped to GlobalISel");
|
|
|
|
|
[globalisel][tablegen] Fix patterns involving multiple ComplexPatterns.
Summary:
Temporaries are now allocated to operands instead of predicates and this
allocation is used to correctly pair up the rendered operands with the
matched operands.
Previously, ComplexPatterns were allocated temporaries independently in the
Src Pattern and Dst Pattern, leading to mismatches. Additionally, the Dst
Pattern failed to account for the allocated index and therefore always used
temporary 0, 1, ... when it should have used base+0, base+1, ...
Thanks to Aditya Nandakumar for noticing the bug.
Depends on D30539
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: igorb, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D31054
llvm-svn: 299538
2017-04-05 21:14:03 +08:00
|
|
|
const OperandMatcher &OM = InsnMatcher.getOperand(DstChild->getName());
|
2017-03-29 23:37:18 +08:00
|
|
|
DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
|
2017-07-05 17:39:33 +08:00
|
|
|
0, *ComplexPattern->second, DstChild->getName(),
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
OM.getAllocatedTemporariesBaseID());
|
2017-03-30 17:36:33 +08:00
|
|
|
return Error::success();
|
2017-03-29 23:37:18 +08:00
|
|
|
}
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
2017-04-13 17:45:37 +08:00
|
|
|
if (ChildRec->isSubClassOf("SDNodeXForm"))
|
|
|
|
return failedImport("Dst pattern child def is an unsupported tablegen "
|
|
|
|
"class (SDNodeXForm)");
|
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
return failedImport(
|
|
|
|
"Dst pattern child def is an unsupported tablegen class");
|
|
|
|
}
|
2017-03-15 05:32:08 +08:00
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
return failedImport("Dst pattern child is an unsupported kind");
|
|
|
|
}
|
2017-03-15 05:32:08 +08:00
|
|
|
|
2017-03-30 17:36:33 +08:00
|
|
|
Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
|
2017-03-29 23:37:18 +08:00
|
|
|
RuleMatcher &M, const TreePatternNode *Dst,
|
2017-06-27 18:11:39 +08:00
|
|
|
const InstructionMatcher &InsnMatcher) {
|
2017-03-29 23:37:18 +08:00
|
|
|
Record *DstOp = Dst->getOperator();
|
2017-04-13 17:45:37 +08:00
|
|
|
if (!DstOp->isSubClassOf("Instruction")) {
|
|
|
|
if (DstOp->isSubClassOf("ValueType"))
|
|
|
|
return failedImport(
|
|
|
|
"Pattern operator isn't an instruction (it's a ValueType)");
|
2017-03-29 23:37:18 +08:00
|
|
|
return failedImport("Pattern operator isn't an instruction");
|
2017-04-13 17:45:37 +08:00
|
|
|
}
|
2017-06-20 20:36:34 +08:00
|
|
|
CodeGenInstruction *DstI = &Target.getInstruction(DstOp);
|
|
|
|
|
|
|
|
unsigned DstINumUses = DstI->Operands.size() - DstI->Operands.NumDefs;
|
|
|
|
unsigned ExpectedDstINumUses = Dst->getNumChildren();
|
2017-06-27 18:11:39 +08:00
|
|
|
bool IsExtractSubReg = false;
|
2017-06-20 20:36:34 +08:00
|
|
|
|
|
|
|
// COPY_TO_REGCLASS is just a copy with a ConstrainOperandToRegClassAction
|
2017-06-27 18:11:39 +08:00
|
|
|
// attached. Similarly for EXTRACT_SUBREG except that's a subregister copy.
|
2017-06-20 20:36:34 +08:00
|
|
|
if (DstI->TheDef->getName() == "COPY_TO_REGCLASS") {
|
|
|
|
DstI = &Target.getInstruction(RK.getDef("COPY"));
|
|
|
|
DstINumUses--; // Ignore the class constraint.
|
|
|
|
ExpectedDstINumUses--;
|
2017-06-27 18:11:39 +08:00
|
|
|
} else if (DstI->TheDef->getName() == "EXTRACT_SUBREG") {
|
|
|
|
DstI = &Target.getInstruction(RK.getDef("COPY"));
|
|
|
|
IsExtractSubReg = true;
|
2017-06-20 20:36:34 +08:00
|
|
|
}
|
2017-03-29 23:37:18 +08:00
|
|
|
|
2017-07-05 17:39:33 +08:00
|
|
|
auto &DstMIBuilder = M.addAction<BuildMIAction>(0, DstI, InsnMatcher);
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
// Render the explicit defs.
|
2017-06-20 20:36:34 +08:00
|
|
|
for (unsigned I = 0; I < DstI->Operands.NumDefs; ++I) {
|
|
|
|
const CGIOperandList::OperandInfo &DstIOperand = DstI->Operands[I];
|
2017-07-05 17:39:33 +08:00
|
|
|
DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher, DstIOperand.Name);
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
}
|
|
|
|
|
2017-06-27 18:11:39 +08:00
|
|
|
// EXTRACT_SUBREG needs to use a subregister COPY.
|
|
|
|
if (IsExtractSubReg) {
|
|
|
|
if (!Dst->getChild(0)->isLeaf())
|
|
|
|
return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
|
|
|
|
|
2017-06-28 21:50:04 +08:00
|
|
|
if (DefInit *SubRegInit =
|
|
|
|
dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue())) {
|
2017-06-27 18:11:39 +08:00
|
|
|
CodeGenRegisterClass *RC = CGRegs.getRegClass(
|
|
|
|
getInitValueAsRegClass(Dst->getChild(0)->getLeafValue()));
|
|
|
|
CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
|
|
|
|
|
|
|
|
const auto &SrcRCDstRCPair =
|
|
|
|
RC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
|
|
|
|
if (SrcRCDstRCPair.hasValue()) {
|
|
|
|
assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
|
|
|
|
if (SrcRCDstRCPair->first != RC)
|
|
|
|
return failedImport("EXTRACT_SUBREG requires an additional COPY");
|
|
|
|
}
|
|
|
|
|
|
|
|
DstMIBuilder.addRenderer<CopySubRegRenderer>(
|
2017-07-05 17:39:33 +08:00
|
|
|
0, InsnMatcher, Dst->getChild(0)->getName(), SubIdx);
|
2017-06-27 18:11:39 +08:00
|
|
|
return DstMIBuilder;
|
|
|
|
}
|
|
|
|
|
|
|
|
return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
|
|
|
|
}
|
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
// Render the explicit uses.
|
[globalisel][tablegen] Add experimental support for OperandWithDefaultOps, PredicateOperand, and OptionalDefOperand
Summary:
As far as instruction selection is concerned, all three appear to be same thing.
Support for these operands is experimental since AArch64 doesn't make use
of them and the in-tree targets that do use them (AMDGPU for
OperandWithDefaultOps, AMDGPU/ARM/Hexagon/Lanai for PredicateOperand, and ARM
for OperandWithDefaultOps) are not using tablegen-erated GlobalISel yet.
Reviewers: rovka, aditya_nandakumar, t.p.northover, qcolombet, ab
Reviewed By: rovka
Subscribers: inglorion, aemerson, rengolin, mehdi_amini, dberris, kristof.beyls, igorb, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D31135
llvm-svn: 300037
2017-04-12 16:23:08 +08:00
|
|
|
unsigned Child = 0;
|
2017-05-17 16:57:28 +08:00
|
|
|
unsigned NumDefaultOps = 0;
|
[globalisel][tablegen] Add experimental support for OperandWithDefaultOps, PredicateOperand, and OptionalDefOperand
Summary:
As far as instruction selection is concerned, all three appear to be same thing.
Support for these operands is experimental since AArch64 doesn't make use
of them and the in-tree targets that do use them (AMDGPU for
OperandWithDefaultOps, AMDGPU/ARM/Hexagon/Lanai for PredicateOperand, and ARM
for OperandWithDefaultOps) are not using tablegen-erated GlobalISel yet.
Reviewers: rovka, aditya_nandakumar, t.p.northover, qcolombet, ab
Reviewed By: rovka
Subscribers: inglorion, aemerson, rengolin, mehdi_amini, dberris, kristof.beyls, igorb, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D31135
llvm-svn: 300037
2017-04-12 16:23:08 +08:00
|
|
|
for (unsigned I = 0; I != DstINumUses; ++I) {
|
2017-06-20 20:36:34 +08:00
|
|
|
const CGIOperandList::OperandInfo &DstIOperand =
|
|
|
|
DstI->Operands[DstI->Operands.NumDefs + I];
|
[globalisel][tablegen] Add experimental support for OperandWithDefaultOps, PredicateOperand, and OptionalDefOperand
Summary:
As far as instruction selection is concerned, all three appear to be same thing.
Support for these operands is experimental since AArch64 doesn't make use
of them and the in-tree targets that do use them (AMDGPU for
OperandWithDefaultOps, AMDGPU/ARM/Hexagon/Lanai for PredicateOperand, and ARM
for OperandWithDefaultOps) are not using tablegen-erated GlobalISel yet.
Reviewers: rovka, aditya_nandakumar, t.p.northover, qcolombet, ab
Reviewed By: rovka
Subscribers: inglorion, aemerson, rengolin, mehdi_amini, dberris, kristof.beyls, igorb, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D31135
llvm-svn: 300037
2017-04-12 16:23:08 +08:00
|
|
|
|
2017-05-17 16:57:28 +08:00
|
|
|
// If the operand has default values, introduce them now.
|
|
|
|
// FIXME: Until we have a decent test case that dictates we should do
|
|
|
|
// otherwise, we're going to assume that operands with default values cannot
|
|
|
|
// be specified in the patterns. Therefore, adding them will not cause us to
|
|
|
|
// end up with too many rendered operands.
|
|
|
|
if (DstIOperand.Rec->isSubClassOf("OperandWithDefaultOps")) {
|
[globalisel][tablegen] Add experimental support for OperandWithDefaultOps, PredicateOperand, and OptionalDefOperand
Summary:
As far as instruction selection is concerned, all three appear to be same thing.
Support for these operands is experimental since AArch64 doesn't make use
of them and the in-tree targets that do use them (AMDGPU for
OperandWithDefaultOps, AMDGPU/ARM/Hexagon/Lanai for PredicateOperand, and ARM
for OperandWithDefaultOps) are not using tablegen-erated GlobalISel yet.
Reviewers: rovka, aditya_nandakumar, t.p.northover, qcolombet, ab
Reviewed By: rovka
Subscribers: inglorion, aemerson, rengolin, mehdi_amini, dberris, kristof.beyls, igorb, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D31135
llvm-svn: 300037
2017-04-12 16:23:08 +08:00
|
|
|
DagInit *DefaultOps = DstIOperand.Rec->getValueAsDag("DefaultOps");
|
2017-05-17 16:57:28 +08:00
|
|
|
if (auto Error = importDefaultOperandRenderers(DstMIBuilder, DefaultOps))
|
|
|
|
return std::move(Error);
|
|
|
|
++NumDefaultOps;
|
[globalisel][tablegen] Add experimental support for OperandWithDefaultOps, PredicateOperand, and OptionalDefOperand
Summary:
As far as instruction selection is concerned, all three appear to be same thing.
Support for these operands is experimental since AArch64 doesn't make use
of them and the in-tree targets that do use them (AMDGPU for
OperandWithDefaultOps, AMDGPU/ARM/Hexagon/Lanai for PredicateOperand, and ARM
for OperandWithDefaultOps) are not using tablegen-erated GlobalISel yet.
Reviewers: rovka, aditya_nandakumar, t.p.northover, qcolombet, ab
Reviewed By: rovka
Subscribers: inglorion, aemerson, rengolin, mehdi_amini, dberris, kristof.beyls, igorb, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D31135
llvm-svn: 300037
2017-04-12 16:23:08 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (auto Error = importExplicitUseRenderer(
|
|
|
|
DstMIBuilder, Dst->getChild(Child), InsnMatcher))
|
2017-03-29 23:37:18 +08:00
|
|
|
return std::move(Error);
|
[globalisel][tablegen] Add experimental support for OperandWithDefaultOps, PredicateOperand, and OptionalDefOperand
Summary:
As far as instruction selection is concerned, all three appear to be same thing.
Support for these operands is experimental since AArch64 doesn't make use
of them and the in-tree targets that do use them (AMDGPU for
OperandWithDefaultOps, AMDGPU/ARM/Hexagon/Lanai for PredicateOperand, and ARM
for OperandWithDefaultOps) are not using tablegen-erated GlobalISel yet.
Reviewers: rovka, aditya_nandakumar, t.p.northover, qcolombet, ab
Reviewed By: rovka
Subscribers: inglorion, aemerson, rengolin, mehdi_amini, dberris, kristof.beyls, igorb, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D31135
llvm-svn: 300037
2017-04-12 16:23:08 +08:00
|
|
|
++Child;
|
2017-03-29 23:37:18 +08:00
|
|
|
}
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
2017-06-20 20:36:34 +08:00
|
|
|
if (NumDefaultOps + ExpectedDstINumUses != DstINumUses)
|
2017-05-17 17:25:08 +08:00
|
|
|
return failedImport("Expected " + llvm::to_string(DstINumUses) +
|
2017-05-17 16:57:28 +08:00
|
|
|
" used operands but found " +
|
2017-06-20 20:36:34 +08:00
|
|
|
llvm::to_string(ExpectedDstINumUses) +
|
2017-05-17 17:25:08 +08:00
|
|
|
" explicit ones and " + llvm::to_string(NumDefaultOps) +
|
2017-05-17 16:57:28 +08:00
|
|
|
" default ones");
|
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
return DstMIBuilder;
|
|
|
|
}
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
2017-05-17 16:57:28 +08:00
|
|
|
Error GlobalISelEmitter::importDefaultOperandRenderers(
|
|
|
|
BuildMIAction &DstMIBuilder, DagInit *DefaultOps) const {
|
2017-05-30 05:49:34 +08:00
|
|
|
for (const auto *DefaultOp : DefaultOps->getArgs()) {
|
2017-05-17 16:57:28 +08:00
|
|
|
// Look through ValueType operators.
|
|
|
|
if (const DagInit *DefaultDagOp = dyn_cast<DagInit>(DefaultOp)) {
|
|
|
|
if (const DefInit *DefaultDagOperator =
|
|
|
|
dyn_cast<DefInit>(DefaultDagOp->getOperator())) {
|
|
|
|
if (DefaultDagOperator->getDef()->isSubClassOf("ValueType"))
|
|
|
|
DefaultOp = DefaultDagOp->getArg(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) {
|
2017-07-05 17:39:33 +08:00
|
|
|
DstMIBuilder.addRenderer<AddRegisterRenderer>(0, DefaultDefOp->getDef());
|
2017-05-17 16:57:28 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) {
|
2017-07-05 17:39:33 +08:00
|
|
|
DstMIBuilder.addRenderer<ImmRenderer>(0, DefaultIntOp->getValue());
|
2017-05-17 16:57:28 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
return failedImport("Could not add default op");
|
|
|
|
}
|
|
|
|
|
|
|
|
return Error::success();
|
|
|
|
}
|
|
|
|
|
2017-03-30 17:36:33 +08:00
|
|
|
Error GlobalISelEmitter::importImplicitDefRenderers(
|
2017-03-29 23:37:18 +08:00
|
|
|
BuildMIAction &DstMIBuilder,
|
|
|
|
const std::vector<Record *> &ImplicitDefs) const {
|
|
|
|
if (!ImplicitDefs.empty())
|
|
|
|
return failedImport("Pattern defines a physical register");
|
2017-03-30 17:36:33 +08:00
|
|
|
return Error::success();
|
2017-03-29 23:37:18 +08:00
|
|
|
}
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
|
|
|
|
// Keep track of the matchers and actions to emit.
|
|
|
|
RuleMatcher M;
|
|
|
|
M.addAction<DebugCommentAction>(P);
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
2017-03-30 17:36:33 +08:00
|
|
|
if (auto Error = importRulePredicates(M, P.getPredicates()->getValues()))
|
2017-03-29 23:37:18 +08:00
|
|
|
return std::move(Error);
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
// Next, analyze the pattern operators.
|
|
|
|
TreePatternNode *Src = P.getSrcPattern();
|
|
|
|
TreePatternNode *Dst = P.getDstPattern();
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
// If the root of either pattern isn't a simple operator, ignore it.
|
2017-04-13 17:45:37 +08:00
|
|
|
if (auto Err = isTrivialOperatorNode(Dst))
|
|
|
|
return failedImport("Dst pattern root isn't a trivial operator (" +
|
|
|
|
toString(std::move(Err)) + ")");
|
|
|
|
if (auto Err = isTrivialOperatorNode(Src))
|
|
|
|
return failedImport("Src pattern root isn't a trivial operator (" +
|
|
|
|
toString(std::move(Err)) + ")");
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
2017-05-24 03:33:16 +08:00
|
|
|
if (Dst->isLeaf())
|
|
|
|
return failedImport("Dst pattern root isn't a known leaf");
|
|
|
|
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
// Start with the defined operands (i.e., the results of the root operator).
|
2017-03-29 23:37:18 +08:00
|
|
|
Record *DstOp = Dst->getOperator();
|
|
|
|
if (!DstOp->isSubClassOf("Instruction"))
|
|
|
|
return failedImport("Pattern operator isn't an instruction");
|
2017-03-15 05:32:08 +08:00
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
auto &DstI = Target.getInstruction(DstOp);
|
|
|
|
if (DstI.Operands.NumDefs != Src->getExtTypes().size())
|
2017-04-13 17:45:37 +08:00
|
|
|
return failedImport("Src pattern results and dst MI defs are different (" +
|
|
|
|
to_string(Src->getExtTypes().size()) + " def(s) vs " +
|
|
|
|
to_string(DstI.Operands.NumDefs) + " def(s))");
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher();
|
2017-07-11 18:40:18 +08:00
|
|
|
unsigned TempOpIdx = 0;
|
|
|
|
auto InsnMatcherOrError =
|
|
|
|
createAndImportSelDAGMatcher(InsnMatcherTemp, Src, TempOpIdx);
|
2017-03-29 23:37:18 +08:00
|
|
|
if (auto Error = InsnMatcherOrError.takeError())
|
|
|
|
return std::move(Error);
|
|
|
|
InstructionMatcher &InsnMatcher = InsnMatcherOrError.get();
|
|
|
|
|
|
|
|
// The root of the match also has constraints on the register bank so that it
|
|
|
|
// matches the result instruction.
|
|
|
|
unsigned OpIdx = 0;
|
|
|
|
for (const EEVT::TypeSet &Ty : Src->getExtTypes()) {
|
|
|
|
(void)Ty;
|
|
|
|
|
|
|
|
const auto &DstIOperand = DstI.Operands[OpIdx];
|
|
|
|
Record *DstIOpRec = DstIOperand.Rec;
|
2017-06-20 20:36:34 +08:00
|
|
|
if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
|
|
|
|
DstIOpRec = getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
|
|
|
|
|
|
|
|
if (DstIOpRec == nullptr)
|
|
|
|
return failedImport(
|
|
|
|
"COPY_TO_REGCLASS operand #1 isn't a register class");
|
2017-06-27 18:11:39 +08:00
|
|
|
} else if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
|
|
|
|
if (!Dst->getChild(0)->isLeaf())
|
|
|
|
return failedImport("EXTRACT_SUBREG operand #0 isn't a leaf");
|
|
|
|
|
2017-06-28 21:50:04 +08:00
|
|
|
// We can assume that a subregister is in the same bank as it's super
|
|
|
|
// register.
|
2017-06-27 18:11:39 +08:00
|
|
|
DstIOpRec = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
|
|
|
|
|
|
|
|
if (DstIOpRec == nullptr)
|
|
|
|
return failedImport(
|
|
|
|
"EXTRACT_SUBREG operand #0 isn't a register class");
|
2017-06-20 20:36:34 +08:00
|
|
|
} else if (DstIOpRec->isSubClassOf("RegisterOperand"))
|
2017-04-22 23:53:21 +08:00
|
|
|
DstIOpRec = DstIOpRec->getValueAsDef("RegClass");
|
2017-06-20 20:36:34 +08:00
|
|
|
else if (!DstIOpRec->isSubClassOf("RegisterClass"))
|
2017-06-28 21:50:04 +08:00
|
|
|
return failedImport("Dst MI def isn't a register class" +
|
|
|
|
to_string(*Dst));
|
2017-03-29 23:37:18 +08:00
|
|
|
|
|
|
|
OperandMatcher &OM = InsnMatcher.getOperand(OpIdx);
|
|
|
|
OM.setSymbolicName(DstIOperand.Name);
|
|
|
|
OM.addPredicate<RegisterBankOperandMatcher>(
|
|
|
|
Target.getRegisterClass(DstIOpRec));
|
|
|
|
++OpIdx;
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
|
|
|
|
2017-03-30 17:36:33 +08:00
|
|
|
auto DstMIBuilderOrError =
|
|
|
|
createAndImportInstructionRenderer(M, Dst, InsnMatcher);
|
2017-03-29 23:37:18 +08:00
|
|
|
if (auto Error = DstMIBuilderOrError.takeError())
|
|
|
|
return std::move(Error);
|
|
|
|
BuildMIAction &DstMIBuilder = DstMIBuilderOrError.get();
|
|
|
|
|
|
|
|
// Render the implicit defs.
|
|
|
|
// These are only added to the root of the result.
|
2017-03-30 17:36:33 +08:00
|
|
|
if (auto Error = importImplicitDefRenderers(DstMIBuilder, P.getDstRegs()))
|
2017-03-29 23:37:18 +08:00
|
|
|
return std::move(Error);
|
|
|
|
|
2017-06-20 20:36:34 +08:00
|
|
|
// Constrain the registers to classes. This is normally derived from the
|
|
|
|
// emitted instruction but a few instructions require special handling.
|
|
|
|
if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
|
|
|
|
// COPY_TO_REGCLASS does not provide operand constraints itself but the
|
|
|
|
// result is constrained to the class given by the second child.
|
|
|
|
Record *DstIOpRec =
|
|
|
|
getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
|
|
|
|
|
|
|
|
if (DstIOpRec == nullptr)
|
|
|
|
return failedImport("COPY_TO_REGCLASS operand #1 isn't a register class");
|
|
|
|
|
|
|
|
M.addAction<ConstrainOperandToRegClassAction>(
|
2017-07-05 17:39:33 +08:00
|
|
|
0, 0, Target.getRegisterClass(DstIOpRec));
|
2017-06-27 18:11:39 +08:00
|
|
|
|
|
|
|
// We're done with this pattern! It's eligible for GISel emission; return
|
|
|
|
// it.
|
|
|
|
++NumPatternImported;
|
|
|
|
return std::move(M);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
|
|
|
|
// EXTRACT_SUBREG selects into a subregister COPY but unlike most
|
|
|
|
// instructions, the result register class is controlled by the
|
|
|
|
// subregisters of the operand. As a result, we must constrain the result
|
|
|
|
// class rather than check that it's already the right one.
|
|
|
|
if (!Dst->getChild(0)->isLeaf())
|
|
|
|
return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
|
|
|
|
|
2017-06-28 23:16:03 +08:00
|
|
|
DefInit *SubRegInit = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
|
|
|
|
if (!SubRegInit)
|
|
|
|
return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
|
2017-06-27 18:11:39 +08:00
|
|
|
|
2017-06-28 23:16:03 +08:00
|
|
|
// Constrain the result to the same register bank as the operand.
|
|
|
|
Record *DstIOpRec =
|
|
|
|
getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
|
2017-06-27 18:11:39 +08:00
|
|
|
|
2017-06-28 23:16:03 +08:00
|
|
|
if (DstIOpRec == nullptr)
|
|
|
|
return failedImport("EXTRACT_SUBREG operand #1 isn't a register class");
|
|
|
|
|
|
|
|
CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
|
2017-07-05 17:39:33 +08:00
|
|
|
CodeGenRegisterClass *SrcRC = CGRegs.getRegClass(DstIOpRec);
|
2017-06-28 23:16:03 +08:00
|
|
|
|
|
|
|
// It would be nice to leave this constraint implicit but we're required
|
|
|
|
// to pick a register class so constrain the result to a register class
|
|
|
|
// that can hold the correct MVT.
|
|
|
|
//
|
|
|
|
// FIXME: This may introduce an extra copy if the chosen class doesn't
|
|
|
|
// actually contain the subregisters.
|
|
|
|
assert(Src->getExtTypes().size() == 1 &&
|
|
|
|
"Expected Src of EXTRACT_SUBREG to have one result type");
|
|
|
|
|
|
|
|
const auto &SrcRCDstRCPair =
|
|
|
|
SrcRC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
|
|
|
|
assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
|
2017-07-05 17:39:33 +08:00
|
|
|
M.addAction<ConstrainOperandToRegClassAction>(0, 0, *SrcRCDstRCPair->second);
|
|
|
|
M.addAction<ConstrainOperandToRegClassAction>(0, 1, *SrcRCDstRCPair->first);
|
|
|
|
|
|
|
|
// We're done with this pattern! It's eligible for GISel emission; return
|
|
|
|
// it.
|
|
|
|
++NumPatternImported;
|
|
|
|
return std::move(M);
|
|
|
|
}
|
|
|
|
|
|
|
|
M.addAction<ConstrainOperandsToDefinitionAction>(0);
|
2017-06-20 20:36:34 +08:00
|
|
|
|
2017-02-10 12:00:17 +08:00
|
|
|
// We're done with this pattern! It's eligible for GISel emission; return it.
|
2017-02-20 22:31:27 +08:00
|
|
|
++NumPatternImported;
|
2017-02-10 12:00:17 +08:00
|
|
|
return std::move(M);
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GlobalISelEmitter::run(raw_ostream &OS) {
|
|
|
|
// Track the GINodeEquiv definitions.
|
|
|
|
gatherNodeEquivs();
|
|
|
|
|
|
|
|
emitSourceFileHeader(("Global Instruction Selector for the " +
|
|
|
|
Target.getName() + " target").str(), OS);
|
2017-02-20 22:31:27 +08:00
|
|
|
std::vector<RuleMatcher> Rules;
|
2016-12-22 07:26:20 +08:00
|
|
|
// Look through the SelectionDAG patterns we found, possibly emitting some.
|
|
|
|
for (const PatternToMatch &Pat : CGP.ptms()) {
|
|
|
|
++NumPatternTotal;
|
2017-02-10 12:00:17 +08:00
|
|
|
auto MatcherOrErr = runOnPattern(Pat);
|
|
|
|
|
|
|
|
// The pattern analysis can fail, indicating an unsupported pattern.
|
|
|
|
// Report that if we've been asked to do so.
|
|
|
|
if (auto Err = MatcherOrErr.takeError()) {
|
2016-12-22 07:26:20 +08:00
|
|
|
if (WarnOnSkippedPatterns) {
|
|
|
|
PrintWarning(Pat.getSrcRecord()->getLoc(),
|
2017-02-10 12:00:17 +08:00
|
|
|
"Skipped pattern: " + toString(std::move(Err)));
|
|
|
|
} else {
|
|
|
|
consumeError(std::move(Err));
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
2017-02-20 22:31:27 +08:00
|
|
|
++NumPatternImportsSkipped;
|
2017-02-10 12:00:17 +08:00
|
|
|
continue;
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
2017-02-10 12:00:17 +08:00
|
|
|
|
2017-02-20 22:31:27 +08:00
|
|
|
Rules.push_back(std::move(MatcherOrErr.get()));
|
|
|
|
}
|
|
|
|
|
[globalisel] Decouple src pattern operands from dst pattern operands.
Summary:
This isn't testable for AArch64 by itself so this patch also adds
support for constant immediates in the pattern and physical
register uses in the result.
The new IntOperandMatcher matches the constant in patterns such as
'(set $rd:GPR32, (G_XOR $rs:GPR32, -1))'. It's always safe to fold
immediates into an instruction so this is the first rule that will match
across multiple BB's.
The Renderer hierarchy is responsible for adding operands to the result
instruction. Renderers can copy operands (CopyRenderer) or add physical
registers (in particular %wzr and %xzr) to the result instruction
in any order (OperandMatchers now import the operand names from
SelectionDAG to allow renderers to access any operand). This allows us to
emit the result instruction for:
%1 = G_XOR %0, -1 --> %1 = ORNWrr %wzr, %0
%1 = G_XOR -1, %0 --> %1 = ORNWrr %wzr, %0
although the latter is untested since the matcher/importer has not been
taught about commutativity yet.
Added BuildMIAction which can build new instructions and mutate them where
possible. W.r.t the mutation aspect, MatchActions are now told the name of
an instruction they can recycle and BuildMIAction will emit mutation code
when the renderers are appropriate. They are appropriate when all operands
are rendered using CopyRenderer and the indices are the same as the matcher.
This currently assumes that all operands have at least one matcher.
Finally, this change also fixes a crash in
AArch64InstructionSelector::select() caused by an immediate operand
passing isImm() rather than isCImm(). This was uncovered by the other
changes and was detected by existing tests.
Depends on D29711
Reviewers: t.p.northover, ab, qcolombet, rovka, aditya_nandakumar, javed.absar
Reviewed By: rovka
Subscribers: aemerson, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29712
llvm-svn: 296131
2017-02-24 23:43:30 +08:00
|
|
|
std::stable_sort(Rules.begin(), Rules.end(),
|
|
|
|
[&](const RuleMatcher &A, const RuleMatcher &B) {
|
[globalisel] Sort RuleMatchers by priority.
Summary:
This makes more important rules have priority over less important rules.
For example, '%a = G_ADD $b:s64, $c:s64' has priority over
'%a = G_ADD $b:s32, $c:s32'. Previously these rules were emitted in the
correct order by chance.
NFC in this patch but it is required to make the next patch work correctly.
Depends on D29710
Reviewers: t.p.northover, ab, qcolombet, aditya_nandakumar, rovka
Reviewed By: ab, rovka
Subscribers: javed.absar, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D29711
llvm-svn: 296121
2017-02-24 21:58:11 +08:00
|
|
|
if (A.isHigherPriorityThan(B)) {
|
|
|
|
assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
|
|
|
|
"and less important at "
|
|
|
|
"the same time");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
std::vector<Record *> ComplexPredicates =
|
|
|
|
RK.getAllDerivedDefinitions("GIComplexOperandMatcher");
|
|
|
|
std::sort(ComplexPredicates.begin(), ComplexPredicates.end(),
|
|
|
|
[](const Record *A, const Record *B) {
|
|
|
|
if (A->getName() < B->getName())
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
});
|
2017-03-15 05:32:08 +08:00
|
|
|
unsigned MaxTemporaries = 0;
|
|
|
|
for (const auto &Rule : Rules)
|
[globalisel][tablegen] Revise API for ComplexPattern operands to improve flexibility.
Summary:
Some targets need to be able to do more complex rendering than just adding an
operand or two to an instruction. For example, it may need to insert an
instruction to extract a subreg first, or it may need to perform an operation
on the operand.
In SelectionDAG, targets would create SDNode's to achieve the desired effect
during the complex pattern predicate. This worked because SelectionDAG had a
form of garbage collection that would take care of SDNode's that were created
but not used due to a later predicate rejecting a match. This doesn't translate
well to GlobalISel and the churn was wasteful.
The API changes in this patch enable GlobalISel to accomplish the same thing
without the waste. The API is now:
InstructionSelector::OptionalComplexRendererFn selectArithImmed(MachineOperand &Root) const;
where Root is the root of the match. The return value can be omitted to
indicate that the predicate failed to match, or a function with the signature
ComplexRendererFn can be returned. For example:
return OptionalComplexRendererFn(
[=](MachineInstrBuilder &MIB) { MIB.addImm(Immed).addImm(ShVal); });
adds two immediate operands to the rendered instruction. Immed and ShVal are
captured from the predicate function.
As an added bonus, this also reduces the amount of information we need to
provide to GIComplexOperandMatcher.
Depends on D31418
Reviewers: aditya_nandakumar, t.p.northover, qcolombet, rovka, ab, javed.absar
Reviewed By: ab
Subscribers: dberris, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D31761
llvm-svn: 301079
2017-04-22 23:11:04 +08:00
|
|
|
MaxTemporaries = std::max(MaxTemporaries, Rule.countRendererFns());
|
2017-03-15 05:32:08 +08:00
|
|
|
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
OS << "#ifdef GET_GLOBALISEL_PREDICATE_BITSET\n"
|
|
|
|
<< "const unsigned MAX_SUBTARGET_PREDICATES = " << SubtargetFeatures.size()
|
|
|
|
<< ";\n"
|
|
|
|
<< "using PredicateBitset = "
|
|
|
|
"llvm::PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;\n"
|
|
|
|
<< "#endif // ifdef GET_GLOBALISEL_PREDICATE_BITSET\n\n";
|
|
|
|
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n"
|
|
|
|
<< " mutable MatcherState State;\n"
|
|
|
|
<< " typedef "
|
|
|
|
"ComplexRendererFn("
|
|
|
|
<< Target.getName()
|
|
|
|
<< "InstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const;\n"
|
|
|
|
<< "const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> "
|
|
|
|
"MatcherInfo;\n"
|
|
|
|
<< "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n";
|
|
|
|
|
|
|
|
OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n"
|
|
|
|
<< ", State(" << MaxTemporaries << "),\n"
|
|
|
|
<< "MatcherInfo({TypeObjects, FeatureBitsets, {\n"
|
|
|
|
<< " nullptr, // GICP_Invalid\n";
|
|
|
|
for (const auto &Record : ComplexPredicates)
|
|
|
|
OS << " &" << Target.getName()
|
|
|
|
<< "InstructionSelector::" << Record->getValueAsString("MatcherFn")
|
|
|
|
<< ", // " << Record->getName() << "\n";
|
|
|
|
OS << "}})\n"
|
|
|
|
<< "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n";
|
2017-03-15 05:32:08 +08:00
|
|
|
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
OS << "#ifdef GET_GLOBALISEL_IMPL\n";
|
|
|
|
SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
|
|
|
|
OS);
|
2017-04-30 01:30:09 +08:00
|
|
|
|
|
|
|
// Separate subtarget features by how often they must be recomputed.
|
|
|
|
SubtargetFeatureInfoMap ModuleFeatures;
|
|
|
|
std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
|
|
|
|
std::inserter(ModuleFeatures, ModuleFeatures.end()),
|
|
|
|
[](const SubtargetFeatureInfoMap::value_type &X) {
|
|
|
|
return !X.second.mustRecomputePerFunction();
|
|
|
|
});
|
|
|
|
SubtargetFeatureInfoMap FunctionFeatures;
|
|
|
|
std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
|
|
|
|
std::inserter(FunctionFeatures, FunctionFeatures.end()),
|
|
|
|
[](const SubtargetFeatureInfoMap::value_type &X) {
|
|
|
|
return X.second.mustRecomputePerFunction();
|
|
|
|
});
|
|
|
|
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
SubtargetFeatureInfo::emitComputeAvailableFeatures(
|
2017-04-30 01:30:09 +08:00
|
|
|
Target.getName(), "InstructionSelector", "computeAvailableModuleFeatures",
|
|
|
|
ModuleFeatures, OS);
|
|
|
|
SubtargetFeatureInfo::emitComputeAvailableFeatures(
|
|
|
|
Target.getName(), "InstructionSelector",
|
|
|
|
"computeAvailableFunctionFeatures", FunctionFeatures, OS,
|
|
|
|
"const MachineFunction *MF");
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
// Emit a table containing the LLT objects needed by the matcher and an enum
|
|
|
|
// for the matcher to reference them with.
|
|
|
|
std::vector<LLTCodeGen> TypeObjects = {
|
|
|
|
LLT::scalar(8), LLT::scalar(16), LLT::scalar(32),
|
|
|
|
LLT::scalar(64), LLT::scalar(80), LLT::vector(8, 1),
|
|
|
|
LLT::vector(16, 1), LLT::vector(32, 1), LLT::vector(64, 1),
|
|
|
|
LLT::vector(8, 8), LLT::vector(16, 8), LLT::vector(32, 8),
|
|
|
|
LLT::vector(64, 8), LLT::vector(4, 16), LLT::vector(8, 16),
|
|
|
|
LLT::vector(16, 16), LLT::vector(32, 16), LLT::vector(2, 32),
|
|
|
|
LLT::vector(4, 32), LLT::vector(8, 32), LLT::vector(16, 32),
|
|
|
|
LLT::vector(2, 64), LLT::vector(4, 64), LLT::vector(8, 64),
|
|
|
|
};
|
|
|
|
std::sort(TypeObjects.begin(), TypeObjects.end());
|
|
|
|
OS << "enum {\n";
|
|
|
|
for (const auto &TypeObject : TypeObjects) {
|
|
|
|
OS << " ";
|
|
|
|
TypeObject.emitCxxEnumValue(OS);
|
|
|
|
OS << ",\n";
|
|
|
|
}
|
|
|
|
OS << "};\n"
|
|
|
|
<< "const static LLT TypeObjects[] = {\n";
|
|
|
|
for (const auto &TypeObject : TypeObjects) {
|
|
|
|
OS << " ";
|
|
|
|
TypeObject.emitCxxConstructorCall(OS);
|
|
|
|
OS << ",\n";
|
|
|
|
}
|
|
|
|
OS << "};\n\n";
|
|
|
|
|
|
|
|
// Emit a table containing the PredicateBitsets objects needed by the matcher
|
|
|
|
// and an enum for the matcher to reference them with.
|
|
|
|
std::vector<std::vector<Record *>> FeatureBitsets;
|
|
|
|
for (auto &Rule : Rules)
|
|
|
|
FeatureBitsets.push_back(Rule.getRequiredFeatures());
|
|
|
|
std::sort(
|
|
|
|
FeatureBitsets.begin(), FeatureBitsets.end(),
|
|
|
|
[&](const std::vector<Record *> &A, const std::vector<Record *> &B) {
|
|
|
|
if (A.size() < B.size())
|
|
|
|
return true;
|
|
|
|
if (A.size() > B.size())
|
|
|
|
return false;
|
|
|
|
for (const auto &Pair : zip(A, B)) {
|
|
|
|
if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
|
|
|
|
return true;
|
|
|
|
if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
FeatureBitsets.erase(
|
|
|
|
std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
|
|
|
|
FeatureBitsets.end());
|
|
|
|
OS << "enum {\n"
|
|
|
|
<< " GIFBS_Invalid,\n";
|
|
|
|
for (const auto &FeatureBitset : FeatureBitsets) {
|
|
|
|
if (FeatureBitset.empty())
|
|
|
|
continue;
|
|
|
|
OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
|
|
|
|
}
|
|
|
|
OS << "};\n"
|
|
|
|
<< "const static PredicateBitset FeatureBitsets[] {\n"
|
|
|
|
<< " {}, // GIFBS_Invalid\n";
|
|
|
|
for (const auto &FeatureBitset : FeatureBitsets) {
|
|
|
|
if (FeatureBitset.empty())
|
|
|
|
continue;
|
|
|
|
OS << " {";
|
|
|
|
for (const auto &Feature : FeatureBitset) {
|
|
|
|
const auto &I = SubtargetFeatures.find(Feature);
|
|
|
|
assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
|
|
|
|
OS << I->second.getEnumBitName() << ", ";
|
|
|
|
}
|
|
|
|
OS << "},\n";
|
|
|
|
}
|
|
|
|
OS << "};\n\n";
|
|
|
|
|
|
|
|
// Emit complex predicate table and an enum to reference them with.
|
|
|
|
OS << "enum {\n"
|
|
|
|
<< " GICP_Invalid,\n";
|
|
|
|
for (const auto &Record : ComplexPredicates)
|
|
|
|
OS << " GICP_" << Record->getName() << ",\n";
|
|
|
|
OS << "};\n"
|
|
|
|
<< "// See constructor for table contents\n\n";
|
|
|
|
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
OS << "bool " << Target.getName()
|
2017-03-15 05:32:08 +08:00
|
|
|
<< "InstructionSelector::selectImpl(MachineInstr &I) const {\n"
|
|
|
|
<< " MachineFunction &MF = *I.getParent()->getParent();\n"
|
[globalisel][tablegen] Partially fix compile-time regressions by converting matcher to state-machine(s)
Summary:
Replace the matcher if-statements for each rule with a state-machine. This
significantly reduces compile time, memory allocations, and cumulative memory
allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is
recommitted.
The following patches will expand on this further to fully fix the regressions.
Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar
Reviewed By: ab
Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D33758
llvm-svn: 307079
2017-07-04 22:35:06 +08:00
|
|
|
<< " MachineRegisterInfo &MRI = MF.getRegInfo();\n"
|
2017-06-28 21:50:04 +08:00
|
|
|
<< " // FIXME: This should be computed on a per-function basis rather "
|
|
|
|
"than per-insn.\n"
|
|
|
|
<< " AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, "
|
|
|
|
"&MF);\n"
|
2017-07-05 22:50:18 +08:00
|
|
|
<< " const PredicateBitset AvailableFeatures = getAvailableFeatures();\n"
|
|
|
|
<< " NewMIVector OutMIs;\n"
|
|
|
|
<< " State.MIs.clear();\n"
|
|
|
|
<< " State.MIs.push_back(&I);\n\n";
|
2017-03-15 05:32:08 +08:00
|
|
|
|
2017-07-27 19:03:45 +08:00
|
|
|
MatchTable Table(0);
|
[tablegen][globalisel] Capture instructions into locals and related infrastructure for multiple instructions matches.
Summary:
Prepare the way for nested instruction matching support by having actions
like CopyRenderer look up operands in the RuleMatcher rather than a
specific InstructionMatcher. This allows actions to reference any operand
from any matched instruction.
It works by checking the 'shape' of the match and capturing
each matched instruction to a local variable. If the shape is wrong
(not enough operands, leaf nodes where non-leafs are expected, etc.), then
the rule exits early without checking the predicates. Once we've captured
the instructions, we then test the predicates as before (except using the
local variables). If the match is successful, then we render the new
instruction as before using the local variables.
It's not noticable in this patch but by the time we support multiple
instruction matching, this patch will also cause a significant improvement
to readability of the emitted code since
MRI.getVRegDef(I->getOperand(0).getReg()) will simply be MI1 after
emitCxxCaptureStmts().
This isn't quite NFC because I've also fixed a bug that I'm surprised we
haven't encountered yet. It now checks there are at least the expected
number of operands before accessing them with getOperand().
Depends on D30531
Reviewers: t.p.northover, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: rovka
Subscribers: dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D30535
llvm-svn: 298257
2017-03-20 23:20:42 +08:00
|
|
|
for (auto &Rule : Rules) {
|
2017-07-27 19:03:45 +08:00
|
|
|
Rule.emit(Table);
|
2017-02-10 12:00:17 +08:00
|
|
|
++NumPatternEmitted;
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
2017-07-27 19:03:45 +08:00
|
|
|
Table << MatchTable::Opcode("GIM_Reject") << MatchTable::LineBreak;
|
|
|
|
Table.emitDeclaration(OS);
|
|
|
|
OS << " if (executeMatchTable(*this, OutMIs, State, MatcherInfo, ";
|
|
|
|
Table.emitUse(OS);
|
|
|
|
OS << ", TII, MRI, TRI, RBI, AvailableFeatures)) {\n"
|
|
|
|
<< " return true;\n"
|
|
|
|
<< " }\n\n";
|
2016-12-22 07:26:20 +08:00
|
|
|
|
2017-03-15 05:32:08 +08:00
|
|
|
OS << " return false;\n"
|
|
|
|
<< "}\n"
|
|
|
|
<< "#endif // ifdef GET_GLOBALISEL_IMPL\n";
|
2017-04-30 01:30:09 +08:00
|
|
|
|
|
|
|
OS << "#ifdef GET_GLOBALISEL_PREDICATES_DECL\n"
|
|
|
|
<< "PredicateBitset AvailableModuleFeatures;\n"
|
|
|
|
<< "mutable PredicateBitset AvailableFunctionFeatures;\n"
|
|
|
|
<< "PredicateBitset getAvailableFeatures() const {\n"
|
|
|
|
<< " return AvailableModuleFeatures | AvailableFunctionFeatures;\n"
|
|
|
|
<< "}\n"
|
|
|
|
<< "PredicateBitset\n"
|
|
|
|
<< "computeAvailableModuleFeatures(const " << Target.getName()
|
|
|
|
<< "Subtarget *Subtarget) const;\n"
|
|
|
|
<< "PredicateBitset\n"
|
|
|
|
<< "computeAvailableFunctionFeatures(const " << Target.getName()
|
|
|
|
<< "Subtarget *Subtarget,\n"
|
|
|
|
<< " const MachineFunction *MF) const;\n"
|
|
|
|
<< "#endif // ifdef GET_GLOBALISEL_PREDICATES_DECL\n";
|
|
|
|
|
|
|
|
OS << "#ifdef GET_GLOBALISEL_PREDICATES_INIT\n"
|
|
|
|
<< "AvailableModuleFeatures(computeAvailableModuleFeatures(&STI)),\n"
|
|
|
|
<< "AvailableFunctionFeatures()\n"
|
|
|
|
<< "#endif // ifdef GET_GLOBALISEL_PREDICATES_INIT\n";
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
|
|
|
|
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary:
The SelectionDAG importer now imports rules with Predicate's attached via
Requires, PredicateControl, etc. These predicates are implemented as
bitset's to allow multiple predicates to be tested together. However,
unlike the MC layer subtarget features, each target only pays for it's own
predicates (e.g. AArch64 doesn't have 192 feature bits just because X86
needs a lot).
Both AArch64 and X86 derive at least one predicate from the MachineFunction
or Function so they must re-initialize AvailableFeatures before each
function. They also declare locals in <Target>InstructionSelector so that
computeAvailableFeatures() can use the code from SelectionDAG without
modification.
Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab
Reviewed By: rovka
Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D31418
llvm-svn: 300993
2017-04-21 23:59:56 +08:00
|
|
|
void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {
|
|
|
|
if (SubtargetFeatures.count(Predicate) == 0)
|
|
|
|
SubtargetFeatures.emplace(
|
|
|
|
Predicate, SubtargetFeatureInfo(Predicate, SubtargetFeatures.size()));
|
|
|
|
}
|
|
|
|
|
2017-02-10 12:00:17 +08:00
|
|
|
} // end anonymous namespace
|
|
|
|
|
2016-12-22 07:26:20 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS) {
|
|
|
|
GlobalISelEmitter(RK).run(OS);
|
|
|
|
}
|
|
|
|
} // End llvm namespace
|