2016-12-22 07:26:20 +08:00
|
|
|
//===- GlobalISelEmitter.cpp - Generate an instruction selector -----------===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2016-12-22 07:26:20 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
/// \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"
|
[globalisel][tablegen] Generate rule coverage and use it to identify untested rules
Summary:
This patch adds a LLVM_ENABLE_GISEL_COV which, like LLVM_ENABLE_DAGISEL_COV,
causes TableGen to instrument the generated table to collect rule coverage
information. However, LLVM_ENABLE_GISEL_COV goes a bit further than
LLVM_ENABLE_DAGISEL_COV. The information is written to files
(${CMAKE_BINARY_DIR}/gisel-coverage-* by default). These files can then be
concatenated into ${LLVM_GISEL_COV_PREFIX}-all after which TableGen will
read this information and use it to emit warnings about untested rules.
This technique could also be used by SelectionDAG and can be further
extended to detect hot rules and give them priority over colder rules.
Usage:
* Enable LLVM_ENABLE_GISEL_COV in CMake
* Build the compiler and run some tests
* cat gisel-coverage-[0-9]* > gisel-coverage-all
* Delete lib/Target/*/*GenGlobalISel.inc*
* Build the compiler
Known issues:
* ${LLVM_GISEL_COV_PREFIX}-all must be generated as a manual
step due to a lack of a portable 'cat' command. It should be the
concatenation of all ${LLVM_GISEL_COV_PREFIX}-[0-9]* files.
* There's no mechanism to discard coverage information when the ruleset
changes
Depends on D39742
Reviewers: ab, qcolombet, t.p.northover, aditya_nandakumar, rovka
Reviewed By: rovka
Subscribers: vsk, arsenm, nhaehnle, mgorny, kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D39747
llvm-svn: 318356
2017-11-16 08:46:35 +08:00
|
|
|
#include "llvm/Support/CodeGenCoverage.h"
|
2016-12-22 07:26:20 +08:00
|
|
|
#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"
|
2018-03-24 07:58:25 +08:00
|
|
|
#include "llvm/Support/MachineValueType.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"
|
2017-03-15 05:32:08 +08:00
|
|
|
#include <numeric>
|
[globalisel][tablegen] Generate rule coverage and use it to identify untested rules
Summary:
This patch adds a LLVM_ENABLE_GISEL_COV which, like LLVM_ENABLE_DAGISEL_COV,
causes TableGen to instrument the generated table to collect rule coverage
information. However, LLVM_ENABLE_GISEL_COV goes a bit further than
LLVM_ENABLE_DAGISEL_COV. The information is written to files
(${CMAKE_BINARY_DIR}/gisel-coverage-* by default). These files can then be
concatenated into ${LLVM_GISEL_COV_PREFIX}-all after which TableGen will
read this information and use it to emit warnings about untested rules.
This technique could also be used by SelectionDAG and can be further
extended to detect hot rules and give them priority over colder rules.
Usage:
* Enable LLVM_ENABLE_GISEL_COV in CMake
* Build the compiler and run some tests
* cat gisel-coverage-[0-9]* > gisel-coverage-all
* Delete lib/Target/*/*GenGlobalISel.inc*
* Build the compiler
Known issues:
* ${LLVM_GISEL_COV_PREFIX}-all must be generated as a manual
step due to a lack of a portable 'cat' command. It should be the
concatenation of all ${LLVM_GISEL_COV_PREFIX}-[0-9]* files.
* There's no mechanism to discard coverage information when the ruleset
changes
Depends on D39742
Reviewers: ab, qcolombet, t.p.northover, aditya_nandakumar, rovka
Reviewed By: rovka
Subscribers: vsk, arsenm, nhaehnle, mgorny, kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D39747
llvm-svn: 318356
2017-11-16 08:46:35 +08:00
|
|
|
#include <string>
|
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");
|
[globalisel][tablegen] Generate rule coverage and use it to identify untested rules
Summary:
This patch adds a LLVM_ENABLE_GISEL_COV which, like LLVM_ENABLE_DAGISEL_COV,
causes TableGen to instrument the generated table to collect rule coverage
information. However, LLVM_ENABLE_GISEL_COV goes a bit further than
LLVM_ENABLE_DAGISEL_COV. The information is written to files
(${CMAKE_BINARY_DIR}/gisel-coverage-* by default). These files can then be
concatenated into ${LLVM_GISEL_COV_PREFIX}-all after which TableGen will
read this information and use it to emit warnings about untested rules.
This technique could also be used by SelectionDAG and can be further
extended to detect hot rules and give them priority over colder rules.
Usage:
* Enable LLVM_ENABLE_GISEL_COV in CMake
* Build the compiler and run some tests
* cat gisel-coverage-[0-9]* > gisel-coverage-all
* Delete lib/Target/*/*GenGlobalISel.inc*
* Build the compiler
Known issues:
* ${LLVM_GISEL_COV_PREFIX}-all must be generated as a manual
step due to a lack of a portable 'cat' command. It should be the
concatenation of all ${LLVM_GISEL_COV_PREFIX}-[0-9]* files.
* There's no mechanism to discard coverage information when the ruleset
changes
Depends on D39742
Reviewers: ab, qcolombet, t.p.northover, aditya_nandakumar, rovka
Reviewed By: rovka
Subscribers: vsk, arsenm, nhaehnle, mgorny, kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D39747
llvm-svn: 318356
2017-11-16 08:46:35 +08:00
|
|
|
STATISTIC(NumPatternsTested, "Number of patterns executed according to coverage information");
|
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
|
|
|
|
[globalisel][tablegen] Generate rule coverage and use it to identify untested rules
Summary:
This patch adds a LLVM_ENABLE_GISEL_COV which, like LLVM_ENABLE_DAGISEL_COV,
causes TableGen to instrument the generated table to collect rule coverage
information. However, LLVM_ENABLE_GISEL_COV goes a bit further than
LLVM_ENABLE_DAGISEL_COV. The information is written to files
(${CMAKE_BINARY_DIR}/gisel-coverage-* by default). These files can then be
concatenated into ${LLVM_GISEL_COV_PREFIX}-all after which TableGen will
read this information and use it to emit warnings about untested rules.
This technique could also be used by SelectionDAG and can be further
extended to detect hot rules and give them priority over colder rules.
Usage:
* Enable LLVM_ENABLE_GISEL_COV in CMake
* Build the compiler and run some tests
* cat gisel-coverage-[0-9]* > gisel-coverage-all
* Delete lib/Target/*/*GenGlobalISel.inc*
* Build the compiler
Known issues:
* ${LLVM_GISEL_COV_PREFIX}-all must be generated as a manual
step due to a lack of a portable 'cat' command. It should be the
concatenation of all ${LLVM_GISEL_COV_PREFIX}-[0-9]* files.
* There's no mechanism to discard coverage information when the ruleset
changes
Depends on D39742
Reviewers: ab, qcolombet, t.p.northover, aditya_nandakumar, rovka
Reviewed By: rovka
Subscribers: vsk, arsenm, nhaehnle, mgorny, kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D39747
llvm-svn: 318356
2017-11-16 08:46:35 +08:00
|
|
|
static cl::opt<bool> GenerateCoverage(
|
|
|
|
"instrument-gisel-coverage",
|
|
|
|
cl::desc("Generate coverage instrumentation for GlobalISel"),
|
|
|
|
cl::init(false), cl::cat(GlobalISelEmitterCat));
|
|
|
|
|
|
|
|
static cl::opt<std::string> UseCoverageFile(
|
|
|
|
"gisel-coverage-file", cl::init(""),
|
|
|
|
cl::desc("Specify file to retrieve coverage information from"),
|
|
|
|
cl::cat(GlobalISelEmitterCat));
|
|
|
|
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
static cl::opt<bool> OptimizeMatchTable(
|
|
|
|
"optimize-match-table",
|
|
|
|
cl::desc("Generate an optimized version of the match table"),
|
|
|
|
cl::init(true), cl::cat(GlobalISelEmitterCat));
|
|
|
|
|
2017-03-16 04:18:38 +08:00
|
|
|
namespace {
|
2016-12-22 07:26:20 +08:00
|
|
|
//===- Helper functions ---------------------------------------------------===//
|
|
|
|
|
[globalisel][tablegen] Add support for fpimm and import of APInt/APFloat based ImmLeaf.
Summary:
There's only a tablegen testcase for IntImmLeaf and not a CodeGen one
because the relevant rules are rejected for other reasons at the moment.
On AArch64, it's because there's an SDNodeXForm attached to the operand.
On X86, it's because the rule either emits multiple instructions or has
another predicate using PatFrag which cannot easily be supported at the
same time.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36569
llvm-svn: 315761
2017-10-14 05:28:03 +08:00
|
|
|
/// Get the name of the enum value used to number the predicate function.
|
|
|
|
std::string getEnumNameForPredicate(const TreePredicateFn &Predicate) {
|
2018-06-16 07:13:43 +08:00
|
|
|
if (Predicate.hasGISelPredicateCode())
|
|
|
|
return "GIPFP_MI_" + Predicate.getFnName();
|
2017-10-15 05:27:53 +08:00
|
|
|
return "GIPFP_" + Predicate.getImmTypeIdentifier().str() + "_" +
|
[globalisel][tablegen] Add support for fpimm and import of APInt/APFloat based ImmLeaf.
Summary:
There's only a tablegen testcase for IntImmLeaf and not a CodeGen one
because the relevant rules are rejected for other reasons at the moment.
On AArch64, it's because there's an SDNodeXForm attached to the operand.
On X86, it's because the rule either emits multiple instructions or has
another predicate using PatFrag which cannot easily be supported at the
same time.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36569
llvm-svn: 315761
2017-10-14 05:28:03 +08:00
|
|
|
Predicate.getFnName();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the opcode used to check this predicate.
|
|
|
|
std::string getMatchOpcodeForPredicate(const TreePredicateFn &Predicate) {
|
2017-10-15 05:27:53 +08:00
|
|
|
return "GIM_Check" + Predicate.getImmTypeIdentifier().str() + "ImmPredicate";
|
[globalisel][tablegen] Add support for fpimm and import of APInt/APFloat based ImmLeaf.
Summary:
There's only a tablegen testcase for IntImmLeaf and not a CodeGen one
because the relevant rules are rejected for other reasons at the moment.
On AArch64, it's because there's an SDNodeXForm attached to the operand.
On X86, it's because the rule either emits multiple instructions or has
another predicate using PatFrag which cannot easily be supported at the
same time.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36569
llvm-svn: 315761
2017-10-14 05:28:03 +08:00
|
|
|
}
|
|
|
|
|
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:
|
2018-05-22 07:28:51 +08:00
|
|
|
LLTCodeGen() = default;
|
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(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;
|
|
|
|
}
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
if (Ty.isPointer()) {
|
|
|
|
OS << "GILLT_p" << Ty.getAddressSpace();
|
|
|
|
if (Ty.getSizeInBits() > 0)
|
|
|
|
OS << "s" << Ty.getSizeInBits();
|
|
|
|
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
|
|
|
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;
|
|
|
|
}
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
if (Ty.isPointer() && Ty.getSizeInBits() > 0) {
|
|
|
|
OS << "LLT::pointer(" << Ty.getAddressSpace() << ", "
|
|
|
|
<< Ty.getSizeInBits() << ")";
|
|
|
|
return;
|
|
|
|
}
|
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
|
|
|
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
|
|
|
|
2018-04-07 04:18:05 +08:00
|
|
|
/// This ordering is used for std::unique() and llvm::sort(). There's no
|
2017-08-17 21:18:35 +08:00
|
|
|
/// particular logic behind the order but either A < B or B < A must be
|
|
|
|
/// true if A != B.
|
[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
|
|
|
bool operator<(const LLTCodeGen &Other) const {
|
2017-08-17 21:18:35 +08:00
|
|
|
if (Ty.isValid() != Other.Ty.isValid())
|
|
|
|
return Ty.isValid() < Other.Ty.isValid();
|
[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 (!Ty.isValid())
|
2017-08-12 03:19:21 +08:00
|
|
|
return false;
|
2017-08-17 21:18:35 +08:00
|
|
|
|
|
|
|
if (Ty.isVector() != Other.Ty.isVector())
|
|
|
|
return Ty.isVector() < Other.Ty.isVector();
|
|
|
|
if (Ty.isScalar() != Other.Ty.isScalar())
|
|
|
|
return Ty.isScalar() < Other.Ty.isScalar();
|
|
|
|
if (Ty.isPointer() != Other.Ty.isPointer())
|
|
|
|
return Ty.isPointer() < Other.Ty.isPointer();
|
|
|
|
|
|
|
|
if (Ty.isPointer() && Ty.getAddressSpace() != Other.Ty.getAddressSpace())
|
|
|
|
return Ty.getAddressSpace() < Other.Ty.getAddressSpace();
|
|
|
|
|
|
|
|
if (Ty.isVector() && Ty.getNumElements() != Other.Ty.getNumElements())
|
|
|
|
return Ty.getNumElements() < Other.Ty.getNumElements();
|
|
|
|
|
|
|
|
return Ty.getSizeInBits() < Other.Ty.getSizeInBits();
|
[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-12-16 07:24:39 +08:00
|
|
|
|
|
|
|
bool operator==(const LLTCodeGen &B) const { return Ty == B.Ty; }
|
2017-03-15 05:32:08 +08:00
|
|
|
};
|
|
|
|
|
[globalisel] Update GlobalISel emitter to match new representation of extending loads
Summary:
Previously, a extending load was represented at (G_*EXT (G_LOAD x)).
This had a few drawbacks:
* G_LOAD had to be legal for all sizes you could extend from, even if
registers didn't naturally hold those sizes.
* All sizes you could extend from had to be allocatable just in case the
extend went missing (e.g. by optimization).
* At minimum, G_*EXT and G_TRUNC had to be legal for these sizes. As we
improve optimization of extends and truncates, this legality requirement
would spread without considerable care w.r.t when certain combines were
permitted.
* The SelectionDAG importer required some ugly and fragile pattern
rewriting to translate patterns into this style.
This patch changes the representation to:
* (G_[SZ]EXTLOAD x)
* (G_LOAD x) any-extends when MMO.getSize() * 8 < ResultTy.getSizeInBits()
which resolves these issues by allowing targets to work entirely in their
native register sizes, and by having a more direct translation from
SelectionDAG patterns.
Each extending load can be lowered by the legalizer into separate extends
and loads, however a target that supports s1 will need the any-extending
load to extend to at least s8 since LLVM does not represent memory accesses
smaller than 8 bit. The legalizer can widenScalar G_LOAD into an
any-extending load but sign/zero-extending loads need help from something
else like a combiner pass. A follow-up patch that adds combiner helpers for
for this will follow.
The new representation requires that the MMO correctly reflect the memory
access so this has been corrected in a couple tests. I've also moved the
extending loads to their own tests since they are (mostly) separate opcodes
now. Additionally, the re-write appears to have invalidated two tests from
select-with-no-legality-check.mir since the matcher table no longer contains
loads that result in s1's and they aren't legal in AArch64 anymore.
Depends on D45540
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar
Reviewed By: rtereshin
Subscribers: javed.absar, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D45541
llvm-svn: 331601
2018-05-06 04:53:24 +08:00
|
|
|
// Track all types that are used so we can emit the corresponding enum.
|
|
|
|
std::set<LLTCodeGen> KnownTypes;
|
|
|
|
|
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);
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
|
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()));
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
static std::string explainPredicates(const TreePatternNode *N) {
|
2017-04-13 17:45:37 +08:00
|
|
|
std::string Explanation = "";
|
|
|
|
StringRef Separator = "";
|
TableGen/ISel: Allow PatFrag predicate code to access captured operands
Summary:
This simplifies writing predicates for pattern fragments that are
automatically re-associated or commuted.
For example, a followup patch adds patterns for fragments of the form
(add (shl $x, $y), $z) to the AMDGPU backend. Such patterns are
automatically commuted to (add $z, (shl $x, $y)), which makes it basically
impossible to refer to $x, $y, and $z generically in the PredicateCode.
With this change, the PredicateCode can refer to $x, $y, and $z simply
as `Operands[i]`.
Test confirmed that there are no changes to any of the generated files
when building all (non-experimental) targets.
Change-Id: I61c00ace7eed42c1d4edc4c5351174b56b77a79c
Reviewers: arsenm, rampitec, RKSimon, craig.topper, hfinkel, uweigand
Subscribers: wdng, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D51994
llvm-svn: 347992
2018-11-30 22:15:13 +08:00
|
|
|
for (const TreePredicateCall &Call : N->getPredicateCalls()) {
|
|
|
|
const TreePredicateFn &P = Call.Fn;
|
2017-04-13 17:45:37 +08:00
|
|
|
Explanation +=
|
|
|
|
(Separator + P.getOrigPatFragRecord()->getRecord()->getName()).str();
|
2017-11-29 06:07:05 +08:00
|
|
|
Separator = ", ";
|
|
|
|
|
2017-04-13 17:45:37 +08:00
|
|
|
if (P.isAlwaysTrue())
|
|
|
|
Explanation += " always-true";
|
|
|
|
if (P.isImmediatePattern())
|
|
|
|
Explanation += " immediate";
|
2017-10-15 10:06:44 +08:00
|
|
|
|
|
|
|
if (P.isUnindexed())
|
|
|
|
Explanation += " unindexed";
|
|
|
|
|
|
|
|
if (P.isNonExtLoad())
|
|
|
|
Explanation += " non-extload";
|
|
|
|
if (P.isAnyExtLoad())
|
|
|
|
Explanation += " extload";
|
|
|
|
if (P.isSignExtLoad())
|
|
|
|
Explanation += " sextload";
|
|
|
|
if (P.isZeroExtLoad())
|
|
|
|
Explanation += " zextload";
|
|
|
|
|
|
|
|
if (P.isNonTruncStore())
|
|
|
|
Explanation += " non-truncstore";
|
|
|
|
if (P.isTruncStore())
|
|
|
|
Explanation += " truncstore";
|
|
|
|
|
|
|
|
if (Record *VT = P.getMemoryVT())
|
|
|
|
Explanation += (" MemVT=" + VT->getName()).str();
|
|
|
|
if (Record *VT = P.getScalarMemoryVT())
|
|
|
|
Explanation += (" ScalarVT(MemVT)=" + VT->getName()).str();
|
2017-11-29 06:07:05 +08:00
|
|
|
|
|
|
|
if (P.isAtomicOrderingMonotonic())
|
|
|
|
Explanation += " monotonic";
|
|
|
|
if (P.isAtomicOrderingAcquire())
|
|
|
|
Explanation += " acquire";
|
|
|
|
if (P.isAtomicOrderingRelease())
|
|
|
|
Explanation += " release";
|
|
|
|
if (P.isAtomicOrderingAcquireRelease())
|
|
|
|
Explanation += " acq_rel";
|
|
|
|
if (P.isAtomicOrderingSequentiallyConsistent())
|
|
|
|
Explanation += " seq_cst";
|
2017-12-01 05:05:59 +08:00
|
|
|
if (P.isAtomicOrderingAcquireOrStronger())
|
|
|
|
Explanation += " >=acquire";
|
|
|
|
if (P.isAtomicOrderingWeakerThanAcquire())
|
|
|
|
Explanation += " <acquire";
|
|
|
|
if (P.isAtomicOrderingReleaseOrStronger())
|
|
|
|
Explanation += " >=release";
|
|
|
|
if (P.isAtomicOrderingWeakerThanRelease())
|
|
|
|
Explanation += " <release";
|
2017-04-13 17:45:37 +08:00
|
|
|
}
|
|
|
|
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();
|
|
|
|
|
2017-10-16 02:22:54 +08:00
|
|
|
if (Operator->isSubClassOf("ComplexPattern"))
|
|
|
|
return (" (Operator is an unmapped ComplexPattern, " + Operator->getName() +
|
|
|
|
")")
|
|
|
|
.str();
|
|
|
|
|
2018-01-17 02:44:05 +08:00
|
|
|
if (Operator->isSubClassOf("SDNodeXForm"))
|
|
|
|
return (" (Operator is an unmapped SDNodeXForm, " + Operator->getName() +
|
|
|
|
")")
|
|
|
|
.str();
|
|
|
|
|
2017-10-16 02:22:54 +08:00
|
|
|
return (" (Operator " + Operator->getName() + " not understood)").str();
|
2017-04-13 17:45:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Helper function to let the emitter report skip reason error messages.
|
|
|
|
static Error failedImport(const Twine &Reason) {
|
|
|
|
return make_error<StringError>(Reason, inconvertibleErrorCode());
|
|
|
|
}
|
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
static Error isTrivialOperatorNode(const TreePatternNode *N) {
|
2017-04-13 17:45:37 +08:00
|
|
|
std::string Explanation = "";
|
|
|
|
std::string Separator = "";
|
2017-08-24 17:11:20 +08:00
|
|
|
|
|
|
|
bool HasUnsupportedPredicate = false;
|
TableGen/ISel: Allow PatFrag predicate code to access captured operands
Summary:
This simplifies writing predicates for pattern fragments that are
automatically re-associated or commuted.
For example, a followup patch adds patterns for fragments of the form
(add (shl $x, $y), $z) to the AMDGPU backend. Such patterns are
automatically commuted to (add $z, (shl $x, $y)), which makes it basically
impossible to refer to $x, $y, and $z generically in the PredicateCode.
With this change, the PredicateCode can refer to $x, $y, and $z simply
as `Operands[i]`.
Test confirmed that there are no changes to any of the generated files
when building all (non-experimental) targets.
Change-Id: I61c00ace7eed42c1d4edc4c5351174b56b77a79c
Reviewers: arsenm, rampitec, RKSimon, craig.topper, hfinkel, uweigand
Subscribers: wdng, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D51994
llvm-svn: 347992
2018-11-30 22:15:13 +08:00
|
|
|
for (const TreePredicateCall &Call : N->getPredicateCalls()) {
|
|
|
|
const TreePredicateFn &Predicate = Call.Fn;
|
|
|
|
|
2017-08-24 17:11:20 +08:00
|
|
|
if (Predicate.isAlwaysTrue())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (Predicate.isImmediatePattern())
|
|
|
|
continue;
|
|
|
|
|
[globalisel] Update GlobalISel emitter to match new representation of extending loads
Summary:
Previously, a extending load was represented at (G_*EXT (G_LOAD x)).
This had a few drawbacks:
* G_LOAD had to be legal for all sizes you could extend from, even if
registers didn't naturally hold those sizes.
* All sizes you could extend from had to be allocatable just in case the
extend went missing (e.g. by optimization).
* At minimum, G_*EXT and G_TRUNC had to be legal for these sizes. As we
improve optimization of extends and truncates, this legality requirement
would spread without considerable care w.r.t when certain combines were
permitted.
* The SelectionDAG importer required some ugly and fragile pattern
rewriting to translate patterns into this style.
This patch changes the representation to:
* (G_[SZ]EXTLOAD x)
* (G_LOAD x) any-extends when MMO.getSize() * 8 < ResultTy.getSizeInBits()
which resolves these issues by allowing targets to work entirely in their
native register sizes, and by having a more direct translation from
SelectionDAG patterns.
Each extending load can be lowered by the legalizer into separate extends
and loads, however a target that supports s1 will need the any-extending
load to extend to at least s8 since LLVM does not represent memory accesses
smaller than 8 bit. The legalizer can widenScalar G_LOAD into an
any-extending load but sign/zero-extending loads need help from something
else like a combiner pass. A follow-up patch that adds combiner helpers for
for this will follow.
The new representation requires that the MMO correctly reflect the memory
access so this has been corrected in a couple tests. I've also moved the
extending loads to their own tests since they are (mostly) separate opcodes
now. Additionally, the re-write appears to have invalidated two tests from
select-with-no-legality-check.mir since the matcher table no longer contains
loads that result in s1's and they aren't legal in AArch64 anymore.
Depends on D45540
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar
Reviewed By: rtereshin
Subscribers: javed.absar, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D45541
llvm-svn: 331601
2018-05-06 04:53:24 +08:00
|
|
|
if (Predicate.isNonExtLoad() || Predicate.isAnyExtLoad() ||
|
|
|
|
Predicate.isSignExtLoad() || Predicate.isZeroExtLoad())
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
continue;
|
|
|
|
|
2017-11-29 06:07:05 +08:00
|
|
|
if (Predicate.isNonTruncStore())
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
continue;
|
2017-10-24 02:19:24 +08:00
|
|
|
|
[globalisel] Update GlobalISel emitter to match new representation of extending loads
Summary:
Previously, a extending load was represented at (G_*EXT (G_LOAD x)).
This had a few drawbacks:
* G_LOAD had to be legal for all sizes you could extend from, even if
registers didn't naturally hold those sizes.
* All sizes you could extend from had to be allocatable just in case the
extend went missing (e.g. by optimization).
* At minimum, G_*EXT and G_TRUNC had to be legal for these sizes. As we
improve optimization of extends and truncates, this legality requirement
would spread without considerable care w.r.t when certain combines were
permitted.
* The SelectionDAG importer required some ugly and fragile pattern
rewriting to translate patterns into this style.
This patch changes the representation to:
* (G_[SZ]EXTLOAD x)
* (G_LOAD x) any-extends when MMO.getSize() * 8 < ResultTy.getSizeInBits()
which resolves these issues by allowing targets to work entirely in their
native register sizes, and by having a more direct translation from
SelectionDAG patterns.
Each extending load can be lowered by the legalizer into separate extends
and loads, however a target that supports s1 will need the any-extending
load to extend to at least s8 since LLVM does not represent memory accesses
smaller than 8 bit. The legalizer can widenScalar G_LOAD into an
any-extending load but sign/zero-extending loads need help from something
else like a combiner pass. A follow-up patch that adds combiner helpers for
for this will follow.
The new representation requires that the MMO correctly reflect the memory
access so this has been corrected in a couple tests. I've also moved the
extending loads to their own tests since they are (mostly) separate opcodes
now. Additionally, the re-write appears to have invalidated two tests from
select-with-no-legality-check.mir since the matcher table no longer contains
loads that result in s1's and they aren't legal in AArch64 anymore.
Depends on D45540
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar
Reviewed By: rtereshin
Subscribers: javed.absar, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D45541
llvm-svn: 331601
2018-05-06 04:53:24 +08:00
|
|
|
if (Predicate.isLoad() && Predicate.getMemoryVT())
|
|
|
|
continue;
|
|
|
|
|
2017-11-29 06:07:05 +08:00
|
|
|
if (Predicate.isLoad() || Predicate.isStore()) {
|
|
|
|
if (Predicate.isUnindexed())
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Predicate.isAtomic() && Predicate.getMemoryVT())
|
2017-10-24 02:19:24 +08:00
|
|
|
continue;
|
|
|
|
|
2017-11-29 06:07:05 +08:00
|
|
|
if (Predicate.isAtomic() &&
|
|
|
|
(Predicate.isAtomicOrderingMonotonic() ||
|
|
|
|
Predicate.isAtomicOrderingAcquire() ||
|
|
|
|
Predicate.isAtomicOrderingRelease() ||
|
|
|
|
Predicate.isAtomicOrderingAcquireRelease() ||
|
2017-12-01 05:05:59 +08:00
|
|
|
Predicate.isAtomicOrderingSequentiallyConsistent() ||
|
|
|
|
Predicate.isAtomicOrderingAcquireOrStronger() ||
|
|
|
|
Predicate.isAtomicOrderingWeakerThanAcquire() ||
|
|
|
|
Predicate.isAtomicOrderingReleaseOrStronger() ||
|
|
|
|
Predicate.isAtomicOrderingWeakerThanRelease()))
|
2017-10-24 02:19:24 +08:00
|
|
|
continue;
|
|
|
|
|
2018-06-16 07:13:43 +08:00
|
|
|
if (Predicate.hasGISelPredicateCode())
|
|
|
|
continue;
|
|
|
|
|
2017-08-24 17:11:20 +08:00
|
|
|
HasUnsupportedPredicate = true;
|
2017-04-13 17:45:37 +08:00
|
|
|
Explanation = Separator + "Has a predicate (" + explainPredicates(N) + ")";
|
|
|
|
Separator = ", ";
|
2017-10-15 10:06:44 +08:00
|
|
|
Explanation += (Separator + "first-failing:" +
|
|
|
|
Predicate.getOrigPatFragRecord()->getRecord()->getName())
|
|
|
|
.str();
|
2017-08-24 17:11:20 +08:00
|
|
|
break;
|
2017-04-13 17:45:37 +08:00
|
|
|
}
|
|
|
|
|
2018-01-17 02:44:05 +08:00
|
|
|
if (!HasUnsupportedPredicate)
|
2017-04-13 17:45:37 +08:00
|
|
|
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;
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
/// The actual run-time value, if known
|
|
|
|
int64_t RawValue;
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
MatchTableRecord(Optional<unsigned> LabelID_, StringRef EmitStr,
|
2018-05-22 07:28:51 +08:00
|
|
|
unsigned NumElements, unsigned Flags,
|
|
|
|
int64_t RawValue = std::numeric_limits<int64_t>::min())
|
2017-07-20 17:25:44 +08:00
|
|
|
: LabelID(LabelID_.hasValue() ? LabelID_.getValue() : ~0u),
|
2018-05-22 07:28:51 +08:00
|
|
|
EmitStr(EmitStr), NumElements(NumElements), Flags(Flags),
|
|
|
|
RawValue(RawValue) {
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
assert((!LabelID_.hasValue() || LabelID != ~0u) &&
|
|
|
|
"This value is reserved for non-labels");
|
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
MatchTableRecord(const MatchTableRecord &Other) = default;
|
|
|
|
MatchTableRecord(MatchTableRecord &&Other) = default;
|
|
|
|
|
|
|
|
/// Useful if a Match Table Record gets optimized out
|
|
|
|
void turnIntoComment() {
|
|
|
|
Flags |= MTRF_Comment;
|
|
|
|
Flags &= ~MTRF_CommaFollows;
|
|
|
|
NumElements = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// For Jump Table generation purposes
|
|
|
|
bool operator<(const MatchTableRecord &Other) const {
|
|
|
|
return RawValue < Other.RawValue;
|
|
|
|
}
|
|
|
|
int64_t getRawValue() const { return RawValue; }
|
2017-07-20 17:25:44 +08:00
|
|
|
|
|
|
|
void emit(raw_ostream &OS, bool LineBreakNextAfterThis,
|
|
|
|
const MatchTable &Table) const;
|
|
|
|
unsigned size() const { return NumElements; }
|
|
|
|
};
|
|
|
|
|
2018-05-03 04:08:14 +08:00
|
|
|
class Matcher;
|
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
/// 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.
|
2018-05-03 04:08:14 +08:00
|
|
|
unsigned CurrentSize = 0;
|
2017-07-27 19:03:45 +08:00
|
|
|
/// A unique identifier for a MatchTable label.
|
2018-05-03 04:08:14 +08:00
|
|
|
unsigned CurrentLabelID = 0;
|
2018-05-03 04:15:11 +08:00
|
|
|
/// Determines if the table should be instrumented for rule coverage tracking.
|
|
|
|
bool IsWithCoverage;
|
2017-07-27 19:03:45 +08:00
|
|
|
|
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);
|
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
static MatchTableRecord NamedValue(StringRef NamedValue, int64_t RawValue) {
|
|
|
|
return MatchTableRecord(None, NamedValue, 1,
|
|
|
|
MatchTableRecord::MTRF_CommaFollows, RawValue);
|
|
|
|
}
|
2017-07-20 17:25:44 +08:00
|
|
|
static MatchTableRecord NamedValue(StringRef Namespace,
|
|
|
|
StringRef NamedValue) {
|
|
|
|
return MatchTableRecord(None, (Namespace + "::" + NamedValue).str(), 1,
|
|
|
|
MatchTableRecord::MTRF_CommaFollows);
|
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
static MatchTableRecord NamedValue(StringRef Namespace, StringRef NamedValue,
|
|
|
|
int64_t RawValue) {
|
|
|
|
return MatchTableRecord(None, (Namespace + "::" + NamedValue).str(), 1,
|
|
|
|
MatchTableRecord::MTRF_CommaFollows, RawValue);
|
|
|
|
}
|
2017-07-20 17:25:44 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2018-05-03 04:15:11 +08:00
|
|
|
static MatchTable buildTable(ArrayRef<Matcher *> Rules, bool WithCoverage);
|
2018-05-03 04:08:14 +08:00
|
|
|
|
2018-05-03 04:15:11 +08:00
|
|
|
MatchTable(bool WithCoverage, unsigned ID = 0)
|
|
|
|
: ID(ID), IsWithCoverage(WithCoverage) {}
|
|
|
|
|
|
|
|
bool isWithCoverage() const { return IsWithCoverage; }
|
2017-07-20 17:25:44 +08:00
|
|
|
|
|
|
|
void push_back(const MatchTableRecord &Value) {
|
|
|
|
if (Value.Flags & MatchTableRecord::MTRF_Label)
|
|
|
|
defineLabel(Value.LabelID);
|
|
|
|
Contents.push_back(Value);
|
|
|
|
CurrentSize += Value.size();
|
|
|
|
}
|
|
|
|
|
2018-05-03 04:08:14 +08:00
|
|
|
unsigned allocateLabelID() { return CurrentLabelID++; }
|
2017-07-27 19:03:45 +08:00
|
|
|
|
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";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
class PredicateMatcher;
|
|
|
|
class RuleMatcher;
|
|
|
|
|
|
|
|
class Matcher {
|
|
|
|
public:
|
|
|
|
virtual ~Matcher() = default;
|
2018-05-22 07:28:51 +08:00
|
|
|
virtual void optimize() {}
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
virtual void emit(MatchTable &Table) = 0;
|
2018-05-22 07:28:51 +08:00
|
|
|
|
|
|
|
virtual bool hasFirstCondition() const = 0;
|
|
|
|
virtual const PredicateMatcher &getFirstCondition() const = 0;
|
|
|
|
virtual std::unique_ptr<PredicateMatcher> popFirstCondition() = 0;
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
};
|
|
|
|
|
2018-05-03 04:15:11 +08:00
|
|
|
MatchTable MatchTable::buildTable(ArrayRef<Matcher *> Rules,
|
|
|
|
bool WithCoverage) {
|
|
|
|
MatchTable Table(WithCoverage);
|
2018-05-03 04:08:14 +08:00
|
|
|
for (Matcher *Rule : Rules)
|
|
|
|
Rule->emit(Table);
|
|
|
|
|
|
|
|
return Table << MatchTable::Opcode("GIM_Reject") << MatchTable::LineBreak;
|
|
|
|
}
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
class GroupMatcher final : public Matcher {
|
|
|
|
/// Conditions that form a common prefix of all the matchers contained.
|
|
|
|
SmallVector<std::unique_ptr<PredicateMatcher>, 1> Conditions;
|
|
|
|
|
|
|
|
/// All the nested matchers, sharing a common prefix.
|
|
|
|
std::vector<Matcher *> Matchers;
|
|
|
|
|
|
|
|
/// An owning collection for any auxiliary matchers created while optimizing
|
|
|
|
/// nested matchers contained.
|
|
|
|
std::vector<std::unique_ptr<Matcher>> MatcherStorage;
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
|
|
|
|
public:
|
2018-05-22 07:28:51 +08:00
|
|
|
/// Add a matcher to the collection of nested matchers if it meets the
|
|
|
|
/// requirements, and return true. If it doesn't, do nothing and return false.
|
|
|
|
///
|
|
|
|
/// Expected to preserve its argument, so it could be moved out later on.
|
|
|
|
bool addMatcher(Matcher &Candidate);
|
|
|
|
|
|
|
|
/// Mark the matcher as fully-built and ensure any invariants expected by both
|
|
|
|
/// optimize() and emit(...) methods. Generally, both sequences of calls
|
|
|
|
/// are expected to lead to a sensible result:
|
|
|
|
///
|
|
|
|
/// addMatcher(...)*; finalize(); optimize(); emit(...); and
|
|
|
|
/// addMatcher(...)*; finalize(); emit(...);
|
|
|
|
///
|
|
|
|
/// or generally
|
|
|
|
///
|
|
|
|
/// addMatcher(...)*; finalize(); { optimize()*; emit(...); }*
|
|
|
|
///
|
|
|
|
/// Multiple calls to optimize() are expected to be handled gracefully, though
|
|
|
|
/// optimize() is not expected to be idempotent. Multiple calls to finalize()
|
|
|
|
/// aren't generally supported. emit(...) is expected to be non-mutating and
|
|
|
|
/// producing the exact same results upon repeated calls.
|
|
|
|
///
|
|
|
|
/// addMatcher() calls after the finalize() call are not supported.
|
|
|
|
///
|
|
|
|
/// finalize() and optimize() are both allowed to mutate the contained
|
|
|
|
/// matchers, so moving them out after finalize() is not supported.
|
|
|
|
void finalize();
|
2018-05-23 10:04:19 +08:00
|
|
|
void optimize() override;
|
2018-05-22 07:28:51 +08:00
|
|
|
void emit(MatchTable &Table) override;
|
|
|
|
|
|
|
|
/// Could be used to move out the matchers added previously, unless finalize()
|
|
|
|
/// has been already called. If any of the matchers are moved out, the group
|
|
|
|
/// becomes safe to destroy, but not safe to re-use for anything else.
|
|
|
|
iterator_range<std::vector<Matcher *>::iterator> matchers() {
|
|
|
|
return make_range(Matchers.begin(), Matchers.end());
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
size_t size() const { return Matchers.size(); }
|
|
|
|
bool empty() const { return Matchers.empty(); }
|
|
|
|
|
|
|
|
std::unique_ptr<PredicateMatcher> popFirstCondition() override {
|
|
|
|
assert(!Conditions.empty() &&
|
|
|
|
"Trying to pop a condition from a condition-less group");
|
|
|
|
std::unique_ptr<PredicateMatcher> P = std::move(Conditions.front());
|
|
|
|
Conditions.erase(Conditions.begin());
|
|
|
|
return P;
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
const PredicateMatcher &getFirstCondition() const override {
|
|
|
|
assert(!Conditions.empty() &&
|
|
|
|
"Trying to get a condition from a condition-less group");
|
|
|
|
return *Conditions.front();
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
bool hasFirstCondition() const override { return !Conditions.empty(); }
|
2017-12-19 05:25:53 +08:00
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
private:
|
|
|
|
/// See if a candidate matcher could be added to this group solely by
|
|
|
|
/// analyzing its first condition.
|
|
|
|
bool candidateConditionMatches(const PredicateMatcher &Predicate) const;
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
};
|
2017-03-16 04:18:38 +08:00
|
|
|
|
[GlobalISel][InstructionSelect] Switching MatchTable over opcodes, perf patch 4
This patch continues a series of patches started by r332907 (reapplied
as r332917)
In this commit we introduce a new matching opcode GIM_SwitchOpcode
that implements a jump table over opcodes and start emitting them for
root instructions.
This is expected to decrease time GlobalISel spends in its
InstructionSelect pass by roughly 20% for an -O0 build as measured on
sqlite3-amalgamation (http://sqlite.org/download.html) targeting
AArch64.
To some degree, we assume here that the opcodes form a dense set,
which is true at the moment for all upstream targets given the
limitations of our rule importing mechanism.
It might not be true for out of tree targets, specifically due to
pseudo's. If so, we might noticeably increase the size of the
MatchTable with this patch due to padding zeros. This will be
addressed later.
Reviewers: qcolombet, dsanders, bogner, aemerson, javed.absar
Reviewed By: qcolombet
Subscribers: rovka, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D44700
llvm-svn: 333017
2018-05-23 03:37:59 +08:00
|
|
|
class SwitchMatcher : public Matcher {
|
|
|
|
/// All the nested matchers, representing distinct switch-cases. The first
|
|
|
|
/// conditions (as Matcher::getFirstCondition() reports) of all the nested
|
|
|
|
/// matchers must share the same type and path to a value they check, in other
|
|
|
|
/// words, be isIdenticalDownToValue, but have different values they check
|
|
|
|
/// against.
|
|
|
|
std::vector<Matcher *> Matchers;
|
|
|
|
|
|
|
|
/// The representative condition, with a type and a path (InsnVarID and OpIdx
|
|
|
|
/// in most cases) shared by all the matchers contained.
|
|
|
|
std::unique_ptr<PredicateMatcher> Condition = nullptr;
|
|
|
|
|
|
|
|
/// Temporary set used to check that the case values don't repeat within the
|
|
|
|
/// same switch.
|
|
|
|
std::set<MatchTableRecord> Values;
|
|
|
|
|
|
|
|
/// An owning collection for any auxiliary matchers created while optimizing
|
|
|
|
/// nested matchers contained.
|
|
|
|
std::vector<std::unique_ptr<Matcher>> MatcherStorage;
|
|
|
|
|
|
|
|
public:
|
|
|
|
bool addMatcher(Matcher &Candidate);
|
|
|
|
|
|
|
|
void finalize();
|
|
|
|
void emit(MatchTable &Table) override;
|
|
|
|
|
|
|
|
iterator_range<std::vector<Matcher *>::iterator> matchers() {
|
|
|
|
return make_range(Matchers.begin(), Matchers.end());
|
|
|
|
}
|
|
|
|
size_t size() const { return Matchers.size(); }
|
|
|
|
bool empty() const { return Matchers.empty(); }
|
|
|
|
|
|
|
|
std::unique_ptr<PredicateMatcher> popFirstCondition() override {
|
|
|
|
// SwitchMatcher doesn't have a common first condition for its cases, as all
|
|
|
|
// the cases only share a kind of a value (a type and a path to it) they
|
|
|
|
// match, but deliberately differ in the actual value they match.
|
|
|
|
llvm_unreachable("Trying to pop a condition from a condition-less group");
|
|
|
|
}
|
|
|
|
const PredicateMatcher &getFirstCondition() const override {
|
|
|
|
llvm_unreachable("Trying to pop a condition from a condition-less group");
|
|
|
|
}
|
|
|
|
bool hasFirstCondition() const override { return false; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
/// See if the predicate type has a Switch-implementation for it.
|
|
|
|
static bool isSupportedPredicateType(const PredicateMatcher &Predicate);
|
|
|
|
|
|
|
|
bool candidateConditionMatches(const PredicateMatcher &Predicate) const;
|
|
|
|
|
|
|
|
/// emit()-helper
|
|
|
|
static void emitPredicateSpecificOpcodes(const PredicateMatcher &P,
|
|
|
|
MatchTable &Table);
|
|
|
|
};
|
|
|
|
|
2017-03-16 04:18:38 +08:00
|
|
|
/// Generates code to check that a match rule matches.
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
class RuleMatcher : public Matcher {
|
2017-11-01 07:03:18 +08:00
|
|
|
public:
|
[ARM][GISel] PR35965 Constrain RegClasses of nested instructions built from Dst Pattern
Summary:
Apparently, we missed on constraining register classes of VReg-operands of all the instructions
built from a destination pattern but the root (top-level) one. The issue exposed itself
while selecting G_FPTOSI for armv7: the corresponding pattern generates VTOSIZS wrapped
into COPY_TO_REGCLASS, so top-level COPY_TO_REGCLASS gets properly constrained,
while nested VTOSIZS (or rather its destination virtual register to be exact) does not.
Fixing this by issuing GIR_ConstrainSelectedInstOperands for every nested GIR_BuildMI.
https://bugs.llvm.org/show_bug.cgi?id=35965
rdar://problem/36886530
Patch by Roman Tereshin
Reviewers: dsanders, qcolombet, rovka, bogner, aditya_nandakumar, volkan
Reviewed By: dsanders, qcolombet, rovka
Subscribers: aemerson, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D42565
llvm-svn: 323692
2018-01-30 05:09:12 +08:00
|
|
|
using ActionList = std::list<std::unique_ptr<MatchAction>>;
|
|
|
|
using action_iterator = ActionList::iterator;
|
2017-11-01 07:03:18 +08:00
|
|
|
|
|
|
|
protected:
|
2017-03-16 04:18:38 +08:00
|
|
|
/// 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.
|
2018-05-22 07:28:51 +08:00
|
|
|
using MatchersTy = std::vector<std::unique_ptr<InstructionMatcher>> ;
|
|
|
|
MatchersTy Matchers;
|
2017-03-16 04:18:38 +08:00
|
|
|
|
|
|
|
/// A list of actions that need to be taken when all predicates in this rule
|
|
|
|
/// have succeeded.
|
[ARM][GISel] PR35965 Constrain RegClasses of nested instructions built from Dst Pattern
Summary:
Apparently, we missed on constraining register classes of VReg-operands of all the instructions
built from a destination pattern but the root (top-level) one. The issue exposed itself
while selecting G_FPTOSI for armv7: the corresponding pattern generates VTOSIZS wrapped
into COPY_TO_REGCLASS, so top-level COPY_TO_REGCLASS gets properly constrained,
while nested VTOSIZS (or rather its destination virtual register to be exact) does not.
Fixing this by issuing GIR_ConstrainSelectedInstOperands for every nested GIR_BuildMI.
https://bugs.llvm.org/show_bug.cgi?id=35965
rdar://problem/36886530
Patch by Roman Tereshin
Reviewers: dsanders, qcolombet, rovka, bogner, aditya_nandakumar, volkan
Reviewed By: dsanders, qcolombet, rovka
Subscribers: aemerson, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D42565
llvm-svn: 323692
2018-01-30 05:09:12 +08:00
|
|
|
ActionList Actions;
|
2017-03-16 04:18:38 +08:00
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
using DefinedInsnVariablesMap = std::map<InstructionMatcher *, unsigned>;
|
2017-11-01 02:50:24 +08:00
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
/// A map of instruction matchers to the local variables
|
[globalisel][tablegen] Do not merge memoperands from instructions that weren't in the match.
Summary:
Fix a bug discovered in an out-of-tree target where memoperands from
pseudo-instructions that weren't part of the match were being merged into the
result instructions as part of GIR_MergeMemOperands.
This bug was caused by a change to the handling of State.MIs between rules when
the state machine tables were fused into a single table. Previously, each rule
would reset State.MIs using State.MIs.resize(1) but this is no longer done, as a
result stale data is occasionally left in some elements of State.MIs. Most
opcodes aren't affected by this but GIR_MergeMemOperands merges all memoperands
from the intructions recorded in State.MIs into the result instruction.
Suppose for example, we processed but rejected the following pattern:
(signextend (load x))
at this point, State.MIs contains the signextend and the load. Now suppose we
process and accept this pattern:
(add x, y)
at this point, State.MIs contains the add as well as the (now irrelevant) load.
When GIR_MergeMemOperands is processed, the memoperands from that irrelevant
load will be merged into the result instruction even though it was not part of
the match.
Bringing back the State.MIs.resize(1) would fix the problem but it would limit
our ability to optimize the table in the future. Instead, this patch fixes the
problem by explicitly stating which instructions should be merged into the result.
There's no direct test case in this commit because a test case would be very brittle.
However, at the time of writing this should fix the failures in
http://green.lab.llvm.org/green/job/Compiler_Verifiers_GlobalISEL/ as well as a
failure in test/CodeGen/ARM/GlobalISel/arm-isel.ll when expensive checks are enabled.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Subscribers: fhahn, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D36094
llvm-svn: 309804
2017-08-02 19:03:36 +08:00
|
|
|
DefinedInsnVariablesMap 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
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
using MutatableInsnSet = SmallPtrSet<InstructionMatcher *, 4>;
|
2017-11-01 02:50:24 +08:00
|
|
|
|
|
|
|
// The set of instruction matchers that have not yet been claimed for mutation
|
|
|
|
// by a BuildMI.
|
|
|
|
MutatableInsnSet MutatableInsns;
|
|
|
|
|
2017-10-14 08:31:58 +08:00
|
|
|
/// A map of named operands defined by the matchers that may be referenced by
|
|
|
|
/// the renderers.
|
|
|
|
StringMap<OperandMatcher *> DefinedOperands;
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
/// ID for the next instruction variable defined with implicitlyDefineInsnVar()
|
[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
|
|
|
unsigned NextInsnVarID;
|
|
|
|
|
2017-11-01 08:29:47 +08:00
|
|
|
/// ID for the next output instruction allocated with allocateOutputInsnID()
|
|
|
|
unsigned NextOutputInsnID;
|
|
|
|
|
2017-11-02 03:57:57 +08:00
|
|
|
/// ID for the next temporary register ID allocated with allocateTempRegID()
|
|
|
|
unsigned NextTempRegID;
|
|
|
|
|
[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;
|
2018-05-22 07:28:51 +08:00
|
|
|
std::vector<std::unique_ptr<PredicateMatcher>> EpilogueMatchers;
|
[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-10-14 08:31:58 +08:00
|
|
|
ArrayRef<SMLoc> SrcLoc;
|
|
|
|
|
2017-10-16 02:22:54 +08:00
|
|
|
typedef std::tuple<Record *, unsigned, unsigned>
|
|
|
|
DefinedComplexPatternSubOperand;
|
|
|
|
typedef StringMap<DefinedComplexPatternSubOperand>
|
|
|
|
DefinedComplexPatternSubOperandMap;
|
|
|
|
/// A map of Symbolic Names to ComplexPattern sub-operands.
|
|
|
|
DefinedComplexPatternSubOperandMap ComplexSubOperands;
|
|
|
|
|
[globalisel][tablegen] Generate rule coverage and use it to identify untested rules
Summary:
This patch adds a LLVM_ENABLE_GISEL_COV which, like LLVM_ENABLE_DAGISEL_COV,
causes TableGen to instrument the generated table to collect rule coverage
information. However, LLVM_ENABLE_GISEL_COV goes a bit further than
LLVM_ENABLE_DAGISEL_COV. The information is written to files
(${CMAKE_BINARY_DIR}/gisel-coverage-* by default). These files can then be
concatenated into ${LLVM_GISEL_COV_PREFIX}-all after which TableGen will
read this information and use it to emit warnings about untested rules.
This technique could also be used by SelectionDAG and can be further
extended to detect hot rules and give them priority over colder rules.
Usage:
* Enable LLVM_ENABLE_GISEL_COV in CMake
* Build the compiler and run some tests
* cat gisel-coverage-[0-9]* > gisel-coverage-all
* Delete lib/Target/*/*GenGlobalISel.inc*
* Build the compiler
Known issues:
* ${LLVM_GISEL_COV_PREFIX}-all must be generated as a manual
step due to a lack of a portable 'cat' command. It should be the
concatenation of all ${LLVM_GISEL_COV_PREFIX}-[0-9]* files.
* There's no mechanism to discard coverage information when the ruleset
changes
Depends on D39742
Reviewers: ab, qcolombet, t.p.northover, aditya_nandakumar, rovka
Reviewed By: rovka
Subscribers: vsk, arsenm, nhaehnle, mgorny, kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D39747
llvm-svn: 318356
2017-11-16 08:46:35 +08:00
|
|
|
uint64_t RuleID;
|
|
|
|
static uint64_t NextRuleID;
|
|
|
|
|
2017-03-16 04:18:38 +08:00
|
|
|
public:
|
2017-10-14 08:31:58 +08:00
|
|
|
RuleMatcher(ArrayRef<SMLoc> SrcLoc)
|
2017-11-01 02:50:24 +08:00
|
|
|
: Matchers(), Actions(), InsnVariableIDs(), MutatableInsns(),
|
2017-11-01 08:29:47 +08:00
|
|
|
DefinedOperands(), NextInsnVarID(0), NextOutputInsnID(0),
|
[globalisel][tablegen] Generate rule coverage and use it to identify untested rules
Summary:
This patch adds a LLVM_ENABLE_GISEL_COV which, like LLVM_ENABLE_DAGISEL_COV,
causes TableGen to instrument the generated table to collect rule coverage
information. However, LLVM_ENABLE_GISEL_COV goes a bit further than
LLVM_ENABLE_DAGISEL_COV. The information is written to files
(${CMAKE_BINARY_DIR}/gisel-coverage-* by default). These files can then be
concatenated into ${LLVM_GISEL_COV_PREFIX}-all after which TableGen will
read this information and use it to emit warnings about untested rules.
This technique could also be used by SelectionDAG and can be further
extended to detect hot rules and give them priority over colder rules.
Usage:
* Enable LLVM_ENABLE_GISEL_COV in CMake
* Build the compiler and run some tests
* cat gisel-coverage-[0-9]* > gisel-coverage-all
* Delete lib/Target/*/*GenGlobalISel.inc*
* Build the compiler
Known issues:
* ${LLVM_GISEL_COV_PREFIX}-all must be generated as a manual
step due to a lack of a portable 'cat' command. It should be the
concatenation of all ${LLVM_GISEL_COV_PREFIX}-[0-9]* files.
* There's no mechanism to discard coverage information when the ruleset
changes
Depends on D39742
Reviewers: ab, qcolombet, t.p.northover, aditya_nandakumar, rovka
Reviewed By: rovka
Subscribers: vsk, arsenm, nhaehnle, mgorny, kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D39747
llvm-svn: 318356
2017-11-16 08:46:35 +08:00
|
|
|
NextTempRegID(0), SrcLoc(SrcLoc), ComplexSubOperands(),
|
|
|
|
RuleID(NextRuleID++) {}
|
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
|
|
|
|
[globalisel][tablegen] Generate rule coverage and use it to identify untested rules
Summary:
This patch adds a LLVM_ENABLE_GISEL_COV which, like LLVM_ENABLE_DAGISEL_COV,
causes TableGen to instrument the generated table to collect rule coverage
information. However, LLVM_ENABLE_GISEL_COV goes a bit further than
LLVM_ENABLE_DAGISEL_COV. The information is written to files
(${CMAKE_BINARY_DIR}/gisel-coverage-* by default). These files can then be
concatenated into ${LLVM_GISEL_COV_PREFIX}-all after which TableGen will
read this information and use it to emit warnings about untested rules.
This technique could also be used by SelectionDAG and can be further
extended to detect hot rules and give them priority over colder rules.
Usage:
* Enable LLVM_ENABLE_GISEL_COV in CMake
* Build the compiler and run some tests
* cat gisel-coverage-[0-9]* > gisel-coverage-all
* Delete lib/Target/*/*GenGlobalISel.inc*
* Build the compiler
Known issues:
* ${LLVM_GISEL_COV_PREFIX}-all must be generated as a manual
step due to a lack of a portable 'cat' command. It should be the
concatenation of all ${LLVM_GISEL_COV_PREFIX}-[0-9]* files.
* There's no mechanism to discard coverage information when the ruleset
changes
Depends on D39742
Reviewers: ab, qcolombet, t.p.northover, aditya_nandakumar, rovka
Reviewed By: rovka
Subscribers: vsk, arsenm, nhaehnle, mgorny, kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D39747
llvm-svn: 318356
2017-11-16 08:46:35 +08:00
|
|
|
uint64_t getRuleID() const { return RuleID; }
|
|
|
|
|
2017-08-08 18:44:31 +08:00
|
|
|
InstructionMatcher &addInstructionMatcher(StringRef SymbolicName);
|
[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);
|
2017-11-01 07:03:18 +08:00
|
|
|
template <class Kind, class... Args>
|
|
|
|
action_iterator insertAction(action_iterator InsertPt, Args &&... args);
|
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
|
|
|
/// Define an instruction without emitting any code to do so.
|
2018-05-22 07:28:51 +08:00
|
|
|
unsigned implicitlyDefineInsnVar(InstructionMatcher &Matcher);
|
|
|
|
|
|
|
|
unsigned getInsnVarID(InstructionMatcher &InsnMatcher) const;
|
[globalisel][tablegen] Do not merge memoperands from instructions that weren't in the match.
Summary:
Fix a bug discovered in an out-of-tree target where memoperands from
pseudo-instructions that weren't part of the match were being merged into the
result instructions as part of GIR_MergeMemOperands.
This bug was caused by a change to the handling of State.MIs between rules when
the state machine tables were fused into a single table. Previously, each rule
would reset State.MIs using State.MIs.resize(1) but this is no longer done, as a
result stale data is occasionally left in some elements of State.MIs. Most
opcodes aren't affected by this but GIR_MergeMemOperands merges all memoperands
from the intructions recorded in State.MIs into the result instruction.
Suppose for example, we processed but rejected the following pattern:
(signextend (load x))
at this point, State.MIs contains the signextend and the load. Now suppose we
process and accept this pattern:
(add x, y)
at this point, State.MIs contains the add as well as the (now irrelevant) load.
When GIR_MergeMemOperands is processed, the memoperands from that irrelevant
load will be merged into the result instruction even though it was not part of
the match.
Bringing back the State.MIs.resize(1) would fix the problem but it would limit
our ability to optimize the table in the future. Instead, this patch fixes the
problem by explicitly stating which instructions should be merged into the result.
There's no direct test case in this commit because a test case would be very brittle.
However, at the time of writing this should fix the failures in
http://green.lab.llvm.org/green/job/Compiler_Verifiers_GlobalISEL/ as well as a
failure in test/CodeGen/ARM/GlobalISel/arm-isel.ll when expensive checks are enabled.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Subscribers: fhahn, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D36094
llvm-svn: 309804
2017-08-02 19:03:36 +08:00
|
|
|
DefinedInsnVariablesMap::const_iterator defined_insn_vars_begin() const {
|
|
|
|
return InsnVariableIDs.begin();
|
|
|
|
}
|
|
|
|
DefinedInsnVariablesMap::const_iterator defined_insn_vars_end() const {
|
|
|
|
return InsnVariableIDs.end();
|
|
|
|
}
|
|
|
|
iterator_range<typename DefinedInsnVariablesMap::const_iterator>
|
|
|
|
defined_insn_vars() const {
|
|
|
|
return make_range(defined_insn_vars_begin(), defined_insn_vars_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
|
|
|
|
2017-11-01 02:50:24 +08:00
|
|
|
MutatableInsnSet::const_iterator mutatable_insns_begin() const {
|
|
|
|
return MutatableInsns.begin();
|
|
|
|
}
|
|
|
|
MutatableInsnSet::const_iterator mutatable_insns_end() const {
|
|
|
|
return MutatableInsns.end();
|
|
|
|
}
|
|
|
|
iterator_range<typename MutatableInsnSet::const_iterator>
|
|
|
|
mutatable_insns() const {
|
|
|
|
return make_range(mutatable_insns_begin(), mutatable_insns_end());
|
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
void reserveInsnMatcherForMutation(InstructionMatcher *InsnMatcher) {
|
2017-11-01 02:50:24 +08:00
|
|
|
bool R = MutatableInsns.erase(InsnMatcher);
|
|
|
|
assert(R && "Reserving a mutatable insn that isn't available");
|
|
|
|
(void)R;
|
|
|
|
}
|
|
|
|
|
2017-11-01 07:03:18 +08:00
|
|
|
action_iterator actions_begin() { return Actions.begin(); }
|
|
|
|
action_iterator actions_end() { return Actions.end(); }
|
|
|
|
iterator_range<action_iterator> actions() {
|
|
|
|
return make_range(actions_begin(), actions_end());
|
|
|
|
}
|
|
|
|
|
2017-10-14 08:31:58 +08:00
|
|
|
void defineOperand(StringRef SymbolicName, OperandMatcher &OM);
|
|
|
|
|
2019-02-09 08:29:13 +08:00
|
|
|
Error defineComplexSubOperand(StringRef SymbolicName, Record *ComplexPattern,
|
|
|
|
unsigned RendererID, unsigned SubOperandID) {
|
|
|
|
if (ComplexSubOperands.count(SymbolicName))
|
|
|
|
return failedImport(
|
|
|
|
"Complex suboperand referenced more than once (Operand: " +
|
|
|
|
SymbolicName + ")");
|
|
|
|
|
2017-10-16 02:22:54 +08:00
|
|
|
ComplexSubOperands[SymbolicName] =
|
|
|
|
std::make_tuple(ComplexPattern, RendererID, SubOperandID);
|
2019-02-09 08:29:13 +08:00
|
|
|
|
|
|
|
return Error::success();
|
2017-10-16 02:22:54 +08:00
|
|
|
}
|
2019-02-09 08:29:13 +08:00
|
|
|
|
2017-10-16 02:22:54 +08:00
|
|
|
Optional<DefinedComplexPatternSubOperand>
|
|
|
|
getComplexSubOperand(StringRef SymbolicName) const {
|
|
|
|
const auto &I = ComplexSubOperands.find(SymbolicName);
|
|
|
|
if (I == ComplexSubOperands.end())
|
|
|
|
return None;
|
|
|
|
return I->second;
|
|
|
|
}
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
InstructionMatcher &getInstructionMatcher(StringRef SymbolicName) const;
|
2017-10-14 08:31:58 +08:00
|
|
|
const OperandMatcher &getOperandMatcher(StringRef Name) const;
|
2017-08-08 18:44:31 +08:00
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
void optimize() override;
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
void emit(MatchTable &Table) override;
|
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
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
std::unique_ptr<PredicateMatcher> popFirstCondition() override;
|
|
|
|
const PredicateMatcher &getFirstCondition() const override;
|
2018-05-24 05:30:16 +08:00
|
|
|
LLTCodeGen getFirstConditionAsRootType();
|
2018-05-22 07:28:51 +08:00
|
|
|
bool hasFirstCondition() const override;
|
|
|
|
unsigned getNumOperands() const;
|
2018-05-22 12:31:50 +08:00
|
|
|
StringRef getOpcode() const;
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +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
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
InstructionMatcher &insnmatchers_front() const { return *Matchers.front(); }
|
2017-11-01 08:29:47 +08:00
|
|
|
|
|
|
|
unsigned allocateOutputInsnID() { return NextOutputInsnID++; }
|
2017-11-02 03:57:57 +08:00
|
|
|
unsigned allocateTempRegID() { return NextTempRegID++; }
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
iterator_range<MatchersTy::iterator> insnmatchers() {
|
|
|
|
return make_range(Matchers.begin(), Matchers.end());
|
|
|
|
}
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
bool insnmatchers_empty() const { return Matchers.empty(); }
|
|
|
|
void insnmatchers_pop_front() { Matchers.erase(Matchers.begin()); }
|
2017-03-16 04:18:38 +08:00
|
|
|
};
|
|
|
|
|
[globalisel][tablegen] Generate rule coverage and use it to identify untested rules
Summary:
This patch adds a LLVM_ENABLE_GISEL_COV which, like LLVM_ENABLE_DAGISEL_COV,
causes TableGen to instrument the generated table to collect rule coverage
information. However, LLVM_ENABLE_GISEL_COV goes a bit further than
LLVM_ENABLE_DAGISEL_COV. The information is written to files
(${CMAKE_BINARY_DIR}/gisel-coverage-* by default). These files can then be
concatenated into ${LLVM_GISEL_COV_PREFIX}-all after which TableGen will
read this information and use it to emit warnings about untested rules.
This technique could also be used by SelectionDAG and can be further
extended to detect hot rules and give them priority over colder rules.
Usage:
* Enable LLVM_ENABLE_GISEL_COV in CMake
* Build the compiler and run some tests
* cat gisel-coverage-[0-9]* > gisel-coverage-all
* Delete lib/Target/*/*GenGlobalISel.inc*
* Build the compiler
Known issues:
* ${LLVM_GISEL_COV_PREFIX}-all must be generated as a manual
step due to a lack of a portable 'cat' command. It should be the
concatenation of all ${LLVM_GISEL_COV_PREFIX}-[0-9]* files.
* There's no mechanism to discard coverage information when the ruleset
changes
Depends on D39742
Reviewers: ab, qcolombet, t.p.northover, aditya_nandakumar, rovka
Reviewed By: rovka
Subscribers: vsk, arsenm, nhaehnle, mgorny, kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D39747
llvm-svn: 318356
2017-11-16 08:46:35 +08:00
|
|
|
uint64_t RuleMatcher::NextRuleID = 0;
|
|
|
|
|
2017-11-01 07:03:18 +08:00
|
|
|
using action_iterator = RuleMatcher::action_iterator;
|
|
|
|
|
[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:
|
2017-08-24 17:11:20 +08:00
|
|
|
/// Template instantiations should specialize this to return a string to use
|
|
|
|
/// for the comment emitted when there are no predicates.
|
|
|
|
std::string getNoPredicateComment() const;
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
protected:
|
|
|
|
using PredicatesTy = std::deque<std::unique_ptr<PredicateTy>>;
|
|
|
|
PredicatesTy Predicates;
|
|
|
|
|
|
|
|
/// Track if the list of predicates was manipulated by one of the optimization
|
|
|
|
/// methods.
|
|
|
|
bool Optimized = 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
|
|
|
public:
|
2018-05-22 07:28:51 +08:00
|
|
|
/// Construct a new predicate and add it to the matcher.
|
[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 Kind, class... Args>
|
2018-05-22 07:28:51 +08:00
|
|
|
Optional<Kind *> addPredicate(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
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
typename PredicatesTy::iterator predicates_begin() {
|
2017-06-28 21:50:04 +08:00
|
|
|
return Predicates.begin();
|
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
typename PredicatesTy::iterator predicates_end() {
|
2017-06-28 21:50:04 +08:00
|
|
|
return Predicates.end();
|
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
iterator_range<typename PredicatesTy::iterator> predicates() {
|
[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 make_range(predicates_begin(), predicates_end());
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
typename PredicatesTy::size_type predicates_size() const {
|
2017-06-28 21:50:04 +08:00
|
|
|
return Predicates.size();
|
|
|
|
}
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
bool predicates_empty() const { return Predicates.empty(); }
|
|
|
|
|
|
|
|
std::unique_ptr<PredicateTy> predicates_pop_front() {
|
|
|
|
std::unique_ptr<PredicateTy> Front = std::move(Predicates.front());
|
2018-05-22 07:28:51 +08:00
|
|
|
Predicates.pop_front();
|
|
|
|
Optimized = true;
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
return Front;
|
|
|
|
}
|
[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
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
void prependPredicate(std::unique_ptr<PredicateTy> &&Predicate) {
|
|
|
|
Predicates.push_front(std::move(Predicate));
|
|
|
|
}
|
|
|
|
|
|
|
|
void eraseNullPredicates() {
|
|
|
|
const auto NewEnd =
|
|
|
|
std::stable_partition(Predicates.begin(), Predicates.end(),
|
|
|
|
std::logical_not<std::unique_ptr<PredicateTy>>());
|
|
|
|
if (NewEnd != Predicates.begin()) {
|
|
|
|
Predicates.erase(Predicates.begin(), NewEnd);
|
|
|
|
Optimized = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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>
|
2018-05-22 07:28:51 +08:00
|
|
|
void emitPredicateListOpcodes(MatchTable &Table, Args &&... args) {
|
|
|
|
if (Predicates.empty() && !Optimized) {
|
2017-08-24 17:11:20 +08:00
|
|
|
Table << MatchTable::Comment(getNoPredicateComment())
|
|
|
|
<< 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;
|
|
|
|
}
|
|
|
|
|
2018-05-22 07:28:51 +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
|
|
|
};
|
|
|
|
|
2017-12-15 07:44:07 +08:00
|
|
|
class PredicateMatcher {
|
[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
|
|
|
/// 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.
|
2017-12-15 07:44:07 +08:00
|
|
|
///
|
|
|
|
/// Note: The relative priority between IPM_ and OPM_ does not matter, they
|
|
|
|
/// are currently not compared between each other.
|
[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-12-15 07:44:07 +08:00
|
|
|
IPM_Opcode,
|
2018-05-22 07:28:51 +08:00
|
|
|
IPM_NumOperands,
|
2017-12-15 07:44:07 +08:00
|
|
|
IPM_ImmPredicate,
|
|
|
|
IPM_AtomicOrderingMMO,
|
[globalisel] Update GlobalISel emitter to match new representation of extending loads
Summary:
Previously, a extending load was represented at (G_*EXT (G_LOAD x)).
This had a few drawbacks:
* G_LOAD had to be legal for all sizes you could extend from, even if
registers didn't naturally hold those sizes.
* All sizes you could extend from had to be allocatable just in case the
extend went missing (e.g. by optimization).
* At minimum, G_*EXT and G_TRUNC had to be legal for these sizes. As we
improve optimization of extends and truncates, this legality requirement
would spread without considerable care w.r.t when certain combines were
permitted.
* The SelectionDAG importer required some ugly and fragile pattern
rewriting to translate patterns into this style.
This patch changes the representation to:
* (G_[SZ]EXTLOAD x)
* (G_LOAD x) any-extends when MMO.getSize() * 8 < ResultTy.getSizeInBits()
which resolves these issues by allowing targets to work entirely in their
native register sizes, and by having a more direct translation from
SelectionDAG patterns.
Each extending load can be lowered by the legalizer into separate extends
and loads, however a target that supports s1 will need the any-extending
load to extend to at least s8 since LLVM does not represent memory accesses
smaller than 8 bit. The legalizer can widenScalar G_LOAD into an
any-extending load but sign/zero-extending loads need help from something
else like a combiner pass. A follow-up patch that adds combiner helpers for
for this will follow.
The new representation requires that the MMO correctly reflect the memory
access so this has been corrected in a couple tests. I've also moved the
extending loads to their own tests since they are (mostly) separate opcodes
now. Additionally, the re-write appears to have invalidated two tests from
select-with-no-legality-check.mir since the matcher table no longer contains
loads that result in s1's and they aren't legal in AArch64 anymore.
Depends on D45540
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar
Reviewed By: rtereshin
Subscribers: javed.absar, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D45541
llvm-svn: 331601
2018-05-06 04:53:24 +08:00
|
|
|
IPM_MemoryLLTSize,
|
|
|
|
IPM_MemoryVsLLTSize,
|
2018-06-16 07:13:43 +08:00
|
|
|
IPM_GenericPredicate,
|
2017-10-21 04:55:29 +08:00
|
|
|
OPM_SameOperand,
|
2017-03-15 05:32:08 +08:00
|
|
|
OPM_ComplexPattern,
|
2017-07-11 16:57:29 +08:00
|
|
|
OPM_IntrinsicID,
|
2017-08-08 18:44:31 +08:00
|
|
|
OPM_Instruction,
|
[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,
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
OPM_PointerToAny,
|
[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_RegBank,
|
|
|
|
OPM_MBB,
|
|
|
|
};
|
|
|
|
|
|
|
|
protected:
|
|
|
|
PredicateKind Kind;
|
2017-12-16 07:07:42 +08:00
|
|
|
unsigned InsnVarID;
|
|
|
|
unsigned OpIdx;
|
[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
|
|
|
|
|
|
|
public:
|
2017-12-16 07:07:42 +08:00
|
|
|
PredicateMatcher(PredicateKind Kind, unsigned InsnVarID, unsigned OpIdx = ~0)
|
|
|
|
: Kind(Kind), InsnVarID(InsnVarID), OpIdx(OpIdx) {}
|
2017-12-15 07:44:07 +08:00
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
unsigned getInsnVarID() const { return InsnVarID; }
|
2017-12-16 07:07:42 +08:00
|
|
|
unsigned getOpIdx() const { return OpIdx; }
|
2018-05-22 07:28:51 +08:00
|
|
|
|
2017-12-15 07:44:07 +08:00
|
|
|
virtual ~PredicateMatcher() = default;
|
|
|
|
/// Emit MatchTable opcodes that check the predicate for the given operand.
|
2017-12-16 07:07:42 +08:00
|
|
|
virtual void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) const = 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
|
|
|
|
[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-12-16 07:24:39 +08:00
|
|
|
|
|
|
|
virtual bool isIdentical(const PredicateMatcher &B) const {
|
|
|
|
return B.getKind() == getKind() && InsnVarID == B.InsnVarID &&
|
|
|
|
OpIdx == B.OpIdx;
|
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
|
|
|
|
virtual bool isIdenticalDownToValue(const PredicateMatcher &B) const {
|
|
|
|
return hasValue() && PredicateMatcher::isIdentical(B);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual MatchTableRecord getValue() const {
|
|
|
|
assert(hasValue() && "Can not get a value of a value-less predicate!");
|
|
|
|
llvm_unreachable("Not implemented yet");
|
|
|
|
}
|
|
|
|
virtual bool hasValue() const { return false; }
|
|
|
|
|
|
|
|
/// Report the maximum number of temporary operands needed by the predicate
|
|
|
|
/// matcher.
|
|
|
|
virtual unsigned countRendererFns() const { return 0; }
|
2017-12-15 07:44:07 +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 PredicateMatcher {
|
|
|
|
public:
|
2017-12-16 07:07:42 +08:00
|
|
|
OperandPredicateMatcher(PredicateKind Kind, unsigned InsnVarID,
|
|
|
|
unsigned OpIdx)
|
|
|
|
: PredicateMatcher(Kind, InsnVarID, OpIdx) {}
|
2017-12-15 07:44:07 +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
|
|
|
|
|
|
|
/// Compare the priority of this object and B.
|
|
|
|
///
|
|
|
|
/// Returns true if this object is more important than B.
|
2017-08-08 18:44:31 +08:00
|
|
|
virtual bool isHigherPriorityThan(const OperandPredicateMatcher &B) 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
|
|
|
};
|
|
|
|
|
2017-08-24 17:11:20 +08:00
|
|
|
template <>
|
|
|
|
std::string
|
|
|
|
PredicateListMatcher<OperandPredicateMatcher>::getNoPredicateComment() const {
|
|
|
|
return "No operand predicates";
|
|
|
|
}
|
|
|
|
|
2017-10-14 08:31:58 +08:00
|
|
|
/// Generates code to check that a register operand is defined by the same exact
|
|
|
|
/// one as another.
|
|
|
|
class SameOperandMatcher : public OperandPredicateMatcher {
|
2017-10-21 04:55:29 +08:00
|
|
|
std::string MatchingName;
|
2017-10-14 08:31:58 +08:00
|
|
|
|
|
|
|
public:
|
2017-12-19 06:12:13 +08:00
|
|
|
SameOperandMatcher(unsigned InsnVarID, unsigned OpIdx, StringRef MatchingName)
|
2017-12-16 07:07:42 +08:00
|
|
|
: OperandPredicateMatcher(OPM_SameOperand, InsnVarID, OpIdx),
|
|
|
|
MatchingName(MatchingName) {}
|
2017-10-14 08:31:58 +08:00
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
static bool classof(const PredicateMatcher *P) {
|
2017-10-21 04:55:29 +08:00
|
|
|
return P->getKind() == OPM_SameOperand;
|
2017-10-14 08:31:58 +08:00
|
|
|
}
|
|
|
|
|
2017-12-16 07:07:42 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) const override;
|
2018-05-22 07:28:51 +08:00
|
|
|
|
|
|
|
bool isIdentical(const PredicateMatcher &B) const override {
|
|
|
|
return OperandPredicateMatcher::isIdentical(B) &&
|
|
|
|
MatchingName == cast<SameOperandMatcher>(&B)->MatchingName;
|
|
|
|
}
|
2017-10-14 08:31:58 +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 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:
|
2018-05-22 07:28:51 +08:00
|
|
|
static std::map<LLTCodeGen, unsigned> TypeIDValues;
|
|
|
|
|
|
|
|
static void initTypeIDValuesMap() {
|
|
|
|
TypeIDValues.clear();
|
|
|
|
|
|
|
|
unsigned ID = 0;
|
|
|
|
for (const LLTCodeGen LLTy : KnownTypes)
|
|
|
|
TypeIDValues[LLTy] = ID++;
|
|
|
|
}
|
|
|
|
|
2017-12-19 06:12:13 +08:00
|
|
|
LLTOperandMatcher(unsigned InsnVarID, unsigned OpIdx, const LLTCodeGen &Ty)
|
2017-12-16 07:07:42 +08:00
|
|
|
: OperandPredicateMatcher(OPM_LLT, InsnVarID, OpIdx), Ty(Ty) {
|
2017-08-17 21:18:35 +08:00
|
|
|
KnownTypes.insert(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
|
|
|
|
2017-12-15 07:44:07 +08:00
|
|
|
static bool classof(const PredicateMatcher *P) {
|
[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 P->getKind() == OPM_LLT;
|
|
|
|
}
|
2017-12-16 07:24:39 +08:00
|
|
|
bool isIdentical(const PredicateMatcher &B) const override {
|
|
|
|
return OperandPredicateMatcher::isIdentical(B) &&
|
|
|
|
Ty == cast<LLTOperandMatcher>(&B)->Ty;
|
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
MatchTableRecord getValue() const override {
|
|
|
|
const auto VI = TypeIDValues.find(Ty);
|
|
|
|
if (VI == TypeIDValues.end())
|
|
|
|
return MatchTable::NamedValue(getTy().getCxxEnumValue());
|
|
|
|
return MatchTable::NamedValue(getTy().getCxxEnumValue(), VI->second);
|
|
|
|
}
|
|
|
|
bool hasValue() const override {
|
|
|
|
if (TypeIDValues.size() != KnownTypes.size())
|
|
|
|
initTypeIDValuesMap();
|
|
|
|
return TypeIDValues.count(Ty);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLTCodeGen getTy() const { return Ty; }
|
[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-12-16 07:07:42 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) 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")
|
2018-05-22 07:28:51 +08:00
|
|
|
<< getValue() << MatchTable::LineBreak;
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
std::map<LLTCodeGen, unsigned> LLTOperandMatcher::TypeIDValues;
|
|
|
|
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
/// Generates code to check that an operand is a pointer to any address space.
|
|
|
|
///
|
|
|
|
/// In SelectionDAG, the types did not describe pointers or address spaces. As a
|
|
|
|
/// result, iN is used to describe a pointer of N bits to any address space and
|
|
|
|
/// PatFrag predicates are typically used to constrain the address space. There's
|
|
|
|
/// no reliable means to derive the missing type information from the pattern so
|
|
|
|
/// imported rules must test the components of a pointer separately.
|
|
|
|
///
|
2017-10-16 11:36:29 +08:00
|
|
|
/// If SizeInBits is zero, then the pointer size will be obtained from the
|
|
|
|
/// subtarget.
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
class PointerToAnyOperandMatcher : public OperandPredicateMatcher {
|
|
|
|
protected:
|
|
|
|
unsigned SizeInBits;
|
|
|
|
|
|
|
|
public:
|
2017-12-19 06:12:13 +08:00
|
|
|
PointerToAnyOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
|
|
|
|
unsigned SizeInBits)
|
2017-12-16 07:07:42 +08:00
|
|
|
: OperandPredicateMatcher(OPM_PointerToAny, InsnVarID, OpIdx),
|
|
|
|
SizeInBits(SizeInBits) {}
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
|
|
|
|
static bool classof(const OperandPredicateMatcher *P) {
|
|
|
|
return P->getKind() == OPM_PointerToAny;
|
|
|
|
}
|
|
|
|
|
2017-12-16 07:07:42 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) const override {
|
|
|
|
Table << MatchTable::Opcode("GIM_CheckPointerToAny")
|
|
|
|
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
|
|
|
|
<< MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
|
|
|
|
<< MatchTable::Comment("SizeInBits")
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
<< MatchTable::IntValue(SizeInBits) << MatchTable::LineBreak;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
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:
|
2017-12-16 07:24:39 +08:00
|
|
|
bool isIdentical(const PredicateMatcher &B) const override { return false; }
|
|
|
|
|
2017-12-19 06:12:13 +08:00
|
|
|
ComplexPatternOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
|
|
|
|
const OperandMatcher &Operand,
|
|
|
|
const Record &TheDef)
|
2017-12-16 07:07:42 +08:00
|
|
|
: OperandPredicateMatcher(OPM_ComplexPattern, InsnVarID, OpIdx),
|
|
|
|
Operand(Operand), TheDef(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
|
|
|
|
2017-12-15 07:44:07 +08:00
|
|
|
static bool classof(const PredicateMatcher *P) {
|
[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 P->getKind() == OPM_ComplexPattern;
|
|
|
|
}
|
2017-03-15 05:32:08 +08:00
|
|
|
|
2017-12-16 07:07:42 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) 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:
|
2017-12-19 06:12:13 +08:00
|
|
|
RegisterBankOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
|
|
|
|
const CodeGenRegisterClass &RC)
|
2017-12-16 07:07:42 +08:00
|
|
|
: OperandPredicateMatcher(OPM_RegBank, InsnVarID, OpIdx), RC(RC) {}
|
[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-12-16 07:24:39 +08:00
|
|
|
bool isIdentical(const PredicateMatcher &B) const override {
|
|
|
|
return OperandPredicateMatcher::isIdentical(B) &&
|
|
|
|
RC.getDef() == cast<RegisterBankOperandMatcher>(&B)->RC.getDef();
|
|
|
|
}
|
|
|
|
|
2017-12-15 07:44:07 +08:00
|
|
|
static bool classof(const PredicateMatcher *P) {
|
[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 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-12-16 07:07:42 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) 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:
|
2017-12-16 07:07:42 +08:00
|
|
|
MBBOperandMatcher(unsigned InsnVarID, unsigned OpIdx)
|
|
|
|
: OperandPredicateMatcher(OPM_MBB, InsnVarID, OpIdx) {}
|
[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-12-15 07:44:07 +08:00
|
|
|
static bool classof(const PredicateMatcher *P) {
|
[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 P->getKind() == OPM_MBB;
|
|
|
|
}
|
|
|
|
|
2017-12-16 07:07:42 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) 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-12-19 06:12:13 +08:00
|
|
|
ConstantIntOperandMatcher(unsigned InsnVarID, unsigned OpIdx, int64_t Value)
|
2017-12-16 07:07:42 +08:00
|
|
|
: OperandPredicateMatcher(OPM_Int, InsnVarID, OpIdx), Value(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
|
|
|
|
2017-12-16 07:24:39 +08:00
|
|
|
bool isIdentical(const PredicateMatcher &B) const override {
|
|
|
|
return OperandPredicateMatcher::isIdentical(B) &&
|
|
|
|
Value == cast<ConstantIntOperandMatcher>(&B)->Value;
|
|
|
|
}
|
|
|
|
|
2017-12-15 07:44:07 +08:00
|
|
|
static bool classof(const PredicateMatcher *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
|
|
|
return P->getKind() == OPM_Int;
|
|
|
|
}
|
|
|
|
|
2017-12-16 07:07:42 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) 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:
|
2017-12-19 06:12:13 +08:00
|
|
|
LiteralIntOperandMatcher(unsigned InsnVarID, unsigned OpIdx, int64_t Value)
|
2017-12-16 07:07:42 +08:00
|
|
|
: OperandPredicateMatcher(OPM_LiteralInt, InsnVarID, OpIdx),
|
|
|
|
Value(Value) {}
|
2017-05-24 03:33:16 +08:00
|
|
|
|
2017-12-16 07:24:39 +08:00
|
|
|
bool isIdentical(const PredicateMatcher &B) const override {
|
|
|
|
return OperandPredicateMatcher::isIdentical(B) &&
|
|
|
|
Value == cast<LiteralIntOperandMatcher>(&B)->Value;
|
|
|
|
}
|
|
|
|
|
2017-12-15 07:44:07 +08:00
|
|
|
static bool classof(const PredicateMatcher *P) {
|
2017-05-24 03:33:16 +08:00
|
|
|
return P->getKind() == OPM_LiteralInt;
|
|
|
|
}
|
|
|
|
|
2017-12-16 07:07:42 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) 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:
|
2017-12-19 06:12:13 +08:00
|
|
|
IntrinsicIDOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
|
|
|
|
const CodeGenIntrinsic *II)
|
2017-12-16 07:07:42 +08:00
|
|
|
: OperandPredicateMatcher(OPM_IntrinsicID, InsnVarID, OpIdx), II(II) {}
|
2017-07-11 16:57:29 +08:00
|
|
|
|
2017-12-16 07:24:39 +08:00
|
|
|
bool isIdentical(const PredicateMatcher &B) const override {
|
|
|
|
return OperandPredicateMatcher::isIdentical(B) &&
|
|
|
|
II == cast<IntrinsicIDOperandMatcher>(&B)->II;
|
|
|
|
}
|
|
|
|
|
2017-12-15 07:44:07 +08:00
|
|
|
static bool classof(const PredicateMatcher *P) {
|
2017-07-11 16:57:29 +08:00
|
|
|
return P->getKind() == OPM_IntrinsicID;
|
|
|
|
}
|
|
|
|
|
2017-12-16 07:07:42 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) 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;
|
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
|
|
|
|
/// Construct a new operand predicate and add it to the matcher.
|
|
|
|
template <class Kind, class... Args>
|
|
|
|
Optional<Kind *> addPredicate(Args &&... args) {
|
|
|
|
if (isSameAsAnotherOperand())
|
|
|
|
return None;
|
|
|
|
Predicates.emplace_back(llvm::make_unique<Kind>(
|
|
|
|
getInsnVarID(), getOpIdx(), std::forward<Args>(args)...));
|
|
|
|
return static_cast<Kind *>(Predicates.back().get());
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned getOpIdx() const { return OpIdx; }
|
2017-12-16 07:07:42 +08:00
|
|
|
unsigned getInsnVarID() 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
|
|
|
|
[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] 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; }
|
|
|
|
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
Error addTypeCheckPredicate(const TypeSetByHwMode &VTy,
|
2017-10-17 04:31:16 +08:00
|
|
|
bool OperandIsAPointer);
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +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.
|
2018-05-22 07:28:51 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule) {
|
|
|
|
if (!Optimized) {
|
|
|
|
std::string Comment;
|
|
|
|
raw_string_ostream CommentOS(Comment);
|
|
|
|
CommentOS << "MIs[" << getInsnVarID() << "] ";
|
|
|
|
if (SymbolicName.empty())
|
|
|
|
CommentOS << "Operand " << OpIdx;
|
|
|
|
else
|
|
|
|
CommentOS << SymbolicName;
|
|
|
|
Table << MatchTable::Comment(CommentOS.str()) << MatchTable::LineBreak;
|
|
|
|
}
|
2017-07-20 17:25:44 +08:00
|
|
|
|
2017-12-16 07:07:42 +08:00
|
|
|
emitPredicateListOpcodes(Table, Rule);
|
[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.
|
2018-05-22 07:28:51 +08:00
|
|
|
bool isHigherPriorityThan(OperandMatcher &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
|
|
|
// 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.
|
2018-05-22 07:28:51 +08:00
|
|
|
for (auto &&Predicate : zip(predicates(), B.predicates())) {
|
[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 (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.
|
2018-05-22 07:28:51 +08:00
|
|
|
unsigned countRendererFns() {
|
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;
|
|
|
|
}
|
2017-10-14 08:31:58 +08:00
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
bool isSameAsAnotherOperand() {
|
2017-10-14 08:31:58 +08:00
|
|
|
for (const auto &Predicate : predicates())
|
|
|
|
if (isa<SameOperandMatcher>(Predicate))
|
|
|
|
return true;
|
|
|
|
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
|
|
|
};
|
|
|
|
|
2017-10-17 04:31:16 +08:00
|
|
|
Error OperandMatcher::addTypeCheckPredicate(const TypeSetByHwMode &VTy,
|
2017-12-16 07:07:42 +08:00
|
|
|
bool OperandIsAPointer) {
|
2017-10-17 04:31:16 +08:00
|
|
|
if (!VTy.isMachineValueType())
|
|
|
|
return failedImport("unsupported typeset");
|
|
|
|
|
|
|
|
if (VTy.getMachineValueType() == MVT::iPTR && OperandIsAPointer) {
|
|
|
|
addPredicate<PointerToAnyOperandMatcher>(0);
|
|
|
|
return Error::success();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto OpTyOrNone = MVTToLLT(VTy.getMachineValueType().SimpleTy);
|
|
|
|
if (!OpTyOrNone)
|
|
|
|
return failedImport("unsupported type");
|
|
|
|
|
|
|
|
if (OperandIsAPointer)
|
|
|
|
addPredicate<PointerToAnyOperandMatcher>(OpTyOrNone->get().getSizeInBits());
|
Add support for pointer types in patterns
Summary:
This adds support for defining patterns for global isel using pointer
types, for example:
def : Pat<(load GPR32:$src),
(p1 (LOAD GPR32:$src))>;
DAGISelEmitter will ignore the pointer information and treat these
types as integers with the same bit-width as the pointer type.
Reviewers: dsanders, rtereshin, arsenm
Reviewed By: arsenm
Subscribers: Petar.Avramovic, wdng, rovka, kristof.beyls, jfb, volkan, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D57065
llvm-svn: 354510
2019-02-21 03:43:47 +08:00
|
|
|
else if (VTy.isPointer())
|
|
|
|
addPredicate<LLTOperandMatcher>(LLT::pointer(VTy.getPtrAddrSpace(),
|
|
|
|
OpTyOrNone->get().getSizeInBits()));
|
2017-10-17 04:31:16 +08:00
|
|
|
else
|
|
|
|
addPredicate<LLTOperandMatcher>(*OpTyOrNone);
|
|
|
|
return Error::success();
|
|
|
|
}
|
|
|
|
|
[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.
|
2017-12-15 07:44:07 +08:00
|
|
|
class InstructionPredicateMatcher : public PredicateMatcher {
|
[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-12-16 07:07:42 +08:00
|
|
|
InstructionPredicateMatcher(PredicateKind Kind, unsigned InsnVarID)
|
|
|
|
: PredicateMatcher(Kind, InsnVarID) {}
|
[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
|
|
|
/// 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;
|
|
|
|
};
|
[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-08-24 17:11:20 +08:00
|
|
|
template <>
|
|
|
|
std::string
|
2018-05-22 07:28:51 +08:00
|
|
|
PredicateListMatcher<PredicateMatcher>::getNoPredicateComment() const {
|
2017-08-24 17:11:20 +08:00
|
|
|
return "No instruction predicates";
|
|
|
|
}
|
|
|
|
|
[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;
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
static DenseMap<const CodeGenInstruction *, unsigned> OpcodeValues;
|
|
|
|
|
[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:
|
2018-05-22 07:28:51 +08:00
|
|
|
static void initOpcodeValuesMap(const CodeGenTarget &Target) {
|
|
|
|
OpcodeValues.clear();
|
|
|
|
|
|
|
|
unsigned OpcodeValue = 0;
|
|
|
|
for (const CodeGenInstruction *I : Target.getInstructionsByEnumValue())
|
|
|
|
OpcodeValues[I] = OpcodeValue++;
|
|
|
|
}
|
|
|
|
|
2017-12-16 07:07:42 +08:00
|
|
|
InstructionOpcodeMatcher(unsigned InsnVarID, const CodeGenInstruction *I)
|
|
|
|
: InstructionPredicateMatcher(IPM_Opcode, InsnVarID), 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
|
|
|
|
2017-12-15 07:44:07 +08:00
|
|
|
static bool classof(const PredicateMatcher *P) {
|
[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 P->getKind() == IPM_Opcode;
|
|
|
|
}
|
|
|
|
|
2017-12-16 07:24:39 +08:00
|
|
|
bool isIdentical(const PredicateMatcher &B) const override {
|
|
|
|
return InstructionPredicateMatcher::isIdentical(B) &&
|
|
|
|
I == cast<InstructionOpcodeMatcher>(&B)->I;
|
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
MatchTableRecord getValue() const override {
|
|
|
|
const auto VI = OpcodeValues.find(I);
|
|
|
|
if (VI != OpcodeValues.end())
|
|
|
|
return MatchTable::NamedValue(I->Namespace, I->TheDef->getName(),
|
|
|
|
VI->second);
|
|
|
|
return MatchTable::NamedValue(I->Namespace, I->TheDef->getName());
|
|
|
|
}
|
|
|
|
bool hasValue() const override { return OpcodeValues.count(I); }
|
2017-12-16 07:24:39 +08:00
|
|
|
|
2017-12-16 07:07:42 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) const override {
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIM_CheckOpcode") << MatchTable::Comment("MI")
|
2018-05-22 07:28:51 +08:00
|
|
|
<< MatchTable::IntValue(InsnVarID) << getValue()
|
2017-07-20 17:25:44 +08:00
|
|
|
<< 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;
|
|
|
|
};
|
2017-08-08 18:44:31 +08:00
|
|
|
|
|
|
|
bool isConstantInstruction() const {
|
|
|
|
return I->TheDef->getName() == "G_CONSTANT";
|
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
|
2018-05-22 12:31:50 +08:00
|
|
|
StringRef getOpcode() const { return I->TheDef->getName(); }
|
2018-05-22 07:28:51 +08:00
|
|
|
unsigned getNumOperands() const { return I->Operands.size(); }
|
|
|
|
|
|
|
|
StringRef getOperandType(unsigned OpIdx) const {
|
|
|
|
return I->Operands[OpIdx].OperandType;
|
|
|
|
}
|
[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
|
|
|
};
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
DenseMap<const CodeGenInstruction *, unsigned>
|
|
|
|
InstructionOpcodeMatcher::OpcodeValues;
|
|
|
|
|
2018-05-22 12:31:50 +08:00
|
|
|
class InstructionNumOperandsMatcher final : public InstructionPredicateMatcher {
|
|
|
|
unsigned NumOperands = 0;
|
|
|
|
|
|
|
|
public:
|
|
|
|
InstructionNumOperandsMatcher(unsigned InsnVarID, unsigned NumOperands)
|
|
|
|
: InstructionPredicateMatcher(IPM_NumOperands, InsnVarID),
|
|
|
|
NumOperands(NumOperands) {}
|
|
|
|
|
|
|
|
static bool classof(const PredicateMatcher *P) {
|
|
|
|
return P->getKind() == IPM_NumOperands;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isIdentical(const PredicateMatcher &B) const override {
|
|
|
|
return InstructionPredicateMatcher::isIdentical(B) &&
|
|
|
|
NumOperands == cast<InstructionNumOperandsMatcher>(&B)->NumOperands;
|
|
|
|
}
|
|
|
|
|
|
|
|
void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) const override {
|
|
|
|
Table << MatchTable::Opcode("GIM_CheckNumOperands")
|
|
|
|
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
|
|
|
|
<< MatchTable::Comment("Expected")
|
|
|
|
<< MatchTable::IntValue(NumOperands) << MatchTable::LineBreak;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-08-24 17:11:20 +08:00
|
|
|
/// Generates code to check that this instruction is a constant whose value
|
|
|
|
/// meets an immediate predicate.
|
|
|
|
///
|
|
|
|
/// Immediates are slightly odd since they are typically used like an operand
|
|
|
|
/// but are represented as an operator internally. We typically write simm8:$src
|
|
|
|
/// in a tablegen pattern, but this is just syntactic sugar for
|
|
|
|
/// (imm:i32)<<P:Predicate_simm8>>:$imm which more directly describes the nodes
|
|
|
|
/// that will be matched and the predicate (which is attached to the imm
|
|
|
|
/// operator) that will be tested. In SelectionDAG this describes a
|
|
|
|
/// ConstantSDNode whose internal value will be tested using the simm8 predicate.
|
|
|
|
///
|
|
|
|
/// The corresponding GlobalISel representation is %1 = G_CONSTANT iN Value. In
|
|
|
|
/// this representation, the immediate could be tested with an
|
|
|
|
/// InstructionMatcher, InstructionOpcodeMatcher, OperandMatcher, and a
|
|
|
|
/// OperandPredicateMatcher-subclass to check the Value meets the predicate but
|
|
|
|
/// there are two implementation issues with producing that matcher
|
|
|
|
/// configuration from the SelectionDAG pattern:
|
|
|
|
/// * ImmLeaf is a PatFrag whose root is an InstructionMatcher. This means that
|
|
|
|
/// were we to sink the immediate predicate to the operand we would have to
|
|
|
|
/// have two partial implementations of PatFrag support, one for immediates
|
|
|
|
/// and one for non-immediates.
|
|
|
|
/// * At the point we handle the predicate, the OperandMatcher hasn't been
|
|
|
|
/// created yet. If we were to sink the predicate to the OperandMatcher we
|
|
|
|
/// would also have to complicate (or duplicate) the code that descends and
|
|
|
|
/// creates matchers for the subtree.
|
|
|
|
/// Overall, it's simpler to handle it in the place it was found.
|
|
|
|
class InstructionImmPredicateMatcher : public InstructionPredicateMatcher {
|
|
|
|
protected:
|
|
|
|
TreePredicateFn Predicate;
|
|
|
|
|
|
|
|
public:
|
2017-12-16 07:07:42 +08:00
|
|
|
InstructionImmPredicateMatcher(unsigned InsnVarID,
|
|
|
|
const TreePredicateFn &Predicate)
|
|
|
|
: InstructionPredicateMatcher(IPM_ImmPredicate, InsnVarID),
|
|
|
|
Predicate(Predicate) {}
|
2017-08-24 17:11:20 +08:00
|
|
|
|
2017-12-16 07:24:39 +08:00
|
|
|
bool isIdentical(const PredicateMatcher &B) const override {
|
|
|
|
return InstructionPredicateMatcher::isIdentical(B) &&
|
|
|
|
Predicate.getOrigPatFragRecord() ==
|
|
|
|
cast<InstructionImmPredicateMatcher>(&B)
|
|
|
|
->Predicate.getOrigPatFragRecord();
|
|
|
|
}
|
|
|
|
|
2017-12-15 07:44:07 +08:00
|
|
|
static bool classof(const PredicateMatcher *P) {
|
2017-08-24 17:11:20 +08:00
|
|
|
return P->getKind() == IPM_ImmPredicate;
|
|
|
|
}
|
|
|
|
|
2017-12-16 07:07:42 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) const override {
|
[globalisel][tablegen] Add support for fpimm and import of APInt/APFloat based ImmLeaf.
Summary:
There's only a tablegen testcase for IntImmLeaf and not a CodeGen one
because the relevant rules are rejected for other reasons at the moment.
On AArch64, it's because there's an SDNodeXForm attached to the operand.
On X86, it's because the rule either emits multiple instructions or has
another predicate using PatFrag which cannot easily be supported at the
same time.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36569
llvm-svn: 315761
2017-10-14 05:28:03 +08:00
|
|
|
Table << MatchTable::Opcode(getMatchOpcodeForPredicate(Predicate))
|
2017-08-24 17:11:20 +08:00
|
|
|
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
|
|
|
|
<< MatchTable::Comment("Predicate")
|
[globalisel][tablegen] Add support for fpimm and import of APInt/APFloat based ImmLeaf.
Summary:
There's only a tablegen testcase for IntImmLeaf and not a CodeGen one
because the relevant rules are rejected for other reasons at the moment.
On AArch64, it's because there's an SDNodeXForm attached to the operand.
On X86, it's because the rule either emits multiple instructions or has
another predicate using PatFrag which cannot easily be supported at the
same time.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36569
llvm-svn: 315761
2017-10-14 05:28:03 +08:00
|
|
|
<< MatchTable::NamedValue(getEnumNameForPredicate(Predicate))
|
2017-08-24 17:11:20 +08:00
|
|
|
<< MatchTable::LineBreak;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-11-29 06:07:05 +08:00
|
|
|
/// Generates code to check that a memory instruction has a atomic ordering
|
|
|
|
/// MachineMemoryOperand.
|
|
|
|
class AtomicOrderingMMOPredicateMatcher : public InstructionPredicateMatcher {
|
2017-12-01 05:05:59 +08:00
|
|
|
public:
|
|
|
|
enum AOComparator {
|
|
|
|
AO_Exactly,
|
|
|
|
AO_OrStronger,
|
|
|
|
AO_WeakerThan,
|
|
|
|
};
|
|
|
|
|
|
|
|
protected:
|
2017-11-29 06:07:05 +08:00
|
|
|
StringRef Order;
|
2017-12-01 05:05:59 +08:00
|
|
|
AOComparator Comparator;
|
2017-11-29 06:07:05 +08:00
|
|
|
|
[globalisel][tablegen] Map ld and st to G_LOAD and G_STORE. NFC
Summary:
There is an important mismatch between ISD::LOAD and G_LOAD (and likewise for
ISD::STORE and G_STORE). In SelectionDAG, ISD::LOAD is a non-atomic load
and atomic loads are handled by a separate node. However, this is not true of
GlobalISel's G_LOAD. For G_LOAD, the MachineMemOperand indicates the atomicity
of the operation. As a result, this mapping must also add a predicate that
checks for non-atomic MachineMemOperands.
This is NFC since these nodes always have predicates in practice and are
therefore always rejected at the moment.
Depends on D37443
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37445
llvm-svn: 315843
2017-10-15 10:41:12 +08:00
|
|
|
public:
|
2017-12-16 07:07:42 +08:00
|
|
|
AtomicOrderingMMOPredicateMatcher(unsigned InsnVarID, StringRef Order,
|
2017-12-01 05:05:59 +08:00
|
|
|
AOComparator Comparator = AO_Exactly)
|
2017-12-16 07:07:42 +08:00
|
|
|
: InstructionPredicateMatcher(IPM_AtomicOrderingMMO, InsnVarID),
|
|
|
|
Order(Order), Comparator(Comparator) {}
|
[globalisel][tablegen] Map ld and st to G_LOAD and G_STORE. NFC
Summary:
There is an important mismatch between ISD::LOAD and G_LOAD (and likewise for
ISD::STORE and G_STORE). In SelectionDAG, ISD::LOAD is a non-atomic load
and atomic loads are handled by a separate node. However, this is not true of
GlobalISel's G_LOAD. For G_LOAD, the MachineMemOperand indicates the atomicity
of the operation. As a result, this mapping must also add a predicate that
checks for non-atomic MachineMemOperands.
This is NFC since these nodes always have predicates in practice and are
therefore always rejected at the moment.
Depends on D37443
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37445
llvm-svn: 315843
2017-10-15 10:41:12 +08:00
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
static bool classof(const PredicateMatcher *P) {
|
2017-11-29 06:07:05 +08:00
|
|
|
return P->getKind() == IPM_AtomicOrderingMMO;
|
[globalisel][tablegen] Map ld and st to G_LOAD and G_STORE. NFC
Summary:
There is an important mismatch between ISD::LOAD and G_LOAD (and likewise for
ISD::STORE and G_STORE). In SelectionDAG, ISD::LOAD is a non-atomic load
and atomic loads are handled by a separate node. However, this is not true of
GlobalISel's G_LOAD. For G_LOAD, the MachineMemOperand indicates the atomicity
of the operation. As a result, this mapping must also add a predicate that
checks for non-atomic MachineMemOperands.
This is NFC since these nodes always have predicates in practice and are
therefore always rejected at the moment.
Depends on D37443
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37445
llvm-svn: 315843
2017-10-15 10:41:12 +08:00
|
|
|
}
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
bool isIdentical(const PredicateMatcher &B) const override {
|
|
|
|
if (!InstructionPredicateMatcher::isIdentical(B))
|
|
|
|
return false;
|
|
|
|
const auto &R = *cast<AtomicOrderingMMOPredicateMatcher>(&B);
|
|
|
|
return Order == R.Order && Comparator == R.Comparator;
|
|
|
|
}
|
|
|
|
|
2017-12-16 07:07:42 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) const override {
|
2017-12-01 05:05:59 +08:00
|
|
|
StringRef Opcode = "GIM_CheckAtomicOrdering";
|
|
|
|
|
|
|
|
if (Comparator == AO_OrStronger)
|
|
|
|
Opcode = "GIM_CheckAtomicOrderingOrStrongerThan";
|
|
|
|
if (Comparator == AO_WeakerThan)
|
|
|
|
Opcode = "GIM_CheckAtomicOrderingWeakerThan";
|
|
|
|
|
|
|
|
Table << MatchTable::Opcode(Opcode) << MatchTable::Comment("MI")
|
|
|
|
<< MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Order")
|
2017-11-29 06:07:05 +08:00
|
|
|
<< MatchTable::NamedValue(("(int64_t)AtomicOrdering::" + Order).str())
|
[globalisel][tablegen] Map ld and st to G_LOAD and G_STORE. NFC
Summary:
There is an important mismatch between ISD::LOAD and G_LOAD (and likewise for
ISD::STORE and G_STORE). In SelectionDAG, ISD::LOAD is a non-atomic load
and atomic loads are handled by a separate node. However, this is not true of
GlobalISel's G_LOAD. For G_LOAD, the MachineMemOperand indicates the atomicity
of the operation. As a result, this mapping must also add a predicate that
checks for non-atomic MachineMemOperands.
This is NFC since these nodes always have predicates in practice and are
therefore always rejected at the moment.
Depends on D37443
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37445
llvm-svn: 315843
2017-10-15 10:41:12 +08:00
|
|
|
<< MatchTable::LineBreak;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
[globalisel] Update GlobalISel emitter to match new representation of extending loads
Summary:
Previously, a extending load was represented at (G_*EXT (G_LOAD x)).
This had a few drawbacks:
* G_LOAD had to be legal for all sizes you could extend from, even if
registers didn't naturally hold those sizes.
* All sizes you could extend from had to be allocatable just in case the
extend went missing (e.g. by optimization).
* At minimum, G_*EXT and G_TRUNC had to be legal for these sizes. As we
improve optimization of extends and truncates, this legality requirement
would spread without considerable care w.r.t when certain combines were
permitted.
* The SelectionDAG importer required some ugly and fragile pattern
rewriting to translate patterns into this style.
This patch changes the representation to:
* (G_[SZ]EXTLOAD x)
* (G_LOAD x) any-extends when MMO.getSize() * 8 < ResultTy.getSizeInBits()
which resolves these issues by allowing targets to work entirely in their
native register sizes, and by having a more direct translation from
SelectionDAG patterns.
Each extending load can be lowered by the legalizer into separate extends
and loads, however a target that supports s1 will need the any-extending
load to extend to at least s8 since LLVM does not represent memory accesses
smaller than 8 bit. The legalizer can widenScalar G_LOAD into an
any-extending load but sign/zero-extending loads need help from something
else like a combiner pass. A follow-up patch that adds combiner helpers for
for this will follow.
The new representation requires that the MMO correctly reflect the memory
access so this has been corrected in a couple tests. I've also moved the
extending loads to their own tests since they are (mostly) separate opcodes
now. Additionally, the re-write appears to have invalidated two tests from
select-with-no-legality-check.mir since the matcher table no longer contains
loads that result in s1's and they aren't legal in AArch64 anymore.
Depends on D45540
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar
Reviewed By: rtereshin
Subscribers: javed.absar, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D45541
llvm-svn: 331601
2018-05-06 04:53:24 +08:00
|
|
|
/// Generates code to check that the size of an MMO is exactly N bytes.
|
|
|
|
class MemorySizePredicateMatcher : public InstructionPredicateMatcher {
|
|
|
|
protected:
|
|
|
|
unsigned MMOIdx;
|
|
|
|
uint64_t Size;
|
|
|
|
|
|
|
|
public:
|
|
|
|
MemorySizePredicateMatcher(unsigned InsnVarID, unsigned MMOIdx, unsigned Size)
|
|
|
|
: InstructionPredicateMatcher(IPM_MemoryLLTSize, InsnVarID),
|
|
|
|
MMOIdx(MMOIdx), Size(Size) {}
|
|
|
|
|
|
|
|
static bool classof(const PredicateMatcher *P) {
|
|
|
|
return P->getKind() == IPM_MemoryLLTSize;
|
|
|
|
}
|
|
|
|
bool isIdentical(const PredicateMatcher &B) const override {
|
|
|
|
return InstructionPredicateMatcher::isIdentical(B) &&
|
|
|
|
MMOIdx == cast<MemorySizePredicateMatcher>(&B)->MMOIdx &&
|
|
|
|
Size == cast<MemorySizePredicateMatcher>(&B)->Size;
|
|
|
|
}
|
|
|
|
|
|
|
|
void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) const override {
|
|
|
|
Table << MatchTable::Opcode("GIM_CheckMemorySizeEqualTo")
|
|
|
|
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
|
|
|
|
<< MatchTable::Comment("MMO") << MatchTable::IntValue(MMOIdx)
|
|
|
|
<< MatchTable::Comment("Size") << MatchTable::IntValue(Size)
|
|
|
|
<< MatchTable::LineBreak;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Generates code to check that the size of an MMO is less-than, equal-to, or
|
|
|
|
/// greater than a given LLT.
|
|
|
|
class MemoryVsLLTSizePredicateMatcher : public InstructionPredicateMatcher {
|
|
|
|
public:
|
|
|
|
enum RelationKind {
|
|
|
|
GreaterThan,
|
|
|
|
EqualTo,
|
|
|
|
LessThan,
|
|
|
|
};
|
|
|
|
|
|
|
|
protected:
|
|
|
|
unsigned MMOIdx;
|
|
|
|
RelationKind Relation;
|
|
|
|
unsigned OpIdx;
|
|
|
|
|
|
|
|
public:
|
|
|
|
MemoryVsLLTSizePredicateMatcher(unsigned InsnVarID, unsigned MMOIdx,
|
|
|
|
enum RelationKind Relation,
|
|
|
|
unsigned OpIdx)
|
|
|
|
: InstructionPredicateMatcher(IPM_MemoryVsLLTSize, InsnVarID),
|
|
|
|
MMOIdx(MMOIdx), Relation(Relation), OpIdx(OpIdx) {}
|
|
|
|
|
|
|
|
static bool classof(const PredicateMatcher *P) {
|
|
|
|
return P->getKind() == IPM_MemoryVsLLTSize;
|
|
|
|
}
|
|
|
|
bool isIdentical(const PredicateMatcher &B) const override {
|
|
|
|
return InstructionPredicateMatcher::isIdentical(B) &&
|
|
|
|
MMOIdx == cast<MemoryVsLLTSizePredicateMatcher>(&B)->MMOIdx &&
|
|
|
|
Relation == cast<MemoryVsLLTSizePredicateMatcher>(&B)->Relation &&
|
|
|
|
OpIdx == cast<MemoryVsLLTSizePredicateMatcher>(&B)->OpIdx;
|
|
|
|
}
|
|
|
|
|
|
|
|
void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) const override {
|
|
|
|
Table << MatchTable::Opcode(Relation == EqualTo
|
|
|
|
? "GIM_CheckMemorySizeEqualToLLT"
|
|
|
|
: Relation == GreaterThan
|
|
|
|
? "GIM_CheckMemorySizeGreaterThanLLT"
|
|
|
|
: "GIM_CheckMemorySizeLessThanLLT")
|
|
|
|
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
|
|
|
|
<< MatchTable::Comment("MMO") << MatchTable::IntValue(MMOIdx)
|
|
|
|
<< MatchTable::Comment("OpIdx") << MatchTable::IntValue(OpIdx)
|
|
|
|
<< MatchTable::LineBreak;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-06-16 07:13:43 +08:00
|
|
|
/// Generates code to check an arbitrary C++ instruction predicate.
|
|
|
|
class GenericInstructionPredicateMatcher : public InstructionPredicateMatcher {
|
|
|
|
protected:
|
|
|
|
TreePredicateFn Predicate;
|
|
|
|
|
|
|
|
public:
|
|
|
|
GenericInstructionPredicateMatcher(unsigned InsnVarID,
|
|
|
|
TreePredicateFn Predicate)
|
|
|
|
: InstructionPredicateMatcher(IPM_GenericPredicate, InsnVarID),
|
|
|
|
Predicate(Predicate) {}
|
|
|
|
|
|
|
|
static bool classof(const InstructionPredicateMatcher *P) {
|
|
|
|
return P->getKind() == IPM_GenericPredicate;
|
|
|
|
}
|
2018-09-26 01:59:02 +08:00
|
|
|
bool isIdentical(const PredicateMatcher &B) const override {
|
|
|
|
return InstructionPredicateMatcher::isIdentical(B) &&
|
|
|
|
Predicate ==
|
|
|
|
static_cast<const GenericInstructionPredicateMatcher &>(B)
|
|
|
|
.Predicate;
|
|
|
|
}
|
2018-06-16 07:13:43 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) const override {
|
|
|
|
Table << MatchTable::Opcode("GIM_CheckCxxInsnPredicate")
|
|
|
|
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
|
|
|
|
<< MatchTable::Comment("FnId")
|
|
|
|
<< MatchTable::NamedValue(getEnumNameForPredicate(Predicate))
|
|
|
|
<< 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
|
|
|
/// 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.
|
2018-05-22 07:28:51 +08:00
|
|
|
class InstructionMatcher final : public PredicateListMatcher<PredicateMatcher> {
|
[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
|
|
|
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
|
|
|
|
2017-10-14 08:31:58 +08:00
|
|
|
RuleMatcher &Rule;
|
|
|
|
|
[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;
|
2018-05-22 12:31:50 +08:00
|
|
|
bool NumOperandsCheck = true;
|
[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-08-08 18:44:31 +08:00
|
|
|
std::string SymbolicName;
|
2017-12-16 07:07:42 +08:00
|
|
|
unsigned InsnVarID;
|
2017-08-08 18:44:31 +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:
|
2017-10-14 08:31:58 +08:00
|
|
|
InstructionMatcher(RuleMatcher &Rule, StringRef SymbolicName)
|
2017-12-16 07:07:42 +08:00
|
|
|
: Rule(Rule), SymbolicName(SymbolicName) {
|
|
|
|
// We create a new instruction matcher.
|
|
|
|
// Get a new ID for that instruction.
|
|
|
|
InsnVarID = Rule.implicitlyDefineInsnVar(*this);
|
|
|
|
}
|
2017-10-14 08:31:58 +08:00
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
/// Construct a new instruction predicate and add it to the matcher.
|
|
|
|
template <class Kind, class... Args>
|
|
|
|
Optional<Kind *> addPredicate(Args &&... args) {
|
|
|
|
Predicates.emplace_back(
|
|
|
|
llvm::make_unique<Kind>(getInsnVarID(), std::forward<Args>(args)...));
|
|
|
|
return static_cast<Kind *>(Predicates.back().get());
|
|
|
|
}
|
|
|
|
|
2017-10-14 08:31:58 +08:00
|
|
|
RuleMatcher &getRuleMatcher() const { return Rule; }
|
2017-08-08 18:44:31 +08:00
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
unsigned getInsnVarID() const { return InsnVarID; }
|
2017-12-16 07:07:42 +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
|
|
|
/// 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));
|
2017-10-14 08:31:58 +08:00
|
|
|
if (!SymbolicName.empty())
|
|
|
|
Rule.defineOperand(SymbolicName, *Operands.back());
|
|
|
|
|
[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 *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) {
|
2018-05-22 07:28:51 +08:00
|
|
|
return X->getOpIdx() == 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");
|
|
|
|
}
|
|
|
|
|
2017-08-08 18:44:31 +08:00
|
|
|
StringRef getSymbolicName() const { return 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
|
|
|
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());
|
|
|
|
}
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
bool operands_empty() const { return Operands.empty(); }
|
|
|
|
|
|
|
|
void pop_front() { Operands.erase(Operands.begin()); }
|
[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
|
|
|
|
2018-05-22 12:31:50 +08:00
|
|
|
void optimize();
|
2018-05-22 07:28:51 +08:00
|
|
|
|
|
|
|
/// Emit MatchTable opcodes that test whether the instruction named in
|
|
|
|
/// InsnVarName matches all the predicates and all the operands.
|
|
|
|
void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule) {
|
2018-05-22 12:31:50 +08:00
|
|
|
if (NumOperandsCheck)
|
|
|
|
InstructionNumOperandsMatcher(InsnVarID, getNumOperands())
|
|
|
|
.emitPredicateOpcodes(Table, Rule);
|
[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-12-16 07:07:42 +08:00
|
|
|
emitPredicateListOpcodes(Table, Rule);
|
2018-05-22 07:28:51 +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 &Operand : Operands)
|
2017-12-16 07:07:42 +08:00
|
|
|
Operand->emitPredicateOpcodes(Table, Rule);
|
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.
|
2018-05-22 07:28:51 +08:00
|
|
|
bool isHigherPriorityThan(InstructionMatcher &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
|
|
|
// Instruction matchers involving more operands have higher priority.
|
|
|
|
if (Operands.size() > B.Operands.size())
|
|
|
|
return true;
|
|
|
|
if (Operands.size() < B.Operands.size())
|
|
|
|
return false;
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
for (auto &&P : zip(predicates(), B.predicates())) {
|
|
|
|
auto L = static_cast<InstructionPredicateMatcher *>(std::get<0>(P).get());
|
|
|
|
auto R = static_cast<InstructionPredicateMatcher *>(std::get<1>(P).get());
|
|
|
|
if (L->isHigherPriorityThan(*R))
|
[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;
|
2018-05-22 07:28:51 +08:00
|
|
|
if (R->isHigherPriorityThan(*L))
|
[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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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.
|
2018-05-22 07:28:51 +08:00
|
|
|
unsigned countRendererFns() {
|
|
|
|
return std::accumulate(
|
|
|
|
predicates().begin(), predicates().end(), 0,
|
|
|
|
[](unsigned A,
|
|
|
|
const std::unique_ptr<PredicateMatcher> &Predicate) {
|
|
|
|
return A + Predicate->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
|
|
|
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
|
|
|
}
|
2017-08-08 18:44:31 +08:00
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
InstructionOpcodeMatcher &getOpcodeMatcher() {
|
|
|
|
for (auto &P : predicates())
|
|
|
|
if (auto *OpMatcher = dyn_cast<InstructionOpcodeMatcher>(P.get()))
|
|
|
|
return *OpMatcher;
|
|
|
|
llvm_unreachable("Didn't find an opcode matcher");
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isConstantInstruction() {
|
|
|
|
return getOpcodeMatcher().isConstantInstruction();
|
2017-08-08 18:44:31 +08:00
|
|
|
}
|
2018-05-22 12:31:50 +08:00
|
|
|
|
|
|
|
StringRef getOpcode() { return getOpcodeMatcher().getOpcode(); }
|
2016-12-22 07:26:20 +08:00
|
|
|
};
|
|
|
|
|
2018-05-22 12:31:50 +08:00
|
|
|
StringRef RuleMatcher::getOpcode() const {
|
|
|
|
return Matchers.front()->getOpcode();
|
|
|
|
}
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
unsigned RuleMatcher::getNumOperands() const {
|
|
|
|
return Matchers.front()->getNumOperands();
|
|
|
|
}
|
|
|
|
|
2018-05-24 05:30:16 +08:00
|
|
|
LLTCodeGen RuleMatcher::getFirstConditionAsRootType() {
|
|
|
|
InstructionMatcher &InsnMatcher = *Matchers.front();
|
|
|
|
if (!InsnMatcher.predicates_empty())
|
|
|
|
if (const auto *TM =
|
|
|
|
dyn_cast<LLTOperandMatcher>(&**InsnMatcher.predicates_begin()))
|
|
|
|
if (TM->getInsnVarID() == 0 && TM->getOpIdx() == 0)
|
|
|
|
return TM->getTy();
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
[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:
|
2017-12-19 06:12:13 +08:00
|
|
|
InstructionOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
|
|
|
|
RuleMatcher &Rule, StringRef SymbolicName)
|
2017-12-16 07:07:42 +08:00
|
|
|
: OperandPredicateMatcher(OPM_Instruction, InsnVarID, OpIdx),
|
2017-10-14 08:31:58 +08:00
|
|
|
InsnMatcher(new InstructionMatcher(Rule, 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
|
|
|
|
2017-12-15 07:44:07 +08:00
|
|
|
static bool classof(const PredicateMatcher *P) {
|
[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 P->getKind() == OPM_Instruction;
|
|
|
|
}
|
|
|
|
|
|
|
|
InstructionMatcher &getInsnMatcher() const { return *InsnMatcher; }
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule) const {
|
|
|
|
const unsigned NewInsnVarID = InsnMatcher->getInsnVarID();
|
|
|
|
Table << MatchTable::Opcode("GIM_RecordInsn")
|
|
|
|
<< MatchTable::Comment("DefineMI")
|
|
|
|
<< MatchTable::IntValue(NewInsnVarID) << MatchTable::Comment("MI")
|
|
|
|
<< MatchTable::IntValue(getInsnVarID())
|
|
|
|
<< MatchTable::Comment("OpIdx") << MatchTable::IntValue(getOpIdx())
|
|
|
|
<< MatchTable::Comment("MIs[" + llvm::to_string(NewInsnVarID) + "]")
|
|
|
|
<< 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
|
|
|
}
|
|
|
|
|
2017-12-16 07:07:42 +08:00
|
|
|
void emitPredicateOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) const override {
|
2018-05-22 07:28:51 +08:00
|
|
|
emitCaptureOpcodes(Table, Rule);
|
2017-12-16 07:07:42 +08:00
|
|
|
InsnMatcher->emitPredicateOpcodes(Table, Rule);
|
[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
|
|
|
}
|
2018-01-18 04:34:29 +08:00
|
|
|
|
|
|
|
bool isHigherPriorityThan(const OperandPredicateMatcher &B) const override {
|
|
|
|
if (OperandPredicateMatcher::isHigherPriorityThan(B))
|
|
|
|
return true;
|
|
|
|
if (B.OperandPredicateMatcher::isHigherPriorityThan(*this))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (const InstructionOperandMatcher *BP =
|
|
|
|
dyn_cast<InstructionOperandMatcher>(&B))
|
|
|
|
if (InsnMatcher->isHigherPriorityThan(*BP->InsnMatcher))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
[tablegen][globalisel] Add support for nested instruction matching.
Summary:
Lift the restrictions that prevented the tree walking introduced in the
previous change and add support for patterns like:
(G_ADD (G_MUL (G_SEXT $src1), (G_SEXT $src2)), $src3) -> SMADDWrrr $dst, $src1, $src2, $src3
Also adds support for G_SEXT and G_ZEXT to support these cases.
One particular aspect of this that I should draw attention to is that I've
tried to be overly conservative in determining the safety of matches that
involve non-adjacent instructions and multiple basic blocks. This is intended
to be used as a cheap initial check and we may add a more expensive check in
the future. The current rules are:
* Reject if any instruction may load/store (we'd need to check for intervening
memory operations.
* Reject if any instruction has implicit operands.
* Reject if any instruction has unmodelled side-effects.
See isObviouslySafeToFold().
Reviewers: t.p.northover, javed.absar, qcolombet, aditya_nandakumar, ab, rovka
Reviewed By: ab
Subscribers: igorb, dberris, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D30539
llvm-svn: 299430
2017-04-04 21:25:23 +08:00
|
|
|
};
|
|
|
|
|
2018-05-22 12:31:50 +08:00
|
|
|
void InstructionMatcher::optimize() {
|
|
|
|
SmallVector<std::unique_ptr<PredicateMatcher>, 8> Stash;
|
|
|
|
const auto &OpcMatcher = getOpcodeMatcher();
|
|
|
|
|
|
|
|
Stash.push_back(predicates_pop_front());
|
|
|
|
if (Stash.back().get() == &OpcMatcher) {
|
|
|
|
if (NumOperandsCheck && OpcMatcher.getNumOperands() < getNumOperands())
|
|
|
|
Stash.emplace_back(
|
|
|
|
new InstructionNumOperandsMatcher(InsnVarID, getNumOperands()));
|
|
|
|
NumOperandsCheck = false;
|
2018-05-23 10:04:19 +08:00
|
|
|
|
|
|
|
for (auto &OM : Operands)
|
|
|
|
for (auto &OP : OM->predicates())
|
|
|
|
if (isa<IntrinsicIDOperandMatcher>(OP)) {
|
|
|
|
Stash.push_back(std::move(OP));
|
|
|
|
OM->eraseNullPredicates();
|
|
|
|
break;
|
|
|
|
}
|
2018-05-22 12:31:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (InsnVarID > 0) {
|
|
|
|
assert(!Operands.empty() && "Nested instruction is expected to def a vreg");
|
|
|
|
for (auto &OP : Operands[0]->predicates())
|
|
|
|
OP.reset();
|
|
|
|
Operands[0]->eraseNullPredicates();
|
|
|
|
}
|
2018-05-24 03:16:59 +08:00
|
|
|
for (auto &OM : Operands) {
|
|
|
|
for (auto &OP : OM->predicates())
|
|
|
|
if (isa<LLTOperandMatcher>(OP))
|
|
|
|
Stash.push_back(std::move(OP));
|
|
|
|
OM->eraseNullPredicates();
|
|
|
|
}
|
2018-05-22 12:31:50 +08:00
|
|
|
while (!Stash.empty())
|
|
|
|
prependPredicate(Stash.pop_back_val());
|
|
|
|
}
|
|
|
|
|
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,
|
2017-10-24 02:19:24 +08:00
|
|
|
OR_CopyOrAddZeroReg,
|
2017-06-27 18:11:39 +08:00
|
|
|
OR_CopySubReg,
|
2017-08-08 18:44:31 +08:00
|
|
|
OR_CopyConstantAsImm,
|
[globalisel][tablegen] Add support for fpimm and import of APInt/APFloat based ImmLeaf.
Summary:
There's only a tablegen testcase for IntImmLeaf and not a CodeGen one
because the relevant rules are rejected for other reasons at the moment.
On AArch64, it's because there's an SDNodeXForm attached to the operand.
On X86, it's because the rule either emits multiple instructions or has
another predicate using PatFrag which cannot easily be supported at the
same time.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36569
llvm-svn: 315761
2017-10-14 05:28:03 +08:00
|
|
|
OR_CopyFConstantAsFPImm,
|
2017-06-27 18:11:39 +08:00
|
|
|
OR_Imm,
|
|
|
|
OR_Register,
|
2017-11-02 03:57:57 +08:00
|
|
|
OR_TempRegister,
|
2018-01-17 02:44:05 +08:00
|
|
|
OR_ComplexPattern,
|
|
|
|
OR_Custom
|
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
|
|
|
|
|
|
|
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 name of the operand.
|
|
|
|
const StringRef SymbolicName;
|
|
|
|
|
|
|
|
public:
|
2017-10-24 09:48:34 +08:00
|
|
|
CopyRenderer(unsigned NewInsnID, StringRef SymbolicName)
|
|
|
|
: OperandRenderer(OR_Copy), NewInsnID(NewInsnID),
|
2017-08-08 18:44:31 +08:00
|
|
|
SymbolicName(SymbolicName) {
|
|
|
|
assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
|
|
|
|
}
|
[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 {
|
2017-10-14 08:31:58 +08:00
|
|
|
const OperandMatcher &Operand = Rule.getOperandMatcher(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")
|
2018-05-22 07:28:51 +08:00
|
|
|
<< MatchTable::IntValue(Operand.getOpIdx())
|
2017-07-20 17:25:44 +08:00
|
|
|
<< 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-10-24 02:19:24 +08:00
|
|
|
/// A CopyOrAddZeroRegRenderer emits code to copy a single operand from an
|
|
|
|
/// existing instruction to the one being built. If the operand turns out to be
|
|
|
|
/// a 'G_CONSTANT 0' then it replaces the operand with a zero register.
|
|
|
|
class CopyOrAddZeroRegRenderer : public OperandRenderer {
|
|
|
|
protected:
|
|
|
|
unsigned NewInsnID;
|
|
|
|
/// The name of the operand.
|
|
|
|
const StringRef SymbolicName;
|
|
|
|
const Record *ZeroRegisterDef;
|
|
|
|
|
|
|
|
public:
|
|
|
|
CopyOrAddZeroRegRenderer(unsigned NewInsnID,
|
|
|
|
StringRef SymbolicName, Record *ZeroRegisterDef)
|
|
|
|
: OperandRenderer(OR_CopyOrAddZeroReg), NewInsnID(NewInsnID),
|
|
|
|
SymbolicName(SymbolicName), ZeroRegisterDef(ZeroRegisterDef) {
|
|
|
|
assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool classof(const OperandRenderer *R) {
|
|
|
|
return R->getKind() == OR_CopyOrAddZeroReg;
|
|
|
|
}
|
|
|
|
|
|
|
|
const StringRef getSymbolicName() const { return SymbolicName; }
|
|
|
|
|
|
|
|
void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
|
|
|
|
const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
|
|
|
|
unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
|
|
|
|
Table << MatchTable::Opcode("GIR_CopyOrAddZeroReg")
|
|
|
|
<< MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
|
|
|
|
<< MatchTable::Comment("OldInsnID")
|
|
|
|
<< MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
|
2018-05-22 07:28:51 +08:00
|
|
|
<< MatchTable::IntValue(Operand.getOpIdx())
|
2017-10-24 02:19:24 +08:00
|
|
|
<< MatchTable::NamedValue(
|
|
|
|
(ZeroRegisterDef->getValue("Namespace")
|
|
|
|
? ZeroRegisterDef->getValueAsString("Namespace")
|
|
|
|
: ""),
|
|
|
|
ZeroRegisterDef->getName())
|
|
|
|
<< MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-08-08 18:44:31 +08:00
|
|
|
/// A CopyConstantAsImmRenderer emits code to render a G_CONSTANT instruction to
|
|
|
|
/// an extended immediate operand.
|
|
|
|
class CopyConstantAsImmRenderer : public OperandRenderer {
|
|
|
|
protected:
|
|
|
|
unsigned NewInsnID;
|
|
|
|
/// The name of the operand.
|
|
|
|
const std::string SymbolicName;
|
|
|
|
bool Signed;
|
|
|
|
|
|
|
|
public:
|
|
|
|
CopyConstantAsImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
|
|
|
|
: OperandRenderer(OR_CopyConstantAsImm), NewInsnID(NewInsnID),
|
|
|
|
SymbolicName(SymbolicName), Signed(true) {}
|
|
|
|
|
|
|
|
static bool classof(const OperandRenderer *R) {
|
|
|
|
return R->getKind() == OR_CopyConstantAsImm;
|
|
|
|
}
|
|
|
|
|
|
|
|
const StringRef getSymbolicName() const { return SymbolicName; }
|
|
|
|
|
|
|
|
void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
|
2018-05-22 07:28:51 +08:00
|
|
|
InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
|
2017-08-08 18:44:31 +08:00
|
|
|
unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
|
|
|
|
Table << MatchTable::Opcode(Signed ? "GIR_CopyConstantAsSImm"
|
|
|
|
: "GIR_CopyConstantAsUImm")
|
|
|
|
<< MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
|
|
|
|
<< MatchTable::Comment("OldInsnID")
|
|
|
|
<< MatchTable::IntValue(OldInsnVarID)
|
|
|
|
<< MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
[globalisel][tablegen] Add support for fpimm and import of APInt/APFloat based ImmLeaf.
Summary:
There's only a tablegen testcase for IntImmLeaf and not a CodeGen one
because the relevant rules are rejected for other reasons at the moment.
On AArch64, it's because there's an SDNodeXForm attached to the operand.
On X86, it's because the rule either emits multiple instructions or has
another predicate using PatFrag which cannot easily be supported at the
same time.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36569
llvm-svn: 315761
2017-10-14 05:28:03 +08:00
|
|
|
/// A CopyFConstantAsFPImmRenderer emits code to render a G_FCONSTANT
|
|
|
|
/// instruction to an extended immediate operand.
|
|
|
|
class CopyFConstantAsFPImmRenderer : public OperandRenderer {
|
|
|
|
protected:
|
|
|
|
unsigned NewInsnID;
|
|
|
|
/// The name of the operand.
|
|
|
|
const std::string SymbolicName;
|
|
|
|
|
|
|
|
public:
|
|
|
|
CopyFConstantAsFPImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
|
|
|
|
: OperandRenderer(OR_CopyFConstantAsFPImm), NewInsnID(NewInsnID),
|
|
|
|
SymbolicName(SymbolicName) {}
|
|
|
|
|
|
|
|
static bool classof(const OperandRenderer *R) {
|
|
|
|
return R->getKind() == OR_CopyFConstantAsFPImm;
|
|
|
|
}
|
|
|
|
|
|
|
|
const StringRef getSymbolicName() const { return SymbolicName; }
|
|
|
|
|
|
|
|
void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
|
2018-05-22 07:28:51 +08:00
|
|
|
InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
|
[globalisel][tablegen] Add support for fpimm and import of APInt/APFloat based ImmLeaf.
Summary:
There's only a tablegen testcase for IntImmLeaf and not a CodeGen one
because the relevant rules are rejected for other reasons at the moment.
On AArch64, it's because there's an SDNodeXForm attached to the operand.
On X86, it's because the rule either emits multiple instructions or has
another predicate using PatFrag which cannot easily be supported at the
same time.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36569
llvm-svn: 315761
2017-10-14 05:28:03 +08:00
|
|
|
unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
|
|
|
|
Table << MatchTable::Opcode("GIR_CopyFConstantAsFPImm")
|
|
|
|
<< MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
|
|
|
|
<< MatchTable::Comment("OldInsnID")
|
|
|
|
<< MatchTable::IntValue(OldInsnVarID)
|
|
|
|
<< MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
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 name of the operand.
|
|
|
|
const StringRef SymbolicName;
|
|
|
|
/// The subregister to extract.
|
|
|
|
const CodeGenSubRegIndex *SubReg;
|
|
|
|
|
|
|
|
public:
|
2017-10-24 09:48:34 +08:00
|
|
|
CopySubRegRenderer(unsigned NewInsnID, StringRef SymbolicName,
|
|
|
|
const CodeGenSubRegIndex *SubReg)
|
|
|
|
: OperandRenderer(OR_CopySubReg), NewInsnID(NewInsnID),
|
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-10-14 08:31:58 +08:00
|
|
|
const OperandMatcher &Operand = Rule.getOperandMatcher(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")
|
2018-05-22 07:28:51 +08:00
|
|
|
<< MatchTable::IntValue(Operand.getOpIdx())
|
2017-07-20 17:25:44 +08:00
|
|
|
<< 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
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-11-02 03:57:57 +08:00
|
|
|
/// Adds a specific temporary virtual register to the instruction being built.
|
|
|
|
/// This is used to chain instructions together when emitting multiple
|
|
|
|
/// instructions.
|
|
|
|
class TempRegRenderer : public OperandRenderer {
|
|
|
|
protected:
|
|
|
|
unsigned InsnID;
|
|
|
|
unsigned TempRegID;
|
|
|
|
bool IsDef;
|
|
|
|
|
|
|
|
public:
|
|
|
|
TempRegRenderer(unsigned InsnID, unsigned TempRegID, bool IsDef = false)
|
|
|
|
: OperandRenderer(OR_Register), InsnID(InsnID), TempRegID(TempRegID),
|
|
|
|
IsDef(IsDef) {}
|
|
|
|
|
|
|
|
static bool classof(const OperandRenderer *R) {
|
|
|
|
return R->getKind() == OR_TempRegister;
|
|
|
|
}
|
|
|
|
|
|
|
|
void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
|
|
|
|
Table << MatchTable::Opcode("GIR_AddTempRegister")
|
|
|
|
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
|
|
|
|
<< MatchTable::Comment("TempRegID") << MatchTable::IntValue(TempRegID)
|
|
|
|
<< MatchTable::Comment("TempRegFlags");
|
|
|
|
if (IsDef)
|
|
|
|
Table << MatchTable::NamedValue("RegState::Define");
|
|
|
|
else
|
|
|
|
Table << MatchTable::IntValue(0);
|
|
|
|
Table << 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
|
|
|
/// 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-10-16 02:22:54 +08:00
|
|
|
/// When provided, this is the suboperand of the ComplexPattern operand to
|
|
|
|
/// render. Otherwise all the suboperands will be rendered.
|
|
|
|
Optional<unsigned> SubOperand;
|
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,
|
2017-10-16 02:22:54 +08:00
|
|
|
StringRef SymbolicName, unsigned RendererID,
|
|
|
|
Optional<unsigned> SubOperand = None)
|
2017-07-05 17:39:33 +08:00
|
|
|
: OperandRenderer(OR_ComplexPattern), InsnID(InsnID), TheDef(TheDef),
|
2017-10-16 02:22:54 +08:00
|
|
|
SymbolicName(SymbolicName), RendererID(RendererID),
|
|
|
|
SubOperand(SubOperand) {}
|
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 {
|
2017-10-16 02:22:54 +08:00
|
|
|
Table << MatchTable::Opcode(SubOperand.hasValue() ? "GIR_ComplexSubOperandRenderer"
|
|
|
|
: "GIR_ComplexRenderer")
|
2017-07-20 17:25:44 +08:00
|
|
|
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
|
|
|
|
<< MatchTable::Comment("RendererID")
|
2017-10-16 02:22:54 +08:00
|
|
|
<< MatchTable::IntValue(RendererID);
|
|
|
|
if (SubOperand.hasValue())
|
|
|
|
Table << MatchTable::Comment("SubOperand")
|
|
|
|
<< MatchTable::IntValue(SubOperand.getValue());
|
|
|
|
Table << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
|
2017-03-15 05:32:08 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-01-17 02:44:05 +08:00
|
|
|
class CustomRenderer : public OperandRenderer {
|
|
|
|
protected:
|
|
|
|
unsigned InsnID;
|
|
|
|
const Record &Renderer;
|
|
|
|
/// The name of the operand.
|
|
|
|
const std::string SymbolicName;
|
|
|
|
|
|
|
|
public:
|
|
|
|
CustomRenderer(unsigned InsnID, const Record &Renderer,
|
|
|
|
StringRef SymbolicName)
|
|
|
|
: OperandRenderer(OR_Custom), InsnID(InsnID), Renderer(Renderer),
|
|
|
|
SymbolicName(SymbolicName) {}
|
|
|
|
|
|
|
|
static bool classof(const OperandRenderer *R) {
|
|
|
|
return R->getKind() == OR_Custom;
|
|
|
|
}
|
|
|
|
|
|
|
|
void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
|
2018-05-22 07:28:51 +08:00
|
|
|
InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
|
2018-01-17 02:44:05 +08:00
|
|
|
unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
|
|
|
|
Table << MatchTable::Opcode("GIR_CustomRenderer")
|
|
|
|
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
|
|
|
|
<< MatchTable::Comment("OldInsnID")
|
|
|
|
<< MatchTable::IntValue(OldInsnVarID)
|
|
|
|
<< MatchTable::Comment("Renderer")
|
|
|
|
<< MatchTable::NamedValue(
|
|
|
|
"GICR_" + Renderer.getValueAsString("RendererFn").str())
|
|
|
|
<< MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
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.
|
2017-11-01 02:50:24 +08:00
|
|
|
virtual void emitActionOpcodes(MatchTable &Table,
|
|
|
|
RuleMatcher &Rule) 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:
|
2017-11-01 02:07:03 +08:00
|
|
|
std::string S;
|
2017-02-04 08:47:08 +08:00
|
|
|
|
|
|
|
public:
|
2017-11-01 02:07:03 +08:00
|
|
|
DebugCommentAction(StringRef S) : S(S) {}
|
2017-02-04 08:47:08 +08:00
|
|
|
|
2017-11-01 02:50:24 +08:00
|
|
|
void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
|
2017-11-01 02:07:03 +08:00
|
|
|
Table << MatchTable::Comment(S) << 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;
|
2018-05-22 07:28:51 +08:00
|
|
|
InstructionMatcher *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
|
|
|
std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers;
|
|
|
|
|
|
|
|
/// True if the instruction can be built solely by mutating the opcode.
|
2017-11-01 02:50:24 +08:00
|
|
|
bool canMutate(RuleMatcher &Rule, const InstructionMatcher *Insn) const {
|
|
|
|
if (!Insn)
|
2017-10-25 02:11:54 +08:00
|
|
|
return false;
|
|
|
|
|
2017-11-01 02:50:24 +08:00
|
|
|
if (OperandRenderers.size() != Insn->getNumOperands())
|
2017-04-30 01:30:09 +08:00
|
|
|
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-10-14 08:31:58 +08:00
|
|
|
const OperandMatcher &OM = Rule.getOperandMatcher(Copy->getSymbolicName());
|
2017-11-01 02:50:24 +08:00
|
|
|
if (Insn != &OM.getInstructionMatcher() ||
|
2018-05-22 07:28:51 +08:00
|
|
|
OM.getOpIdx() != 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-11-01 02:50:24 +08:00
|
|
|
BuildMIAction(unsigned InsnID, const CodeGenInstruction *I)
|
|
|
|
: InsnID(InsnID), I(I), Matched(nullptr) {}
|
|
|
|
|
[ARM][GISel] PR35965 Constrain RegClasses of nested instructions built from Dst Pattern
Summary:
Apparently, we missed on constraining register classes of VReg-operands of all the instructions
built from a destination pattern but the root (top-level) one. The issue exposed itself
while selecting G_FPTOSI for armv7: the corresponding pattern generates VTOSIZS wrapped
into COPY_TO_REGCLASS, so top-level COPY_TO_REGCLASS gets properly constrained,
while nested VTOSIZS (or rather its destination virtual register to be exact) does not.
Fixing this by issuing GIR_ConstrainSelectedInstOperands for every nested GIR_BuildMI.
https://bugs.llvm.org/show_bug.cgi?id=35965
rdar://problem/36886530
Patch by Roman Tereshin
Reviewers: dsanders, qcolombet, rovka, bogner, aditya_nandakumar, volkan
Reviewed By: dsanders, qcolombet, rovka
Subscribers: aemerson, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D42565
llvm-svn: 323692
2018-01-30 05:09:12 +08:00
|
|
|
unsigned getInsnID() const { return InsnID; }
|
2017-11-01 03:09:29 +08:00
|
|
|
const CodeGenInstruction *getCGI() const { return I; }
|
|
|
|
|
2017-11-01 02:50:24 +08:00
|
|
|
void chooseInsnToMutate(RuleMatcher &Rule) {
|
2018-05-22 07:28:51 +08:00
|
|
|
for (auto *MutateCandidate : Rule.mutatable_insns()) {
|
2017-11-01 02:50:24 +08:00
|
|
|
if (canMutate(Rule, MutateCandidate)) {
|
|
|
|
// Take the first one we're offered that we're able to mutate.
|
|
|
|
Rule.reserveInsnMatcherForMutation(MutateCandidate);
|
|
|
|
Matched = MutateCandidate;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
[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(
|
2017-11-01 08:29:47 +08:00
|
|
|
llvm::make_unique<Kind>(InsnID, std::forward<Args>(args)...));
|
[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 *static_cast<Kind *>(OperandRenderers.back().get());
|
|
|
|
}
|
|
|
|
|
2017-11-01 02:50:24 +08:00
|
|
|
void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
|
|
|
|
if (Matched) {
|
|
|
|
assert(canMutate(Rule, Matched) &&
|
|
|
|
"Arranged to mutate an insn that isn't mutatable");
|
|
|
|
|
|
|
|
unsigned RecycleInsnID = Rule.getInsnVarID(*Matched);
|
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-08-03 22:48:22 +08:00
|
|
|
if (I->mayLoad || I->mayStore) {
|
|
|
|
Table << MatchTable::Opcode("GIR_MergeMemOperands")
|
|
|
|
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
|
|
|
|
<< MatchTable::Comment("MergeInsnID's");
|
|
|
|
// Emit the ID's for all the instructions that are matched by this rule.
|
|
|
|
// TODO: Limit this to matched instructions that mayLoad/mayStore or have
|
|
|
|
// some other means of having a memoperand. Also limit this to
|
|
|
|
// emitted instructions that expect to have a memoperand too. For
|
|
|
|
// example, (G_SEXT (G_LOAD x)) that results in separate load and
|
|
|
|
// sign-extend instructions shouldn't put the memoperand on the
|
|
|
|
// sign-extend since it has no effect there.
|
|
|
|
std::vector<unsigned> MergeInsnIDs;
|
|
|
|
for (const auto &IDMatcherPair : Rule.defined_insn_vars())
|
|
|
|
MergeInsnIDs.push_back(IDMatcherPair.second);
|
llvm::sort(C.begin(), C.end(), ...) -> llvm::sort(C, ...)
Summary: The convenience wrapper in STLExtras is available since rL342102.
Reviewers: dblaikie, javed.absar, JDevlieghere, andreadb
Subscribers: MatzeB, sanjoy, arsenm, dschuff, mehdi_amini, sdardis, nemanjai, jvesely, nhaehnle, sbc100, jgravelle-google, eraman, aheejin, kbarton, JDevlieghere, javed.absar, gbedwell, jrtc27, mgrang, atanasyan, steven_wu, george.burgess.iv, dexonsmith, kristina, jsji, llvm-commits
Differential Revision: https://reviews.llvm.org/D52573
llvm-svn: 343163
2018-09-27 10:13:45 +08:00
|
|
|
llvm::sort(MergeInsnIDs);
|
2017-08-03 22:48:22 +08:00
|
|
|
for (const auto &MergeInsnID : MergeInsnIDs)
|
|
|
|
Table << MatchTable::IntValue(MergeInsnID);
|
2017-08-08 18:44:31 +08:00
|
|
|
Table << MatchTable::NamedValue("GIU_MergeMemOperands_EndOfList")
|
|
|
|
<< MatchTable::LineBreak;
|
2017-08-03 22:48:22 +08:00
|
|
|
}
|
|
|
|
|
2017-11-02 03:57:57 +08:00
|
|
|
// FIXME: This is a hack but it's sufficient for ISel. We'll need to do
|
|
|
|
// better for combines. Particularly when there are multiple match
|
|
|
|
// roots.
|
|
|
|
if (InsnID == 0)
|
|
|
|
Table << MatchTable::Opcode("GIR_EraseFromParent")
|
|
|
|
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
|
|
|
|
<< 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-11-01 02:50:24 +08:00
|
|
|
void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
|
2017-07-20 17:25:44 +08:00
|
|
|
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-11-01 02:50:24 +08:00
|
|
|
void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
|
2017-07-20 17:25:44 +08:00
|
|
|
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-11-02 03:57:57 +08:00
|
|
|
/// Generates code to create a temporary register which can be used to chain
|
|
|
|
/// instructions together.
|
|
|
|
class MakeTempRegisterAction : public MatchAction {
|
|
|
|
private:
|
|
|
|
LLTCodeGen Ty;
|
|
|
|
unsigned TempRegID;
|
|
|
|
|
|
|
|
public:
|
|
|
|
MakeTempRegisterAction(const LLTCodeGen &Ty, unsigned TempRegID)
|
|
|
|
: Ty(Ty), TempRegID(TempRegID) {}
|
|
|
|
|
|
|
|
void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
|
|
|
|
Table << MatchTable::Opcode("GIR_MakeTempReg")
|
|
|
|
<< MatchTable::Comment("TempRegID") << MatchTable::IntValue(TempRegID)
|
|
|
|
<< MatchTable::Comment("TypeID")
|
|
|
|
<< MatchTable::NamedValue(Ty.getCxxEnumValue())
|
|
|
|
<< MatchTable::LineBreak;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-08-08 18:44:31 +08:00
|
|
|
InstructionMatcher &RuleMatcher::addInstructionMatcher(StringRef SymbolicName) {
|
2017-10-14 08:31:58 +08:00
|
|
|
Matchers.emplace_back(new InstructionMatcher(*this, SymbolicName));
|
2017-11-01 02:50:24 +08:00
|
|
|
MutatableInsns.insert(Matchers.back().get());
|
2017-03-16 04:18:38 +08:00
|
|
|
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-11-01 07:03:18 +08:00
|
|
|
// Emplaces an action of the specified Kind at the end of the action list.
|
|
|
|
//
|
|
|
|
// Returns a reference to the newly created action.
|
|
|
|
//
|
|
|
|
// Like std::vector::emplace_back(), may invalidate all iterators if the new
|
|
|
|
// size exceeds the capacity. Otherwise, only invalidates the past-the-end
|
|
|
|
// iterator.
|
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());
|
|
|
|
}
|
2017-11-02 03:57:57 +08:00
|
|
|
|
2017-11-01 07:03:18 +08:00
|
|
|
// Emplaces an action of the specified Kind before the given insertion point.
|
|
|
|
//
|
|
|
|
// Returns an iterator pointing at the newly created instruction.
|
|
|
|
//
|
|
|
|
// Like std::vector::insert(), may invalidate all iterators if the new size
|
|
|
|
// exceeds the capacity. Otherwise, only invalidates the iterators from the
|
|
|
|
// insertion point onwards.
|
|
|
|
template <class Kind, class... Args>
|
|
|
|
action_iterator RuleMatcher::insertAction(action_iterator InsertPt,
|
|
|
|
Args &&... args) {
|
2017-11-02 03:57:57 +08:00
|
|
|
return Actions.emplace(InsertPt,
|
|
|
|
llvm::make_unique<Kind>(std::forward<Args>(args)...));
|
2017-11-01 07:03:18 +08:00
|
|
|
}
|
2016-12-22 07:26:20 +08:00
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
unsigned RuleMatcher::implicitlyDefineInsnVar(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 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
|
|
|
}
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
unsigned RuleMatcher::getInsnVarID(InstructionMatcher &InsnMatcher) const {
|
[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 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-10-14 08:31:58 +08:00
|
|
|
void RuleMatcher::defineOperand(StringRef SymbolicName, OperandMatcher &OM) {
|
|
|
|
if (DefinedOperands.find(SymbolicName) == DefinedOperands.end()) {
|
|
|
|
DefinedOperands[SymbolicName] = &OM;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the operand is already defined, then we must ensure both references in
|
|
|
|
// the matcher have the exact same node.
|
|
|
|
OM.addPredicate<SameOperandMatcher>(OM.getSymbolicName());
|
|
|
|
}
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
InstructionMatcher &
|
2017-08-08 18:44:31 +08:00
|
|
|
RuleMatcher::getInstructionMatcher(StringRef SymbolicName) const {
|
|
|
|
for (const auto &I : InsnVariableIDs)
|
|
|
|
if (I.first->getSymbolicName() == SymbolicName)
|
|
|
|
return *I.first;
|
|
|
|
llvm_unreachable(
|
|
|
|
("Failed to lookup instruction " + SymbolicName).str().c_str());
|
|
|
|
}
|
|
|
|
|
2017-10-14 08:31:58 +08:00
|
|
|
const OperandMatcher &
|
|
|
|
RuleMatcher::getOperandMatcher(StringRef Name) const {
|
|
|
|
const auto &I = DefinedOperands.find(Name);
|
|
|
|
|
|
|
|
if (I == DefinedOperands.end())
|
|
|
|
PrintFatalError(SrcLoc, "Operand " + Name + " was not declared in matcher");
|
|
|
|
|
|
|
|
return *I->second;
|
|
|
|
}
|
|
|
|
|
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)
|
2018-05-22 07:28:51 +08:00
|
|
|
<< MatchTable::Comment("On fail goto")
|
|
|
|
<< MatchTable::JumpTarget(LabelID)
|
|
|
|
<< MatchTable::Comment(("Rule ID " + Twine(RuleID) + " //").str())
|
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-12-16 07:07:42 +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
|
|
|
|
[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
|
|
|
}
|
llvm::sort(C.begin(), C.end(), ...) -> llvm::sort(C, ...)
Summary: The convenience wrapper in STLExtras is available since rL342102.
Reviewers: dblaikie, javed.absar, JDevlieghere, andreadb
Subscribers: MatzeB, sanjoy, arsenm, dschuff, mehdi_amini, sdardis, nemanjai, jvesely, nhaehnle, sbc100, jgravelle-google, eraman, aheejin, kbarton, JDevlieghere, javed.absar, gbedwell, jrtc27, mgrang, atanasyan, steven_wu, george.burgess.iv, dexonsmith, kristina, jsji, llvm-commits
Differential Revision: https://reviews.llvm.org/D52573
llvm-svn: 343163
2018-09-27 10:13:45 +08:00
|
|
|
llvm::sort(InsnIDs);
|
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.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
for (const auto &PM : EpilogueMatchers)
|
|
|
|
PM->emitPredicateOpcodes(Table, *this);
|
|
|
|
|
2017-07-05 17:39:33 +08:00
|
|
|
for (const auto &MA : Actions)
|
2017-11-01 02:50:24 +08:00
|
|
|
MA->emitActionOpcodes(Table, *this);
|
[globalisel][tablegen] Generate rule coverage and use it to identify untested rules
Summary:
This patch adds a LLVM_ENABLE_GISEL_COV which, like LLVM_ENABLE_DAGISEL_COV,
causes TableGen to instrument the generated table to collect rule coverage
information. However, LLVM_ENABLE_GISEL_COV goes a bit further than
LLVM_ENABLE_DAGISEL_COV. The information is written to files
(${CMAKE_BINARY_DIR}/gisel-coverage-* by default). These files can then be
concatenated into ${LLVM_GISEL_COV_PREFIX}-all after which TableGen will
read this information and use it to emit warnings about untested rules.
This technique could also be used by SelectionDAG and can be further
extended to detect hot rules and give them priority over colder rules.
Usage:
* Enable LLVM_ENABLE_GISEL_COV in CMake
* Build the compiler and run some tests
* cat gisel-coverage-[0-9]* > gisel-coverage-all
* Delete lib/Target/*/*GenGlobalISel.inc*
* Build the compiler
Known issues:
* ${LLVM_GISEL_COV_PREFIX}-all must be generated as a manual
step due to a lack of a portable 'cat' command. It should be the
concatenation of all ${LLVM_GISEL_COV_PREFIX}-[0-9]* files.
* There's no mechanism to discard coverage information when the ruleset
changes
Depends on D39742
Reviewers: ab, qcolombet, t.p.northover, aditya_nandakumar, rovka
Reviewed By: rovka
Subscribers: vsk, arsenm, nhaehnle, mgorny, kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D39747
llvm-svn: 318356
2017-11-16 08:46:35 +08:00
|
|
|
|
2018-05-03 04:15:11 +08:00
|
|
|
if (Table.isWithCoverage())
|
[globalisel][tablegen] Generate rule coverage and use it to identify untested rules
Summary:
This patch adds a LLVM_ENABLE_GISEL_COV which, like LLVM_ENABLE_DAGISEL_COV,
causes TableGen to instrument the generated table to collect rule coverage
information. However, LLVM_ENABLE_GISEL_COV goes a bit further than
LLVM_ENABLE_DAGISEL_COV. The information is written to files
(${CMAKE_BINARY_DIR}/gisel-coverage-* by default). These files can then be
concatenated into ${LLVM_GISEL_COV_PREFIX}-all after which TableGen will
read this information and use it to emit warnings about untested rules.
This technique could also be used by SelectionDAG and can be further
extended to detect hot rules and give them priority over colder rules.
Usage:
* Enable LLVM_ENABLE_GISEL_COV in CMake
* Build the compiler and run some tests
* cat gisel-coverage-[0-9]* > gisel-coverage-all
* Delete lib/Target/*/*GenGlobalISel.inc*
* Build the compiler
Known issues:
* ${LLVM_GISEL_COV_PREFIX}-all must be generated as a manual
step due to a lack of a portable 'cat' command. It should be the
concatenation of all ${LLVM_GISEL_COV_PREFIX}-[0-9]* files.
* There's no mechanism to discard coverage information when the ruleset
changes
Depends on D39742
Reviewers: ab, qcolombet, t.p.northover, aditya_nandakumar, rovka
Reviewed By: rovka
Subscribers: vsk, arsenm, nhaehnle, mgorny, kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D39747
llvm-svn: 318356
2017-11-16 08:46:35 +08:00
|
|
|
Table << MatchTable::Opcode("GIR_Coverage") << MatchTable::IntValue(RuleID)
|
|
|
|
<< MatchTable::LineBreak;
|
2018-05-22 07:28:51 +08:00
|
|
|
else
|
|
|
|
Table << MatchTable::Comment(("GIR_Coverage, " + Twine(RuleID) + ",").str())
|
|
|
|
<< MatchTable::LineBreak;
|
[globalisel][tablegen] Generate rule coverage and use it to identify untested rules
Summary:
This patch adds a LLVM_ENABLE_GISEL_COV which, like LLVM_ENABLE_DAGISEL_COV,
causes TableGen to instrument the generated table to collect rule coverage
information. However, LLVM_ENABLE_GISEL_COV goes a bit further than
LLVM_ENABLE_DAGISEL_COV. The information is written to files
(${CMAKE_BINARY_DIR}/gisel-coverage-* by default). These files can then be
concatenated into ${LLVM_GISEL_COV_PREFIX}-all after which TableGen will
read this information and use it to emit warnings about untested rules.
This technique could also be used by SelectionDAG and can be further
extended to detect hot rules and give them priority over colder rules.
Usage:
* Enable LLVM_ENABLE_GISEL_COV in CMake
* Build the compiler and run some tests
* cat gisel-coverage-[0-9]* > gisel-coverage-all
* Delete lib/Target/*/*GenGlobalISel.inc*
* Build the compiler
Known issues:
* ${LLVM_GISEL_COV_PREFIX}-all must be generated as a manual
step due to a lack of a portable 'cat' command. It should be the
concatenation of all ${LLVM_GISEL_COV_PREFIX}-[0-9]* files.
* There's no mechanism to discard coverage information when the ruleset
changes
Depends on D39742
Reviewers: ab, qcolombet, t.p.northover, aditya_nandakumar, rovka
Reviewed By: rovka
Subscribers: vsk, arsenm, nhaehnle, mgorny, kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D39747
llvm-svn: 318356
2017-11-16 08:46:35 +08:00
|
|
|
|
2017-07-20 17:25:44 +08:00
|
|
|
Table << MatchTable::Opcode("GIR_Done", -1) << MatchTable::LineBreak
|
2017-07-27 19:03:45 +08:00
|
|
|
<< MatchTable::Label(LabelID);
|
2018-01-25 08:18:52 +08:00
|
|
|
++NumPatternEmitted;
|
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
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-08-08 18:44:31 +08:00
|
|
|
bool OperandPredicateMatcher::isHigherPriorityThan(
|
|
|
|
const OperandPredicateMatcher &B) const {
|
|
|
|
// Generally speaking, an instruction is more important than an Int or a
|
|
|
|
// LiteralInt because it can cover more nodes but theres an exception to
|
|
|
|
// this. G_CONSTANT's are less important than either of those two because they
|
|
|
|
// are more permissive.
|
Re-commit: [globalisel][tablegen] Support zero-instruction emission.
Summary:
Support the case where an operand of a pattern is also the whole of the
result pattern. In this case the original result and all its uses must be
replaced by the operand. However, register class restrictions can require
a COPY. This patch handles both cases by always emitting the copy and
leaving it for the register allocator to optimize.
The previous commit failed on Windows machines due to a flaw in the sort
predicate which allowed both A < B < C and B == C to be satisfied
simultaneously. The cause of this was some sloppiness in the priority order of
G_CONSTANT instructions compared to other instructions. These had equal priority
because it makes no difference, however there were operands had higher priority
than G_CONSTANT but lower priority than any other instruction. As a result, a
priority order between G_CONSTANT and other instructions must be enforced to
ensure the predicate defines a strict weak order.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Subscribers: javed.absar, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D36084
llvm-svn: 311076
2017-08-17 17:26:14 +08:00
|
|
|
|
|
|
|
const InstructionOperandMatcher *AOM =
|
|
|
|
dyn_cast<InstructionOperandMatcher>(this);
|
|
|
|
const InstructionOperandMatcher *BOM =
|
|
|
|
dyn_cast<InstructionOperandMatcher>(&B);
|
|
|
|
bool AIsConstantInsn = AOM && AOM->getInsnMatcher().isConstantInstruction();
|
|
|
|
bool BIsConstantInsn = BOM && BOM->getInsnMatcher().isConstantInstruction();
|
|
|
|
|
|
|
|
if (AOM && BOM) {
|
|
|
|
// The relative priorities between a G_CONSTANT and any other instruction
|
|
|
|
// don't actually matter but this code is needed to ensure a strict weak
|
|
|
|
// ordering. This is particularly important on Windows where the rules will
|
|
|
|
// be incorrectly sorted without it.
|
|
|
|
if (AIsConstantInsn != BIsConstantInsn)
|
|
|
|
return AIsConstantInsn < BIsConstantInsn;
|
|
|
|
return false;
|
2017-08-08 18:44:31 +08:00
|
|
|
}
|
|
|
|
|
Re-commit: [globalisel][tablegen] Support zero-instruction emission.
Summary:
Support the case where an operand of a pattern is also the whole of the
result pattern. In this case the original result and all its uses must be
replaced by the operand. However, register class restrictions can require
a COPY. This patch handles both cases by always emitting the copy and
leaving it for the register allocator to optimize.
The previous commit failed on Windows machines due to a flaw in the sort
predicate which allowed both A < B < C and B == C to be satisfied
simultaneously. The cause of this was some sloppiness in the priority order of
G_CONSTANT instructions compared to other instructions. These had equal priority
because it makes no difference, however there were operands had higher priority
than G_CONSTANT but lower priority than any other instruction. As a result, a
priority order between G_CONSTANT and other instructions must be enforced to
ensure the predicate defines a strict weak order.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Subscribers: javed.absar, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D36084
llvm-svn: 311076
2017-08-17 17:26:14 +08:00
|
|
|
if (AOM && AIsConstantInsn && (B.Kind == OPM_Int || B.Kind == OPM_LiteralInt))
|
|
|
|
return false;
|
|
|
|
if (BOM && BIsConstantInsn && (Kind == OPM_Int || Kind == OPM_LiteralInt))
|
|
|
|
return true;
|
|
|
|
|
2017-08-08 18:44:31 +08:00
|
|
|
return Kind < B.Kind;
|
2017-08-08 21:21:26 +08:00
|
|
|
}
|
2017-08-08 18:44:31 +08:00
|
|
|
|
2017-10-14 08:31:58 +08:00
|
|
|
void SameOperandMatcher::emitPredicateOpcodes(MatchTable &Table,
|
2017-12-16 07:07:42 +08:00
|
|
|
RuleMatcher &Rule) const {
|
2017-10-21 04:55:29 +08:00
|
|
|
const OperandMatcher &OtherOM = Rule.getOperandMatcher(MatchingName);
|
2017-10-14 08:31:58 +08:00
|
|
|
unsigned OtherInsnVarID = Rule.getInsnVarID(OtherOM.getInstructionMatcher());
|
2018-05-22 07:28:51 +08:00
|
|
|
assert(OtherInsnVarID == OtherOM.getInstructionMatcher().getInsnVarID());
|
2017-10-14 08:31:58 +08:00
|
|
|
|
|
|
|
Table << MatchTable::Opcode("GIM_CheckIsSameOperand")
|
|
|
|
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
|
|
|
|
<< MatchTable::Comment("OpIdx") << MatchTable::IntValue(OpIdx)
|
|
|
|
<< MatchTable::Comment("OtherMI")
|
|
|
|
<< MatchTable::IntValue(OtherInsnVarID)
|
|
|
|
<< MatchTable::Comment("OtherOpIdx")
|
2018-05-22 07:28:51 +08:00
|
|
|
<< MatchTable::IntValue(OtherOM.getOpIdx())
|
2017-10-14 08:31:58 +08:00
|
|
|
<< MatchTable::LineBreak;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
[globalisel][tablegen] Map ld and st to G_LOAD and G_STORE. NFC
Summary:
There is an important mismatch between ISD::LOAD and G_LOAD (and likewise for
ISD::STORE and G_STORE). In SelectionDAG, ISD::LOAD is a non-atomic load
and atomic loads are handled by a separate node. However, this is not true of
GlobalISel's G_LOAD. For G_LOAD, the MachineMemOperand indicates the atomicity
of the operation. As a result, this mapping must also add a predicate that
checks for non-atomic MachineMemOperands.
This is NFC since these nodes always have predicates in practice and are
therefore always rejected at the moment.
Depends on D37443
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37445
llvm-svn: 315843
2017-10-15 10:41:12 +08:00
|
|
|
/// Keep track of the equivalence between SDNodes and Instruction by mapping
|
2017-12-05 13:52:07 +08:00
|
|
|
/// SDNodes to the GINodeEquiv mapping. We need to map to the GINodeEquiv to
|
|
|
|
/// check for attributes on the relation such as CheckMMOIsNonAtomic.
|
2017-02-10 12:00:17 +08:00
|
|
|
/// This is defined using 'GINodeEquiv' in the target description.
|
[globalisel][tablegen] Map ld and st to G_LOAD and G_STORE. NFC
Summary:
There is an important mismatch between ISD::LOAD and G_LOAD (and likewise for
ISD::STORE and G_STORE). In SelectionDAG, ISD::LOAD is a non-atomic load
and atomic loads are handled by a separate node. However, this is not true of
GlobalISel's G_LOAD. For G_LOAD, the MachineMemOperand indicates the atomicity
of the operation. As a result, this mapping must also add a predicate that
checks for non-atomic MachineMemOperands.
This is NFC since these nodes always have predicates in practice and are
therefore always rejected at the moment.
Depends on D37443
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37445
llvm-svn: 315843
2017-10-15 10:41:12 +08:00
|
|
|
DenseMap<Record *, Record *> NodeEquivs;
|
2017-02-10 12:00:17 +08:00
|
|
|
|
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;
|
|
|
|
|
2018-01-17 02:44:05 +08:00
|
|
|
/// Keep track of the equivalence between SDNodeXForm's and
|
|
|
|
/// GICustomOperandRenderer. Map entries are specified by subclassing
|
|
|
|
/// GISDNodeXFormEquiv.
|
|
|
|
DenseMap<const Record *, const Record *> SDNodeXFormEquivs;
|
|
|
|
|
2018-02-17 06:37:15 +08:00
|
|
|
/// Keep track of Scores of PatternsToMatch similar to how the DAG does.
|
|
|
|
/// This adds compatibility for RuleMatchers to use this for ordering rules.
|
|
|
|
DenseMap<uint64_t, int> RuleMatcherScores;
|
|
|
|
|
[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
|
|
|
|
[globalisel][tablegen] Generate rule coverage and use it to identify untested rules
Summary:
This patch adds a LLVM_ENABLE_GISEL_COV which, like LLVM_ENABLE_DAGISEL_COV,
causes TableGen to instrument the generated table to collect rule coverage
information. However, LLVM_ENABLE_GISEL_COV goes a bit further than
LLVM_ENABLE_DAGISEL_COV. The information is written to files
(${CMAKE_BINARY_DIR}/gisel-coverage-* by default). These files can then be
concatenated into ${LLVM_GISEL_COV_PREFIX}-all after which TableGen will
read this information and use it to emit warnings about untested rules.
This technique could also be used by SelectionDAG and can be further
extended to detect hot rules and give them priority over colder rules.
Usage:
* Enable LLVM_ENABLE_GISEL_COV in CMake
* Build the compiler and run some tests
* cat gisel-coverage-[0-9]* > gisel-coverage-all
* Delete lib/Target/*/*GenGlobalISel.inc*
* Build the compiler
Known issues:
* ${LLVM_GISEL_COV_PREFIX}-all must be generated as a manual
step due to a lack of a portable 'cat' command. It should be the
concatenation of all ${LLVM_GISEL_COV_PREFIX}-[0-9]* files.
* There's no mechanism to discard coverage information when the ruleset
changes
Depends on D39742
Reviewers: ab, qcolombet, t.p.northover, aditya_nandakumar, rovka
Reviewed By: rovka
Subscribers: vsk, arsenm, nhaehnle, mgorny, kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D39747
llvm-svn: 318356
2017-11-16 08:46:35 +08:00
|
|
|
// Rule coverage information.
|
|
|
|
Optional<CodeGenCoverage> RuleCoverage;
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
void gatherOpcodeValues();
|
|
|
|
void gatherTypeIDValues();
|
2017-02-10 12:00:17 +08:00
|
|
|
void gatherNodeEquivs();
|
2018-06-16 07:13:43 +08:00
|
|
|
|
[globalisel][tablegen] Map ld and st to G_LOAD and G_STORE. NFC
Summary:
There is an important mismatch between ISD::LOAD and G_LOAD (and likewise for
ISD::STORE and G_STORE). In SelectionDAG, ISD::LOAD is a non-atomic load
and atomic loads are handled by a separate node. However, this is not true of
GlobalISel's G_LOAD. For G_LOAD, the MachineMemOperand indicates the atomicity
of the operation. As a result, this mapping must also add a predicate that
checks for non-atomic MachineMemOperands.
This is NFC since these nodes always have predicates in practice and are
therefore always rejected at the moment.
Depends on D37443
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37445
llvm-svn: 315843
2017-10-15 10:41:12 +08:00
|
|
|
Record *findNodeEquiv(Record *N) const;
|
[globalisel] Update GlobalISel emitter to match new representation of extending loads
Summary:
Previously, a extending load was represented at (G_*EXT (G_LOAD x)).
This had a few drawbacks:
* G_LOAD had to be legal for all sizes you could extend from, even if
registers didn't naturally hold those sizes.
* All sizes you could extend from had to be allocatable just in case the
extend went missing (e.g. by optimization).
* At minimum, G_*EXT and G_TRUNC had to be legal for these sizes. As we
improve optimization of extends and truncates, this legality requirement
would spread without considerable care w.r.t when certain combines were
permitted.
* The SelectionDAG importer required some ugly and fragile pattern
rewriting to translate patterns into this style.
This patch changes the representation to:
* (G_[SZ]EXTLOAD x)
* (G_LOAD x) any-extends when MMO.getSize() * 8 < ResultTy.getSizeInBits()
which resolves these issues by allowing targets to work entirely in their
native register sizes, and by having a more direct translation from
SelectionDAG patterns.
Each extending load can be lowered by the legalizer into separate extends
and loads, however a target that supports s1 will need the any-extending
load to extend to at least s8 since LLVM does not represent memory accesses
smaller than 8 bit. The legalizer can widenScalar G_LOAD into an
any-extending load but sign/zero-extending loads need help from something
else like a combiner pass. A follow-up patch that adds combiner helpers for
for this will follow.
The new representation requires that the MMO correctly reflect the memory
access so this has been corrected in a couple tests. I've also moved the
extending loads to their own tests since they are (mostly) separate opcodes
now. Additionally, the re-write appears to have invalidated two tests from
select-with-no-legality-check.mir since the matcher table no longer contains
loads that result in s1's and they aren't legal in AArch64 anymore.
Depends on D45540
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar
Reviewed By: rtereshin
Subscribers: javed.absar, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D45541
llvm-svn: 331601
2018-05-06 04:53:24 +08:00
|
|
|
const CodeGenInstruction *getEquivNode(Record &Equiv,
|
2018-06-15 04:32:58 +08:00
|
|
|
const TreePatternNode *N) const;
|
2017-02-10 12:00:17 +08:00
|
|
|
|
2017-09-15 00:56:21 +08:00
|
|
|
Error importRulePredicates(RuleMatcher &M, ArrayRef<Predicate> Predicates);
|
2018-06-16 07:13:43 +08:00
|
|
|
Expected<InstructionMatcher &>
|
|
|
|
createAndImportSelDAGMatcher(RuleMatcher &Rule,
|
|
|
|
InstructionMatcher &InsnMatcher,
|
|
|
|
const TreePatternNode *Src, unsigned &TempOpIdx);
|
2017-10-16 02:22:54 +08:00
|
|
|
Error importComplexPatternOperandMatcher(OperandMatcher &OM, Record *R,
|
|
|
|
unsigned &TempOpIdx) const;
|
|
|
|
Error importChildMatcher(RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
|
2018-06-15 04:32:58 +08:00
|
|
|
const TreePatternNode *SrcChild,
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
bool OperandIsAPointer, unsigned OpIdx,
|
2018-06-16 07:13:43 +08:00
|
|
|
unsigned &TempOpIdx);
|
2017-11-01 03:09:29 +08:00
|
|
|
|
2017-06-27 18:11:39 +08:00
|
|
|
Expected<BuildMIAction &>
|
2017-11-01 02:50:24 +08:00
|
|
|
createAndImportInstructionRenderer(RuleMatcher &M,
|
2018-06-15 04:32:58 +08:00
|
|
|
const TreePatternNode *Dst);
|
2017-11-02 03:57:57 +08:00
|
|
|
Expected<action_iterator> createAndImportSubInstructionRenderer(
|
2018-06-15 04:32:58 +08:00
|
|
|
action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst,
|
2017-11-02 03:57:57 +08:00
|
|
|
unsigned TempReg);
|
2017-11-01 07:03:18 +08:00
|
|
|
Expected<action_iterator>
|
|
|
|
createInstructionRenderer(action_iterator InsertPt, RuleMatcher &M,
|
2018-06-15 04:32:58 +08:00
|
|
|
const TreePatternNode *Dst);
|
2017-11-01 03:09:29 +08:00
|
|
|
void importExplicitDefRenderers(BuildMIAction &DstMIBuilder);
|
2017-11-01 07:03:18 +08:00
|
|
|
Expected<action_iterator>
|
|
|
|
importExplicitUseRenderers(action_iterator InsertPt, RuleMatcher &M,
|
|
|
|
BuildMIAction &DstMIBuilder,
|
2018-06-15 04:32:58 +08:00
|
|
|
const llvm::TreePatternNode *Dst);
|
2017-11-01 07:03:18 +08:00
|
|
|
Expected<action_iterator>
|
|
|
|
importExplicitUseRenderer(action_iterator InsertPt, RuleMatcher &Rule,
|
|
|
|
BuildMIAction &DstMIBuilder,
|
2018-06-15 04:32:58 +08:00
|
|
|
TreePatternNode *DstChild);
|
2019-05-30 15:30:37 +08:00
|
|
|
Error importDefaultOperandRenderers(action_iterator InsertPt, RuleMatcher &M,
|
|
|
|
BuildMIAction &DstMIBuilder,
|
2017-05-17 16:57:28 +08:00
|
|
|
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;
|
|
|
|
|
2018-06-16 07:13:43 +08:00
|
|
|
void emitCxxPredicateFns(raw_ostream &OS, StringRef CodeFieldName,
|
|
|
|
StringRef TypeIdentifier, StringRef ArgType,
|
|
|
|
StringRef ArgName, StringRef AdditionalDeclarations,
|
|
|
|
std::function<bool(const Record *R)> Filter);
|
|
|
|
void emitImmPredicateFns(raw_ostream &OS, StringRef TypeIdentifier,
|
|
|
|
StringRef ArgType,
|
|
|
|
std::function<bool(const Record *R)> Filter);
|
|
|
|
void emitMIPredicateFns(raw_ostream &OS);
|
[aarch64] Support APInt and APFloat in ImmLeaf subclasses and make AArch64 use them.
Summary:
The purpose of this patch is to expose more information about ImmLeaf-like
PatLeaf's so that GlobalISel can learn to import them. Previously, ImmLeaf
could only be used to test int64_t's produced by sign-extending an APInt.
Other tests on immediates had to use the generic PatLeaf and extract the
constant using C++.
With this patch, tablegen will know how to generate predicates for APInt,
and APFloat. This will allow it to 'do the right thing' for both SelectionDAG
and GlobalISel which require different methods of extracting the immediate
from the IR.
This is NFC for SelectionDAG since the new code is equivalent to the
previous code. It's also NFC for FastISel because FastIselShouldIgnore is 1
for the ImmLeaf subclasses. Enabling FastIselShouldIgnore == 0 for these new
subclasses will require a significant re-factor of FastISel.
For GlobalISel, it's currently NFC because the relevant code to import the
affected rules is not yet present. This will be added in a later patch.
Depends on D36086
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: bjope, aemerson, rengolin, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36534
llvm-svn: 315747
2017-10-14 04:42:18 +08:00
|
|
|
|
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-11-11 11:23:44 +08:00
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
MatchTable buildMatchTable(MutableArrayRef<RuleMatcher> Rules, bool Optimize,
|
|
|
|
bool WithCoverage);
|
|
|
|
|
|
|
|
public:
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
/// Takes a sequence of \p Rules and group them based on the predicates
|
2018-05-22 07:28:51 +08:00
|
|
|
/// they share. \p MatcherStorage is used as a memory container
|
2018-01-24 13:04:35 +08:00
|
|
|
/// for the group that are created as part of this process.
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
///
|
2018-05-22 07:28:51 +08:00
|
|
|
/// What this optimization does looks like if GroupT = GroupMatcher:
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
/// Output without optimization:
|
|
|
|
/// \verbatim
|
|
|
|
/// # R1
|
|
|
|
/// # predicate A
|
|
|
|
/// # predicate B
|
|
|
|
/// ...
|
|
|
|
/// # R2
|
|
|
|
/// # predicate A // <-- effectively this is going to be checked twice.
|
|
|
|
/// // Once in R1 and once in R2.
|
|
|
|
/// # predicate C
|
|
|
|
/// \endverbatim
|
|
|
|
/// Output with optimization:
|
|
|
|
/// \verbatim
|
|
|
|
/// # Group1_2
|
|
|
|
/// # predicate A // <-- Check is now shared.
|
|
|
|
/// # R1
|
|
|
|
/// # predicate B
|
|
|
|
/// # R2
|
|
|
|
/// # predicate C
|
|
|
|
/// \endverbatim
|
2018-05-22 07:28:51 +08:00
|
|
|
template <class GroupT>
|
|
|
|
static std::vector<Matcher *> optimizeRules(
|
2018-05-03 04:08:14 +08:00
|
|
|
ArrayRef<Matcher *> Rules,
|
2018-05-22 07:28:51 +08:00
|
|
|
std::vector<std::unique_ptr<Matcher>> &MatcherStorage);
|
2018-05-22 06:21:24 +08:00
|
|
|
};
|
[GlobalISel] Improving InstructionSelect's performance by reducing MatchTable, mostly NFC, perf patch 1
This patch starts a series of patches that decrease time spent by
GlobalISel in its InstructionSelect pass by roughly 60% for -O0 builds
for large inputs as measured on sqlite3-amalgamation
(http://sqlite.org/download.html) targeting AArch64.
The performance improvements are achieved solely by reducing the
number of matching GIM_* opcodes executed by the MatchTable's
interpreter during the selection by approx. a factor of 30, which also
brings contribution of this particular part of the selection process
to the overall runtime of InstructionSelect pass down from approx.
60-70% to 5-7%, thus making further improvements in this particular
direction not very profitable.
The improvements described above are expected for any target that
doesn't have many complex patterns. The targets that do should
strictly benefit from the changes, but by how much exactly is hard to
estimate beforehand. It's also likely that such target WILL benefit
from further improvements to MatchTable, most likely the ones that
bring it closer to a perfect decision tree.
This commit specifically is rather large mostly NFC commit that does
necessary preparation work and refactoring, there will be a following
series of small patches introducing a specific optimization each
shortly after.
This commit specifically is expected to cause a small compile time
regression (around 2.5% of InstructionSelect pass time), which should
be fixed by the next commit of the series.
Every commit planned shares the same Phabricator Review.
Reviewers: qcolombet, dsanders, bogner, aemerson, javed.absar
Reviewed By: qcolombet
Subscribers: rovka, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D44700
llvm-svn: 332907
2018-05-22 06:04:39 +08:00
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
void GlobalISelEmitter::gatherOpcodeValues() {
|
|
|
|
InstructionOpcodeMatcher::initOpcodeValuesMap(Target);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GlobalISelEmitter::gatherTypeIDValues() {
|
|
|
|
LLTOperandMatcher::initTypeIDValuesMap();
|
|
|
|
}
|
|
|
|
|
2016-12-22 07:26:20 +08:00
|
|
|
void GlobalISelEmitter::gatherNodeEquivs() {
|
|
|
|
assert(NodeEquivs.empty());
|
|
|
|
for (Record *Equiv : RK.getAllDerivedDefinitions("GINodeEquiv"))
|
[globalisel][tablegen] Map ld and st to G_LOAD and G_STORE. NFC
Summary:
There is an important mismatch between ISD::LOAD and G_LOAD (and likewise for
ISD::STORE and G_STORE). In SelectionDAG, ISD::LOAD is a non-atomic load
and atomic loads are handled by a separate node. However, this is not true of
GlobalISel's G_LOAD. For G_LOAD, the MachineMemOperand indicates the atomicity
of the operation. As a result, this mapping must also add a predicate that
checks for non-atomic MachineMemOperands.
This is NFC since these nodes always have predicates in practice and are
therefore always rejected at the moment.
Depends on D37443
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37445
llvm-svn: 315843
2017-10-15 10:41:12 +08:00
|
|
|
NodeEquivs[Equiv->getValueAsDef("Node")] = Equiv;
|
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;
|
|
|
|
}
|
2018-01-17 02:44:05 +08:00
|
|
|
|
|
|
|
assert(SDNodeXFormEquivs.empty());
|
|
|
|
for (Record *Equiv : RK.getAllDerivedDefinitions("GISDNodeXFormEquiv")) {
|
|
|
|
Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
|
|
|
|
if (!SelDAGEquiv)
|
|
|
|
continue;
|
|
|
|
SDNodeXFormEquivs[SelDAGEquiv] = Equiv;
|
|
|
|
}
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
|
|
|
|
[globalisel][tablegen] Map ld and st to G_LOAD and G_STORE. NFC
Summary:
There is an important mismatch between ISD::LOAD and G_LOAD (and likewise for
ISD::STORE and G_STORE). In SelectionDAG, ISD::LOAD is a non-atomic load
and atomic loads are handled by a separate node. However, this is not true of
GlobalISel's G_LOAD. For G_LOAD, the MachineMemOperand indicates the atomicity
of the operation. As a result, this mapping must also add a predicate that
checks for non-atomic MachineMemOperands.
This is NFC since these nodes always have predicates in practice and are
therefore always rejected at the moment.
Depends on D37443
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: kristof.beyls, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37445
llvm-svn: 315843
2017-10-15 10:41:12 +08:00
|
|
|
Record *GlobalISelEmitter::findNodeEquiv(Record *N) const {
|
2016-12-22 07:26:20 +08:00
|
|
|
return NodeEquivs.lookup(N);
|
|
|
|
}
|
|
|
|
|
[globalisel] Update GlobalISel emitter to match new representation of extending loads
Summary:
Previously, a extending load was represented at (G_*EXT (G_LOAD x)).
This had a few drawbacks:
* G_LOAD had to be legal for all sizes you could extend from, even if
registers didn't naturally hold those sizes.
* All sizes you could extend from had to be allocatable just in case the
extend went missing (e.g. by optimization).
* At minimum, G_*EXT and G_TRUNC had to be legal for these sizes. As we
improve optimization of extends and truncates, this legality requirement
would spread without considerable care w.r.t when certain combines were
permitted.
* The SelectionDAG importer required some ugly and fragile pattern
rewriting to translate patterns into this style.
This patch changes the representation to:
* (G_[SZ]EXTLOAD x)
* (G_LOAD x) any-extends when MMO.getSize() * 8 < ResultTy.getSizeInBits()
which resolves these issues by allowing targets to work entirely in their
native register sizes, and by having a more direct translation from
SelectionDAG patterns.
Each extending load can be lowered by the legalizer into separate extends
and loads, however a target that supports s1 will need the any-extending
load to extend to at least s8 since LLVM does not represent memory accesses
smaller than 8 bit. The legalizer can widenScalar G_LOAD into an
any-extending load but sign/zero-extending loads need help from something
else like a combiner pass. A follow-up patch that adds combiner helpers for
for this will follow.
The new representation requires that the MMO correctly reflect the memory
access so this has been corrected in a couple tests. I've also moved the
extending loads to their own tests since they are (mostly) separate opcodes
now. Additionally, the re-write appears to have invalidated two tests from
select-with-no-legality-check.mir since the matcher table no longer contains
loads that result in s1's and they aren't legal in AArch64 anymore.
Depends on D45540
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar
Reviewed By: rtereshin
Subscribers: javed.absar, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D45541
llvm-svn: 331601
2018-05-06 04:53:24 +08:00
|
|
|
const CodeGenInstruction *
|
2018-06-15 04:32:58 +08:00
|
|
|
GlobalISelEmitter::getEquivNode(Record &Equiv, const TreePatternNode *N) const {
|
TableGen/ISel: Allow PatFrag predicate code to access captured operands
Summary:
This simplifies writing predicates for pattern fragments that are
automatically re-associated or commuted.
For example, a followup patch adds patterns for fragments of the form
(add (shl $x, $y), $z) to the AMDGPU backend. Such patterns are
automatically commuted to (add $z, (shl $x, $y)), which makes it basically
impossible to refer to $x, $y, and $z generically in the PredicateCode.
With this change, the PredicateCode can refer to $x, $y, and $z simply
as `Operands[i]`.
Test confirmed that there are no changes to any of the generated files
when building all (non-experimental) targets.
Change-Id: I61c00ace7eed42c1d4edc4c5351174b56b77a79c
Reviewers: arsenm, rampitec, RKSimon, craig.topper, hfinkel, uweigand
Subscribers: wdng, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D51994
llvm-svn: 347992
2018-11-30 22:15:13 +08:00
|
|
|
for (const TreePredicateCall &Call : N->getPredicateCalls()) {
|
|
|
|
const TreePredicateFn &Predicate = Call.Fn;
|
[globalisel] Update GlobalISel emitter to match new representation of extending loads
Summary:
Previously, a extending load was represented at (G_*EXT (G_LOAD x)).
This had a few drawbacks:
* G_LOAD had to be legal for all sizes you could extend from, even if
registers didn't naturally hold those sizes.
* All sizes you could extend from had to be allocatable just in case the
extend went missing (e.g. by optimization).
* At minimum, G_*EXT and G_TRUNC had to be legal for these sizes. As we
improve optimization of extends and truncates, this legality requirement
would spread without considerable care w.r.t when certain combines were
permitted.
* The SelectionDAG importer required some ugly and fragile pattern
rewriting to translate patterns into this style.
This patch changes the representation to:
* (G_[SZ]EXTLOAD x)
* (G_LOAD x) any-extends when MMO.getSize() * 8 < ResultTy.getSizeInBits()
which resolves these issues by allowing targets to work entirely in their
native register sizes, and by having a more direct translation from
SelectionDAG patterns.
Each extending load can be lowered by the legalizer into separate extends
and loads, however a target that supports s1 will need the any-extending
load to extend to at least s8 since LLVM does not represent memory accesses
smaller than 8 bit. The legalizer can widenScalar G_LOAD into an
any-extending load but sign/zero-extending loads need help from something
else like a combiner pass. A follow-up patch that adds combiner helpers for
for this will follow.
The new representation requires that the MMO correctly reflect the memory
access so this has been corrected in a couple tests. I've also moved the
extending loads to their own tests since they are (mostly) separate opcodes
now. Additionally, the re-write appears to have invalidated two tests from
select-with-no-legality-check.mir since the matcher table no longer contains
loads that result in s1's and they aren't legal in AArch64 anymore.
Depends on D45540
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar
Reviewed By: rtereshin
Subscribers: javed.absar, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D45541
llvm-svn: 331601
2018-05-06 04:53:24 +08:00
|
|
|
if (!Equiv.isValueUnset("IfSignExtend") && Predicate.isLoad() &&
|
|
|
|
Predicate.isSignExtLoad())
|
|
|
|
return &Target.getInstruction(Equiv.getValueAsDef("IfSignExtend"));
|
|
|
|
if (!Equiv.isValueUnset("IfZeroExtend") && Predicate.isLoad() &&
|
|
|
|
Predicate.isZeroExtLoad())
|
|
|
|
return &Target.getInstruction(Equiv.getValueAsDef("IfZeroExtend"));
|
|
|
|
}
|
|
|
|
return &Target.getInstruction(Equiv.getValueAsDef("I"));
|
|
|
|
}
|
|
|
|
|
2016-12-22 07:26:20 +08:00
|
|
|
GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
|
[globalisel] Update GlobalISel emitter to match new representation of extending loads
Summary:
Previously, a extending load was represented at (G_*EXT (G_LOAD x)).
This had a few drawbacks:
* G_LOAD had to be legal for all sizes you could extend from, even if
registers didn't naturally hold those sizes.
* All sizes you could extend from had to be allocatable just in case the
extend went missing (e.g. by optimization).
* At minimum, G_*EXT and G_TRUNC had to be legal for these sizes. As we
improve optimization of extends and truncates, this legality requirement
would spread without considerable care w.r.t when certain combines were
permitted.
* The SelectionDAG importer required some ugly and fragile pattern
rewriting to translate patterns into this style.
This patch changes the representation to:
* (G_[SZ]EXTLOAD x)
* (G_LOAD x) any-extends when MMO.getSize() * 8 < ResultTy.getSizeInBits()
which resolves these issues by allowing targets to work entirely in their
native register sizes, and by having a more direct translation from
SelectionDAG patterns.
Each extending load can be lowered by the legalizer into separate extends
and loads, however a target that supports s1 will need the any-extending
load to extend to at least s8 since LLVM does not represent memory accesses
smaller than 8 bit. The legalizer can widenScalar G_LOAD into an
any-extending load but sign/zero-extending loads need help from something
else like a combiner pass. A follow-up patch that adds combiner helpers for
for this will follow.
The new representation requires that the MMO correctly reflect the memory
access so this has been corrected in a couple tests. I've also moved the
extending loads to their own tests since they are (mostly) separate opcodes
now. Additionally, the re-write appears to have invalidated two tests from
select-with-no-legality-check.mir since the matcher table no longer contains
loads that result in s1's and they aren't legal in AArch64 anymore.
Depends on D45540
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar
Reviewed By: rtereshin
Subscribers: javed.absar, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D45541
llvm-svn: 331601
2018-05-06 04:53:24 +08:00
|
|
|
: RK(RK), CGP(RK), Target(CGP.getTargetInfo()),
|
|
|
|
CGRegs(RK, Target.getHwModes()) {}
|
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,
|
2017-09-15 00:56:21 +08:00
|
|
|
ArrayRef<Predicate> Predicates) {
|
|
|
|
for (const Predicate &P : Predicates) {
|
|
|
|
if (!P.Def)
|
|
|
|
continue;
|
|
|
|
declareSubtargetFeature(P.Def);
|
|
|
|
M.addRequiredFeature(P.Def);
|
[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-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-12-05 13:52:07 +08:00
|
|
|
Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
|
|
|
|
RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
|
2018-06-16 07:13:43 +08:00
|
|
|
const TreePatternNode *Src, unsigned &TempOpIdx) {
|
2017-12-05 13:52:07 +08:00
|
|
|
Record *SrcGIEquivOrNull = nullptr;
|
|
|
|
const CodeGenInstruction *SrcGIOrNull = nullptr;
|
|
|
|
|
|
|
|
// Start with the defined operands (i.e., the results of the root operator).
|
2018-06-15 04:32:58 +08:00
|
|
|
if (Src->getExtTypes().size() > 1)
|
2017-12-05 13:52:07 +08:00
|
|
|
return failedImport("Src pattern has multiple results");
|
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
if (Src->isLeaf()) {
|
|
|
|
Init *SrcInit = Src->getLeafValue();
|
2017-12-05 13:52:07 +08:00
|
|
|
if (isa<IntInit>(SrcInit)) {
|
|
|
|
InsnMatcher.addPredicate<InstructionOpcodeMatcher>(
|
|
|
|
&Target.getInstruction(RK.getDef("G_CONSTANT")));
|
|
|
|
} else
|
|
|
|
return failedImport(
|
|
|
|
"Unable to deduce gMIR opcode to handle Src (which is a leaf)");
|
|
|
|
} else {
|
2018-06-15 04:32:58 +08:00
|
|
|
SrcGIEquivOrNull = findNodeEquiv(Src->getOperator());
|
2017-12-05 13:52:07 +08:00
|
|
|
if (!SrcGIEquivOrNull)
|
|
|
|
return failedImport("Pattern operator lacks an equivalent Instruction" +
|
2018-06-15 04:32:58 +08:00
|
|
|
explainOperator(Src->getOperator()));
|
[globalisel] Update GlobalISel emitter to match new representation of extending loads
Summary:
Previously, a extending load was represented at (G_*EXT (G_LOAD x)).
This had a few drawbacks:
* G_LOAD had to be legal for all sizes you could extend from, even if
registers didn't naturally hold those sizes.
* All sizes you could extend from had to be allocatable just in case the
extend went missing (e.g. by optimization).
* At minimum, G_*EXT and G_TRUNC had to be legal for these sizes. As we
improve optimization of extends and truncates, this legality requirement
would spread without considerable care w.r.t when certain combines were
permitted.
* The SelectionDAG importer required some ugly and fragile pattern
rewriting to translate patterns into this style.
This patch changes the representation to:
* (G_[SZ]EXTLOAD x)
* (G_LOAD x) any-extends when MMO.getSize() * 8 < ResultTy.getSizeInBits()
which resolves these issues by allowing targets to work entirely in their
native register sizes, and by having a more direct translation from
SelectionDAG patterns.
Each extending load can be lowered by the legalizer into separate extends
and loads, however a target that supports s1 will need the any-extending
load to extend to at least s8 since LLVM does not represent memory accesses
smaller than 8 bit. The legalizer can widenScalar G_LOAD into an
any-extending load but sign/zero-extending loads need help from something
else like a combiner pass. A follow-up patch that adds combiner helpers for
for this will follow.
The new representation requires that the MMO correctly reflect the memory
access so this has been corrected in a couple tests. I've also moved the
extending loads to their own tests since they are (mostly) separate opcodes
now. Additionally, the re-write appears to have invalidated two tests from
select-with-no-legality-check.mir since the matcher table no longer contains
loads that result in s1's and they aren't legal in AArch64 anymore.
Depends on D45540
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar
Reviewed By: rtereshin
Subscribers: javed.absar, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D45541
llvm-svn: 331601
2018-05-06 04:53:24 +08:00
|
|
|
SrcGIOrNull = getEquivNode(*SrcGIEquivOrNull, Src);
|
2017-12-05 13:52:07 +08:00
|
|
|
|
|
|
|
// The operators look good: match the opcode
|
|
|
|
InsnMatcher.addPredicate<InstructionOpcodeMatcher>(SrcGIOrNull);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned OpIdx = 0;
|
2018-06-15 04:32:58 +08:00
|
|
|
for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
|
2017-12-05 13:52:07 +08:00
|
|
|
// Results don't have a name unless they are the root node. The caller will
|
|
|
|
// set the name if appropriate.
|
|
|
|
OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
|
|
|
|
if (auto Error = OM.addTypeCheckPredicate(VTy, false /* OperandIsAPointer */))
|
|
|
|
return failedImport(toString(std::move(Error)) +
|
|
|
|
" for result of Src pattern operator");
|
|
|
|
}
|
|
|
|
|
TableGen/ISel: Allow PatFrag predicate code to access captured operands
Summary:
This simplifies writing predicates for pattern fragments that are
automatically re-associated or commuted.
For example, a followup patch adds patterns for fragments of the form
(add (shl $x, $y), $z) to the AMDGPU backend. Such patterns are
automatically commuted to (add $z, (shl $x, $y)), which makes it basically
impossible to refer to $x, $y, and $z generically in the PredicateCode.
With this change, the PredicateCode can refer to $x, $y, and $z simply
as `Operands[i]`.
Test confirmed that there are no changes to any of the generated files
when building all (non-experimental) targets.
Change-Id: I61c00ace7eed42c1d4edc4c5351174b56b77a79c
Reviewers: arsenm, rampitec, RKSimon, craig.topper, hfinkel, uweigand
Subscribers: wdng, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D51994
llvm-svn: 347992
2018-11-30 22:15:13 +08:00
|
|
|
for (const TreePredicateCall &Call : Src->getPredicateCalls()) {
|
|
|
|
const TreePredicateFn &Predicate = Call.Fn;
|
2017-08-24 17:11:20 +08:00
|
|
|
if (Predicate.isAlwaysTrue())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (Predicate.isImmediatePattern()) {
|
|
|
|
InsnMatcher.addPredicate<InstructionImmPredicateMatcher>(Predicate);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
[globalisel] Update GlobalISel emitter to match new representation of extending loads
Summary:
Previously, a extending load was represented at (G_*EXT (G_LOAD x)).
This had a few drawbacks:
* G_LOAD had to be legal for all sizes you could extend from, even if
registers didn't naturally hold those sizes.
* All sizes you could extend from had to be allocatable just in case the
extend went missing (e.g. by optimization).
* At minimum, G_*EXT and G_TRUNC had to be legal for these sizes. As we
improve optimization of extends and truncates, this legality requirement
would spread without considerable care w.r.t when certain combines were
permitted.
* The SelectionDAG importer required some ugly and fragile pattern
rewriting to translate patterns into this style.
This patch changes the representation to:
* (G_[SZ]EXTLOAD x)
* (G_LOAD x) any-extends when MMO.getSize() * 8 < ResultTy.getSizeInBits()
which resolves these issues by allowing targets to work entirely in their
native register sizes, and by having a more direct translation from
SelectionDAG patterns.
Each extending load can be lowered by the legalizer into separate extends
and loads, however a target that supports s1 will need the any-extending
load to extend to at least s8 since LLVM does not represent memory accesses
smaller than 8 bit. The legalizer can widenScalar G_LOAD into an
any-extending load but sign/zero-extending loads need help from something
else like a combiner pass. A follow-up patch that adds combiner helpers for
for this will follow.
The new representation requires that the MMO correctly reflect the memory
access so this has been corrected in a couple tests. I've also moved the
extending loads to their own tests since they are (mostly) separate opcodes
now. Additionally, the re-write appears to have invalidated two tests from
select-with-no-legality-check.mir since the matcher table no longer contains
loads that result in s1's and they aren't legal in AArch64 anymore.
Depends on D45540
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar
Reviewed By: rtereshin
Subscribers: javed.absar, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D45541
llvm-svn: 331601
2018-05-06 04:53:24 +08:00
|
|
|
// G_LOAD is used for both non-extending and any-extending loads.
|
|
|
|
if (Predicate.isLoad() && Predicate.isNonExtLoad()) {
|
|
|
|
InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
|
|
|
|
0, MemoryVsLLTSizePredicateMatcher::EqualTo, 0);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (Predicate.isLoad() && Predicate.isAnyExtLoad()) {
|
|
|
|
InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
|
|
|
|
0, MemoryVsLLTSizePredicateMatcher::LessThan, 0);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// No check required. We already did it by swapping the opcode.
|
|
|
|
if (!SrcGIEquivOrNull->isValueUnset("IfSignExtend") &&
|
|
|
|
Predicate.isSignExtLoad())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// No check required. We already did it by swapping the opcode.
|
|
|
|
if (!SrcGIEquivOrNull->isValueUnset("IfZeroExtend") &&
|
|
|
|
Predicate.isZeroExtLoad())
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
continue;
|
|
|
|
|
2017-10-24 02:19:24 +08:00
|
|
|
// No check required. G_STORE by itself is a non-extending store.
|
|
|
|
if (Predicate.isNonTruncStore())
|
|
|
|
continue;
|
|
|
|
|
2017-11-29 06:07:05 +08:00
|
|
|
if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {
|
|
|
|
if (Predicate.getMemoryVT() != nullptr) {
|
|
|
|
Optional<LLTCodeGen> MemTyOrNone =
|
|
|
|
MVTToLLT(getValueType(Predicate.getMemoryVT()));
|
2017-10-24 02:19:24 +08:00
|
|
|
|
2017-11-29 06:07:05 +08:00
|
|
|
if (!MemTyOrNone)
|
|
|
|
return failedImport("MemVT could not be converted to LLT");
|
2017-10-24 02:19:24 +08:00
|
|
|
|
[globalisel] Update GlobalISel emitter to match new representation of extending loads
Summary:
Previously, a extending load was represented at (G_*EXT (G_LOAD x)).
This had a few drawbacks:
* G_LOAD had to be legal for all sizes you could extend from, even if
registers didn't naturally hold those sizes.
* All sizes you could extend from had to be allocatable just in case the
extend went missing (e.g. by optimization).
* At minimum, G_*EXT and G_TRUNC had to be legal for these sizes. As we
improve optimization of extends and truncates, this legality requirement
would spread without considerable care w.r.t when certain combines were
permitted.
* The SelectionDAG importer required some ugly and fragile pattern
rewriting to translate patterns into this style.
This patch changes the representation to:
* (G_[SZ]EXTLOAD x)
* (G_LOAD x) any-extends when MMO.getSize() * 8 < ResultTy.getSizeInBits()
which resolves these issues by allowing targets to work entirely in their
native register sizes, and by having a more direct translation from
SelectionDAG patterns.
Each extending load can be lowered by the legalizer into separate extends
and loads, however a target that supports s1 will need the any-extending
load to extend to at least s8 since LLVM does not represent memory accesses
smaller than 8 bit. The legalizer can widenScalar G_LOAD into an
any-extending load but sign/zero-extending loads need help from something
else like a combiner pass. A follow-up patch that adds combiner helpers for
for this will follow.
The new representation requires that the MMO correctly reflect the memory
access so this has been corrected in a couple tests. I've also moved the
extending loads to their own tests since they are (mostly) separate opcodes
now. Additionally, the re-write appears to have invalidated two tests from
select-with-no-legality-check.mir since the matcher table no longer contains
loads that result in s1's and they aren't legal in AArch64 anymore.
Depends on D45540
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar
Reviewed By: rtereshin
Subscribers: javed.absar, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D45541
llvm-svn: 331601
2018-05-06 04:53:24 +08:00
|
|
|
// MMO's work in bytes so we must take care of unusual types like i1
|
|
|
|
// don't round down.
|
|
|
|
unsigned MemSizeInBits =
|
|
|
|
llvm::alignTo(MemTyOrNone->get().getSizeInBits(), 8);
|
|
|
|
|
|
|
|
InsnMatcher.addPredicate<MemorySizePredicateMatcher>(
|
|
|
|
0, MemSizeInBits / 8);
|
2017-11-29 06:07:05 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Predicate.isLoad() || Predicate.isStore()) {
|
|
|
|
// No check required. A G_LOAD/G_STORE is an unindexed load.
|
|
|
|
if (Predicate.isUnindexed())
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Predicate.isAtomic()) {
|
|
|
|
if (Predicate.isAtomicOrderingMonotonic()) {
|
|
|
|
InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
|
|
|
|
"Monotonic");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (Predicate.isAtomicOrderingAcquire()) {
|
|
|
|
InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Acquire");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (Predicate.isAtomicOrderingRelease()) {
|
|
|
|
InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Release");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (Predicate.isAtomicOrderingAcquireRelease()) {
|
|
|
|
InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
|
|
|
|
"AcquireRelease");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (Predicate.isAtomicOrderingSequentiallyConsistent()) {
|
|
|
|
InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
|
|
|
|
"SequentiallyConsistent");
|
|
|
|
continue;
|
|
|
|
}
|
2017-12-01 05:05:59 +08:00
|
|
|
|
|
|
|
if (Predicate.isAtomicOrderingAcquireOrStronger()) {
|
|
|
|
InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
|
|
|
|
"Acquire", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (Predicate.isAtomicOrderingWeakerThanAcquire()) {
|
|
|
|
InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
|
|
|
|
"Acquire", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Predicate.isAtomicOrderingReleaseOrStronger()) {
|
|
|
|
InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
|
|
|
|
"Release", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (Predicate.isAtomicOrderingWeakerThanRelease()) {
|
|
|
|
InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
|
|
|
|
"Release", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);
|
|
|
|
continue;
|
|
|
|
}
|
2017-10-24 02:19:24 +08:00
|
|
|
}
|
|
|
|
|
2018-06-16 07:13:43 +08:00
|
|
|
if (Predicate.hasGISelPredicateCode()) {
|
|
|
|
InsnMatcher.addPredicate<GenericInstructionPredicateMatcher>(Predicate);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-08-24 17:11:20 +08:00
|
|
|
return failedImport("Src pattern child has predicate (" +
|
|
|
|
explainPredicates(Src) + ")");
|
|
|
|
}
|
2017-12-05 13:52:07 +08:00
|
|
|
if (SrcGIEquivOrNull && SrcGIEquivOrNull->getValueAsBit("CheckMMOIsNonAtomic"))
|
|
|
|
InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("NotAtomic");
|
2017-08-24 17:11:20 +08:00
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
if (Src->isLeaf()) {
|
|
|
|
Init *SrcInit = Src->getLeafValue();
|
2017-05-24 03:33:16 +08:00
|
|
|
if (IntInit *SrcIntInit = dyn_cast<IntInit>(SrcInit)) {
|
2017-10-14 08:31:58 +08:00
|
|
|
OperandMatcher &OM =
|
2018-06-15 04:32:58 +08:00
|
|
|
InsnMatcher.addOperand(OpIdx++, Src->getName(), TempOpIdx);
|
2017-05-24 03:33:16 +08:00
|
|
|
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");
|
[globalisel][tablegen] Add support for fpimm and import of APInt/APFloat based ImmLeaf.
Summary:
There's only a tablegen testcase for IntImmLeaf and not a CodeGen one
because the relevant rules are rejected for other reasons at the moment.
On AArch64, it's because there's an SDNodeXForm attached to the operand.
On X86, it's because the rule either emits multiple instructions or has
another predicate using PatFrag which cannot easily be supported at the
same time.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36569
llvm-svn: 315761
2017-10-14 05:28:03 +08:00
|
|
|
if (SrcGIOrNull->TheDef->getName() == "G_CONSTANT" ||
|
|
|
|
SrcGIOrNull->TheDef->getName() == "G_FCONSTANT") {
|
|
|
|
// imm/fpimm still have operands but we don't need to do anything with it
|
2017-08-08 18:44:31 +08:00
|
|
|
// here since we don't support ImmLeaf predicates yet. However, we still
|
|
|
|
// need to note the hidden operand to get GIM_CheckNumOperands correct.
|
|
|
|
InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
|
|
|
|
return InsnMatcher;
|
|
|
|
}
|
|
|
|
|
2017-05-24 03:33:16 +08:00
|
|
|
// Match the used operands (i.e. the children of the operator).
|
2018-06-15 04:32:58 +08:00
|
|
|
for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {
|
|
|
|
TreePatternNode *SrcChild = Src->getChild(i);
|
2017-07-06 16:12:20 +08:00
|
|
|
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
// SelectionDAG allows pointers to be represented with iN since it doesn't
|
|
|
|
// distinguish between pointers and integers but they are different types in GlobalISel.
|
|
|
|
// Coerce integers to pointers to address space 0 if the context indicates a pointer.
|
2017-11-18 08:16:44 +08:00
|
|
|
bool OperandIsAPointer = SrcGIOrNull->isOperandAPointer(i);
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
|
2017-09-19 20:56:36 +08:00
|
|
|
// For G_INTRINSIC/G_INTRINSIC_W_SIDE_EFFECTS, the operand immediately
|
|
|
|
// following the defs is an intrinsic ID.
|
|
|
|
if ((SrcGIOrNull->TheDef->getName() == "G_INTRINSIC" ||
|
|
|
|
SrcGIOrNull->TheDef->getName() == "G_INTRINSIC_W_SIDE_EFFECTS") &&
|
|
|
|
i == 0) {
|
2018-06-15 04:32:58 +08:00
|
|
|
if (const CodeGenIntrinsic *II = Src->getIntrinsicInfo(CGP)) {
|
2017-07-06 16:12:20 +08:00
|
|
|
OperandMatcher &OM =
|
2018-06-15 04:32:58 +08:00
|
|
|
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)");
|
|
|
|
}
|
|
|
|
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
if (auto Error =
|
|
|
|
importChildMatcher(Rule, InsnMatcher, SrcChild, OperandIsAPointer,
|
|
|
|
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-10-16 02:22:54 +08:00
|
|
|
Error GlobalISelEmitter::importComplexPatternOperandMatcher(
|
|
|
|
OperandMatcher &OM, Record *R, unsigned &TempOpIdx) const {
|
|
|
|
const auto &ComplexPattern = ComplexPatternEquivs.find(R);
|
|
|
|
if (ComplexPattern == ComplexPatternEquivs.end())
|
|
|
|
return failedImport("SelectionDAG ComplexPattern (" + R->getName() +
|
|
|
|
") not mapped to GlobalISel");
|
|
|
|
|
|
|
|
OM.addPredicate<ComplexPatternOperandMatcher>(OM, *ComplexPattern->second);
|
|
|
|
TempOpIdx++;
|
|
|
|
return Error::success();
|
|
|
|
}
|
|
|
|
|
|
|
|
Error GlobalISelEmitter::importChildMatcher(RuleMatcher &Rule,
|
|
|
|
InstructionMatcher &InsnMatcher,
|
2018-06-15 04:32:58 +08:00
|
|
|
const TreePatternNode *SrcChild,
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
bool OperandIsAPointer,
|
2017-03-30 17:36:33 +08:00
|
|
|
unsigned OpIdx,
|
2018-06-16 07:13:43 +08:00
|
|
|
unsigned &TempOpIdx) {
|
[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 =
|
2018-06-15 04:32:58 +08:00
|
|
|
InsnMatcher.addOperand(OpIdx, SrcChild->getName(), TempOpIdx);
|
2017-10-14 08:31:58 +08:00
|
|
|
if (OM.isSameAsAnotherOperand())
|
|
|
|
return Error::success();
|
2017-03-29 23:37:18 +08:00
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
ArrayRef<TypeSetByHwMode> ChildTypes = SrcChild->getExtTypes();
|
2017-03-29 23:37:18 +08:00
|
|
|
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.
|
2018-06-15 04:32:58 +08:00
|
|
|
if (!SrcChild->isLeaf()) {
|
|
|
|
if (SrcChild->getOperator()->isSubClassOf("SDNode")) {
|
|
|
|
auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild->getOperator());
|
2017-03-29 23:37:18 +08:00
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[globalisel][tablegen] Implement unindexed load, non-extending load, and MemVT checks
Summary:
This includes some context-sensitivity in the MVT to LLT conversion so that
pointer types are tested correctly.
FIXME: I'm not happy with the way this is done since everything is a
special-case. I've yet to find a reasonable way to implement it.
select-load.mir fails because <1 x s64> loads in tablegen get priority over s64
loads. This is fixed in the next patch and as such they should be committed
together, I've posted them separately to help with the review.
Depends on D37456
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Subscribers: kristof.beyls, javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D37457
llvm-svn: 315884
2017-10-16 08:56:30 +08:00
|
|
|
if (auto Error =
|
|
|
|
OM.addTypeCheckPredicate(ChildTypes.front(), OperandIsAPointer))
|
|
|
|
return failedImport(toString(std::move(Error)) + " for Src operand (" +
|
2018-06-15 04:32:58 +08:00
|
|
|
to_string(*SrcChild) + ")");
|
2017-03-29 23:37:18 +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
|
|
|
// Check for nested instructions.
|
2018-06-15 04:32:58 +08:00
|
|
|
if (!SrcChild->isLeaf()) {
|
|
|
|
if (SrcChild->getOperator()->isSubClassOf("ComplexPattern")) {
|
2017-10-16 02:22:54 +08:00
|
|
|
// When a ComplexPattern is used as an operator, it should do the same
|
|
|
|
// thing as when used as a leaf. However, the children of the operator
|
|
|
|
// name the sub-operands that make up the complex operand and we must
|
|
|
|
// prepare to reference them in the renderer too.
|
|
|
|
unsigned RendererID = TempOpIdx;
|
|
|
|
if (auto Error = importComplexPatternOperandMatcher(
|
2018-06-15 04:32:58 +08:00
|
|
|
OM, SrcChild->getOperator(), TempOpIdx))
|
2017-10-16 02:22:54 +08:00
|
|
|
return Error;
|
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
for (unsigned i = 0, e = SrcChild->getNumChildren(); i != e; ++i) {
|
|
|
|
auto *SubOperand = SrcChild->getChild(i);
|
2019-02-09 08:29:13 +08:00
|
|
|
if (!SubOperand->getName().empty()) {
|
|
|
|
if (auto Error = Rule.defineComplexSubOperand(SubOperand->getName(),
|
|
|
|
SrcChild->getOperator(),
|
|
|
|
RendererID, i))
|
|
|
|
return Error;
|
|
|
|
}
|
2017-10-16 02:22:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return Error::success();
|
|
|
|
}
|
|
|
|
|
2017-10-14 08:31:58 +08:00
|
|
|
auto MaybeInsnOperand = OM.addPredicate<InstructionOperandMatcher>(
|
2018-06-15 04:32:58 +08:00
|
|
|
InsnMatcher.getRuleMatcher(), SrcChild->getName());
|
2017-10-14 08:31:58 +08:00
|
|
|
if (!MaybeInsnOperand.hasValue()) {
|
|
|
|
// This isn't strictly true. If the user were to provide exactly the same
|
|
|
|
// matchers as the original operand then we could allow it. However, it's
|
|
|
|
// simpler to not permit the redundant specification.
|
|
|
|
return failedImport("Nested instruction cannot be the same as another 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
|
|
|
// Map the node to a gMIR instruction.
|
2017-10-14 08:31:58 +08:00
|
|
|
InstructionOperandMatcher &InsnOperand = **MaybeInsnOperand;
|
2017-07-11 18:40:18 +08:00
|
|
|
auto InsnMatcherOrError = createAndImportSelDAGMatcher(
|
2017-10-16 02:22:54 +08:00
|
|
|
Rule, 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();
|
|
|
|
}
|
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
if (SrcChild->hasAnyPredicate())
|
2017-11-03 18:30:19 +08:00
|
|
|
return failedImport("Src pattern child has unsupported predicate");
|
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
// Check for constant immediates.
|
2018-06-15 04:32:58 +08:00
|
|
|
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.
|
2018-06-15 04:32:58 +08:00
|
|
|
if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
|
2017-03-29 23:37:18 +08:00
|
|
|
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-10-10 02:14:53 +08:00
|
|
|
// Check for ValueType.
|
|
|
|
if (ChildRec->isSubClassOf("ValueType")) {
|
|
|
|
// We already added a type check as standard practice so this doesn't need
|
|
|
|
// to do anything.
|
|
|
|
return Error::success();
|
|
|
|
}
|
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
// Check for ComplexPattern's.
|
2017-10-16 02:22:54 +08:00
|
|
|
if (ChildRec->isSubClassOf("ComplexPattern"))
|
|
|
|
return importComplexPatternOperandMatcher(OM, ChildRec, TempOpIdx);
|
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-11-01 07:03:18 +08:00
|
|
|
Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
|
|
|
|
action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
|
2018-06-15 04:32:58 +08:00
|
|
|
TreePatternNode *DstChild) {
|
2017-08-24 17:11:20 +08:00
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
const auto &SubOperand = Rule.getComplexSubOperand(DstChild->getName());
|
2017-10-16 02:22:54 +08:00
|
|
|
if (SubOperand.hasValue()) {
|
|
|
|
DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
|
2018-06-15 04:32:58 +08:00
|
|
|
*std::get<0>(*SubOperand), DstChild->getName(),
|
2017-10-16 02:22:54 +08:00
|
|
|
std::get<1>(*SubOperand), std::get<2>(*SubOperand));
|
2017-11-01 07:03:18 +08:00
|
|
|
return InsertPt;
|
2017-10-16 02:22:54 +08:00
|
|
|
}
|
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
if (!DstChild->isLeaf()) {
|
2018-01-17 02:44:05 +08:00
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
if (DstChild->getOperator()->isSubClassOf("SDNodeXForm")) {
|
|
|
|
auto Child = DstChild->getChild(0);
|
|
|
|
auto I = SDNodeXFormEquivs.find(DstChild->getOperator());
|
2018-01-17 02:44:05 +08:00
|
|
|
if (I != SDNodeXFormEquivs.end()) {
|
2018-06-15 04:32:58 +08:00
|
|
|
DstMIBuilder.addRenderer<CustomRenderer>(*I->second, Child->getName());
|
2018-01-17 02:44:05 +08:00
|
|
|
return InsertPt;
|
|
|
|
}
|
2018-06-15 04:32:58 +08:00
|
|
|
return failedImport("SDNodeXForm " + Child->getName() +
|
2018-01-17 02:44:05 +08:00
|
|
|
" has no custom renderer");
|
|
|
|
}
|
|
|
|
|
2017-08-08 18:44:31 +08:00
|
|
|
// We accept 'bb' here. It's an operator because BasicBlockSDNode isn't
|
|
|
|
// inline, but in MI it's just another operand.
|
2018-06-15 04:32:58 +08:00
|
|
|
if (DstChild->getOperator()->isSubClassOf("SDNode")) {
|
|
|
|
auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator());
|
2017-03-29 23:37:18 +08:00
|
|
|
if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
|
2018-06-15 04:32:58 +08:00
|
|
|
DstMIBuilder.addRenderer<CopyRenderer>(DstChild->getName());
|
2017-11-01 07:03:18 +08:00
|
|
|
return InsertPt;
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
|
|
|
}
|
2017-08-08 18:44:31 +08:00
|
|
|
|
|
|
|
// Similarly, imm is an operator in TreePatternNode's view but must be
|
|
|
|
// rendered as operands.
|
|
|
|
// FIXME: The target should be able to choose sign-extended when appropriate
|
|
|
|
// (e.g. on Mips).
|
2018-06-15 04:32:58 +08:00
|
|
|
if (DstChild->getOperator()->getName() == "imm") {
|
|
|
|
DstMIBuilder.addRenderer<CopyConstantAsImmRenderer>(DstChild->getName());
|
2017-11-01 07:03:18 +08:00
|
|
|
return InsertPt;
|
2018-06-15 04:32:58 +08:00
|
|
|
} else if (DstChild->getOperator()->getName() == "fpimm") {
|
[globalisel][tablegen] Add support for fpimm and import of APInt/APFloat based ImmLeaf.
Summary:
There's only a tablegen testcase for IntImmLeaf and not a CodeGen one
because the relevant rules are rejected for other reasons at the moment.
On AArch64, it's because there's an SDNodeXForm attached to the operand.
On X86, it's because the rule either emits multiple instructions or has
another predicate using PatFrag which cannot easily be supported at the
same time.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36569
llvm-svn: 315761
2017-10-14 05:28:03 +08:00
|
|
|
DstMIBuilder.addRenderer<CopyFConstantAsFPImmRenderer>(
|
2018-06-15 04:32:58 +08:00
|
|
|
DstChild->getName());
|
2017-11-01 07:03:18 +08:00
|
|
|
return InsertPt;
|
2017-08-08 18:44:31 +08:00
|
|
|
}
|
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
if (DstChild->getOperator()->isSubClassOf("Instruction")) {
|
|
|
|
ArrayRef<TypeSetByHwMode> ChildTypes = DstChild->getExtTypes();
|
2017-11-02 03:57:57 +08:00
|
|
|
if (ChildTypes.size() != 1)
|
|
|
|
return failedImport("Dst pattern child has multiple results");
|
|
|
|
|
|
|
|
Optional<LLTCodeGen> OpTyOrNone = None;
|
|
|
|
if (ChildTypes.front().isMachineValueType())
|
|
|
|
OpTyOrNone =
|
|
|
|
MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
|
|
|
|
if (!OpTyOrNone)
|
|
|
|
return failedImport("Dst operand has an unsupported type");
|
|
|
|
|
|
|
|
unsigned TempRegID = Rule.allocateTempRegID();
|
|
|
|
InsertPt = Rule.insertAction<MakeTempRegisterAction>(
|
|
|
|
InsertPt, OpTyOrNone.getValue(), TempRegID);
|
|
|
|
DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
|
|
|
|
|
|
|
|
auto InsertPtOrError = createAndImportSubInstructionRenderer(
|
|
|
|
++InsertPt, Rule, DstChild, TempRegID);
|
|
|
|
if (auto Error = InsertPtOrError.takeError())
|
|
|
|
return std::move(Error);
|
|
|
|
return InsertPtOrError.get();
|
|
|
|
}
|
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
return failedImport("Dst pattern child isn't a leaf node or an MBB" + llvm::to_string(*DstChild));
|
2017-03-29 23:37:18 +08:00
|
|
|
}
|
2016-12-22 07:26:20 +08:00
|
|
|
|
2017-12-01 02:48:35 +08:00
|
|
|
// It could be a specific immediate in which case we should just check for
|
|
|
|
// that immediate.
|
|
|
|
if (const IntInit *ChildIntInit =
|
2018-06-15 04:32:58 +08:00
|
|
|
dyn_cast<IntInit>(DstChild->getLeafValue())) {
|
2017-12-01 02:48:35 +08:00
|
|
|
DstMIBuilder.addRenderer<ImmRenderer>(ChildIntInit->getValue());
|
|
|
|
return InsertPt;
|
|
|
|
}
|
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
// Otherwise, we're looking for a bog-standard RegisterClass operand.
|
2018-06-15 04:32:58 +08:00
|
|
|
if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild->getLeafValue())) {
|
2017-03-29 23:37:18 +08:00
|
|
|
auto *ChildRec = ChildDefInit->getDef();
|
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
ArrayRef<TypeSetByHwMode> 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
|
|
|
|
2017-09-15 00:56:21 +08:00
|
|
|
Optional<LLTCodeGen> OpTyOrNone = None;
|
|
|
|
if (ChildTypes.front().isMachineValueType())
|
|
|
|
OpTyOrNone = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
|
2016-12-22 07:26:20 +08:00
|
|
|
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-11-01 08:29:47 +08:00
|
|
|
DstMIBuilder.addRenderer<AddRegisterRenderer>(ChildRec);
|
2017-11-01 07:03:18 +08:00
|
|
|
return InsertPt;
|
[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") ||
|
2017-10-10 02:14:53 +08:00
|
|
|
ChildRec->isSubClassOf("RegisterOperand") ||
|
|
|
|
ChildRec->isSubClassOf("ValueType")) {
|
2017-10-24 02:19:24 +08:00
|
|
|
if (ChildRec->isSubClassOf("RegisterOperand") &&
|
|
|
|
!ChildRec->isValueUnset("GIZeroRegister")) {
|
|
|
|
DstMIBuilder.addRenderer<CopyOrAddZeroRegRenderer>(
|
2018-06-15 04:32:58 +08:00
|
|
|
DstChild->getName(), ChildRec->getValueAsDef("GIZeroRegister"));
|
2017-11-01 07:03:18 +08:00
|
|
|
return InsertPt;
|
2017-10-24 02:19:24 +08:00
|
|
|
}
|
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
DstMIBuilder.addRenderer<CopyRenderer>(DstChild->getName());
|
2017-11-01 07:03:18 +08:00
|
|
|
return InsertPt;
|
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");
|
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
const OperandMatcher &OM = Rule.getOperandMatcher(DstChild->getName());
|
2017-03-29 23:37:18 +08:00
|
|
|
DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
|
2018-06-15 04:32:58 +08:00
|
|
|
*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-11-01 07:03:18 +08:00
|
|
|
return InsertPt;
|
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
|
|
|
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(
|
2018-06-15 04:32:58 +08:00
|
|
|
RuleMatcher &M, const TreePatternNode *Dst) {
|
2017-11-01 07:03:18 +08:00
|
|
|
auto InsertPtOrError = createInstructionRenderer(M.actions_end(), M, Dst);
|
|
|
|
if (auto Error = InsertPtOrError.takeError())
|
2017-11-01 03:09:29 +08:00
|
|
|
return std::move(Error);
|
|
|
|
|
2017-11-01 07:03:18 +08:00
|
|
|
action_iterator InsertPt = InsertPtOrError.get();
|
|
|
|
BuildMIAction &DstMIBuilder = *static_cast<BuildMIAction *>(InsertPt->get());
|
2017-11-01 03:09:29 +08:00
|
|
|
|
|
|
|
importExplicitDefRenderers(DstMIBuilder);
|
|
|
|
|
2017-11-01 07:03:18 +08:00
|
|
|
if (auto Error = importExplicitUseRenderers(InsertPt, M, DstMIBuilder, Dst)
|
|
|
|
.takeError())
|
2017-11-01 03:09:29 +08:00
|
|
|
return std::move(Error);
|
|
|
|
|
|
|
|
return DstMIBuilder;
|
|
|
|
}
|
|
|
|
|
2017-11-02 03:57:57 +08:00
|
|
|
Expected<action_iterator>
|
|
|
|
GlobalISelEmitter::createAndImportSubInstructionRenderer(
|
2018-06-15 04:32:58 +08:00
|
|
|
const action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst,
|
2017-11-02 03:57:57 +08:00
|
|
|
unsigned TempRegID) {
|
|
|
|
auto InsertPtOrError = createInstructionRenderer(InsertPt, M, Dst);
|
|
|
|
|
|
|
|
// TODO: Assert there's exactly one result.
|
|
|
|
|
|
|
|
if (auto Error = InsertPtOrError.takeError())
|
|
|
|
return std::move(Error);
|
|
|
|
|
|
|
|
BuildMIAction &DstMIBuilder =
|
|
|
|
*static_cast<BuildMIAction *>(InsertPtOrError.get()->get());
|
|
|
|
|
|
|
|
// Assign the result to TempReg.
|
|
|
|
DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, true);
|
|
|
|
|
[ARM][GISel] PR35965 Constrain RegClasses of nested instructions built from Dst Pattern
Summary:
Apparently, we missed on constraining register classes of VReg-operands of all the instructions
built from a destination pattern but the root (top-level) one. The issue exposed itself
while selecting G_FPTOSI for armv7: the corresponding pattern generates VTOSIZS wrapped
into COPY_TO_REGCLASS, so top-level COPY_TO_REGCLASS gets properly constrained,
while nested VTOSIZS (or rather its destination virtual register to be exact) does not.
Fixing this by issuing GIR_ConstrainSelectedInstOperands for every nested GIR_BuildMI.
https://bugs.llvm.org/show_bug.cgi?id=35965
rdar://problem/36886530
Patch by Roman Tereshin
Reviewers: dsanders, qcolombet, rovka, bogner, aditya_nandakumar, volkan
Reviewed By: dsanders, qcolombet, rovka
Subscribers: aemerson, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D42565
llvm-svn: 323692
2018-01-30 05:09:12 +08:00
|
|
|
InsertPtOrError =
|
|
|
|
importExplicitUseRenderers(InsertPtOrError.get(), M, DstMIBuilder, Dst);
|
2017-11-02 03:57:57 +08:00
|
|
|
if (auto Error = InsertPtOrError.takeError())
|
|
|
|
return std::move(Error);
|
|
|
|
|
[ARM][GISel] PR35965 Constrain RegClasses of nested instructions built from Dst Pattern
Summary:
Apparently, we missed on constraining register classes of VReg-operands of all the instructions
built from a destination pattern but the root (top-level) one. The issue exposed itself
while selecting G_FPTOSI for armv7: the corresponding pattern generates VTOSIZS wrapped
into COPY_TO_REGCLASS, so top-level COPY_TO_REGCLASS gets properly constrained,
while nested VTOSIZS (or rather its destination virtual register to be exact) does not.
Fixing this by issuing GIR_ConstrainSelectedInstOperands for every nested GIR_BuildMI.
https://bugs.llvm.org/show_bug.cgi?id=35965
rdar://problem/36886530
Patch by Roman Tereshin
Reviewers: dsanders, qcolombet, rovka, bogner, aditya_nandakumar, volkan
Reviewed By: dsanders, qcolombet, rovka
Subscribers: aemerson, javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D42565
llvm-svn: 323692
2018-01-30 05:09:12 +08:00
|
|
|
M.insertAction<ConstrainOperandsToDefinitionAction>(InsertPt,
|
|
|
|
DstMIBuilder.getInsnID());
|
2017-11-02 03:57:57 +08:00
|
|
|
return InsertPtOrError.get();
|
|
|
|
}
|
|
|
|
|
2017-11-01 07:03:18 +08:00
|
|
|
Expected<action_iterator> GlobalISelEmitter::createInstructionRenderer(
|
2018-06-15 04:32:58 +08:00
|
|
|
action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst) {
|
|
|
|
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);
|
|
|
|
|
|
|
|
// 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-11-01 03:09:29 +08:00
|
|
|
if (DstI->TheDef->getName() == "COPY_TO_REGCLASS")
|
2017-06-20 20:36:34 +08:00
|
|
|
DstI = &Target.getInstruction(RK.getDef("COPY"));
|
2017-11-01 03:09:29 +08:00
|
|
|
else if (DstI->TheDef->getName() == "EXTRACT_SUBREG")
|
2017-06-27 18:11:39 +08:00
|
|
|
DstI = &Target.getInstruction(RK.getDef("COPY"));
|
2017-11-02 03:57:57 +08:00
|
|
|
else if (DstI->TheDef->getName() == "REG_SEQUENCE")
|
|
|
|
return failedImport("Unable to emit REG_SEQUENCE");
|
2017-03-29 23:37:18 +08:00
|
|
|
|
2017-11-01 08:29:47 +08:00
|
|
|
return M.insertAction<BuildMIAction>(InsertPt, M.allocateOutputInsnID(),
|
|
|
|
DstI);
|
2017-11-01 03:09:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GlobalISelEmitter::importExplicitDefRenderers(
|
|
|
|
BuildMIAction &DstMIBuilder) {
|
|
|
|
const CodeGenInstruction *DstI = DstMIBuilder.getCGI();
|
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-11-01 08:29:47 +08:00
|
|
|
DstMIBuilder.addRenderer<CopyRenderer>(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-11-01 03:09:29 +08:00
|
|
|
}
|
|
|
|
|
2017-11-01 07:03:18 +08:00
|
|
|
Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
|
|
|
|
action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
|
2018-06-15 04:32:58 +08:00
|
|
|
const llvm::TreePatternNode *Dst) {
|
2017-11-01 03:09:29 +08:00
|
|
|
const CodeGenInstruction *DstI = DstMIBuilder.getCGI();
|
2018-06-15 04:32:58 +08:00
|
|
|
CodeGenInstruction *OrigDstI = &Target.getInstruction(Dst->getOperator());
|
[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.
|
2017-11-01 03:09:29 +08:00
|
|
|
if (OrigDstI->TheDef->getName() == "EXTRACT_SUBREG") {
|
2018-06-15 04:32:58 +08:00
|
|
|
if (!Dst->getChild(0)->isLeaf())
|
2017-06-27 18:11:39 +08:00
|
|
|
return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
|
|
|
|
|
2017-06-28 21:50:04 +08:00
|
|
|
if (DefInit *SubRegInit =
|
2018-06-15 04:32:58 +08:00
|
|
|
dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue())) {
|
|
|
|
Record *RCDef = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
|
2017-11-02 03:57:57 +08:00
|
|
|
if (!RCDef)
|
|
|
|
return failedImport("EXTRACT_SUBREG child #0 could not "
|
|
|
|
"be coerced to a register class");
|
|
|
|
|
|
|
|
CodeGenRegisterClass *RC = CGRegs.getRegClass(RCDef);
|
2017-06-27 18:11:39 +08:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
DstMIBuilder.addRenderer<CopySubRegRenderer>(Dst->getChild(0)->getName(),
|
2017-11-01 08:29:47 +08:00
|
|
|
SubIdx);
|
2017-11-01 07:03:18 +08:00
|
|
|
return InsertPt;
|
2017-06-27 18:11:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
|
|
|
|
}
|
|
|
|
|
2017-03-29 23:37:18 +08:00
|
|
|
// Render the explicit uses.
|
2017-11-01 03:09:29 +08:00
|
|
|
unsigned DstINumUses = OrigDstI->Operands.size() - OrigDstI->Operands.NumDefs;
|
2018-06-15 04:32:58 +08:00
|
|
|
unsigned ExpectedDstINumUses = Dst->getNumChildren();
|
2017-11-01 03:09:29 +08:00
|
|
|
if (OrigDstI->TheDef->getName() == "COPY_TO_REGCLASS") {
|
|
|
|
DstINumUses--; // Ignore the class constraint.
|
|
|
|
ExpectedDstINumUses--;
|
|
|
|
}
|
|
|
|
|
[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");
|
2019-05-30 15:30:37 +08:00
|
|
|
if (auto Error = importDefaultOperandRenderers(
|
|
|
|
InsertPt, M, DstMIBuilder, DefaultOps))
|
2017-05-17 16:57:28 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2017-11-01 07:03:18 +08:00
|
|
|
auto InsertPtOrError = importExplicitUseRenderer(InsertPt, M, DstMIBuilder,
|
2018-06-15 04:32:58 +08:00
|
|
|
Dst->getChild(Child));
|
2017-11-01 07:03:18 +08:00
|
|
|
if (auto Error = InsertPtOrError.takeError())
|
2017-03-29 23:37:18 +08:00
|
|
|
return std::move(Error);
|
2017-11-01 07:03:18 +08:00
|
|
|
InsertPt = InsertPtOrError.get();
|
[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-11-01 07:03:18 +08:00
|
|
|
return InsertPt;
|
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-05-17 16:57:28 +08:00
|
|
|
Error GlobalISelEmitter::importDefaultOperandRenderers(
|
2019-05-30 15:30:37 +08:00
|
|
|
action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
|
|
|
|
DagInit *DefaultOps) const {
|
2017-05-30 05:49:34 +08:00
|
|
|
for (const auto *DefaultOp : DefaultOps->getArgs()) {
|
2019-05-30 15:30:37 +08:00
|
|
|
Optional<LLTCodeGen> OpTyOrNone = None;
|
|
|
|
|
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())) {
|
2019-05-31 16:39:34 +08:00
|
|
|
if (DefaultDagOperator->getDef()->isSubClassOf("ValueType")) {
|
2019-05-30 15:30:37 +08:00
|
|
|
OpTyOrNone = MVTToLLT(getValueType(
|
|
|
|
DefaultDagOperator->getDef()));
|
2017-05-17 16:57:28 +08:00
|
|
|
DefaultOp = DefaultDagOp->getArg(0);
|
2019-05-31 16:39:34 +08:00
|
|
|
}
|
2017-05-17 16:57:28 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) {
|
2019-05-30 15:30:37 +08:00
|
|
|
auto Def = DefaultDefOp->getDef();
|
|
|
|
if (Def->getName() == "undef_tied_input") {
|
|
|
|
unsigned TempRegID = M.allocateTempRegID();
|
|
|
|
M.insertAction<MakeTempRegisterAction>(
|
|
|
|
InsertPt, OpTyOrNone.getValue(), TempRegID);
|
|
|
|
InsertPt = M.insertAction<BuildMIAction>(
|
|
|
|
InsertPt, M.allocateOutputInsnID(),
|
|
|
|
&Target.getInstruction(RK.getDef("IMPLICIT_DEF")));
|
|
|
|
BuildMIAction &IDMIBuilder = *static_cast<BuildMIAction *>(
|
|
|
|
InsertPt->get());
|
|
|
|
IDMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
|
|
|
|
DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
|
|
|
|
} else {
|
|
|
|
DstMIBuilder.addRenderer<AddRegisterRenderer>(Def);
|
|
|
|
}
|
2017-05-17 16:57:28 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) {
|
2017-11-01 08:29:47 +08:00
|
|
|
DstMIBuilder.addRenderer<ImmRenderer>(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.
|
2018-02-17 06:37:15 +08:00
|
|
|
int Score = P.getPatternComplexity(CGP);
|
2017-10-14 08:31:58 +08:00
|
|
|
RuleMatcher M(P.getSrcRecord()->getLoc());
|
2018-02-17 06:37:15 +08:00
|
|
|
RuleMatcherScores[M.getRuleID()] = Score;
|
2017-11-01 02:07:03 +08:00
|
|
|
M.addAction<DebugCommentAction>(llvm::to_string(*P.getSrcPattern()) +
|
|
|
|
" => " +
|
|
|
|
llvm::to_string(*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-09-15 00:56:21 +08:00
|
|
|
if (auto Error = importRulePredicates(M, P.getPredicates()))
|
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.
|
2018-06-15 04:32:58 +08:00
|
|
|
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-12-16 07:07:42 +08:00
|
|
|
// The different predicates and matchers created during
|
|
|
|
// addInstructionMatcher use the RuleMatcher M to set up their
|
|
|
|
// instruction ID (InsnVarID) that are going to be used when
|
|
|
|
// M is going to be emitted.
|
|
|
|
// However, the code doing the emission still relies on the IDs
|
|
|
|
// returned during that process by the RuleMatcher when issuing
|
|
|
|
// the recordInsn opcodes.
|
|
|
|
// Because of that:
|
|
|
|
// 1. The order in which we created the predicates
|
|
|
|
// and such must be the same as the order in which we emit them,
|
|
|
|
// and
|
|
|
|
// 2. We need to reset the generation of the IDs in M somewhere between
|
|
|
|
// addInstructionMatcher and emit
|
|
|
|
//
|
|
|
|
// FIXME: Long term, we don't want to have to rely on this implicit
|
|
|
|
// naming being the same. One possible solution would be to have
|
|
|
|
// explicit operator for operation capture and reference those.
|
|
|
|
// The plus side is that it would expose opportunities to share
|
|
|
|
// the capture accross rules. The downside is that it would
|
|
|
|
// introduce a dependency between predicates (captures must happen
|
|
|
|
// before their first use.)
|
2018-06-15 04:32:58 +08:00
|
|
|
InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher(Src->getName());
|
Re-commit: [globalisel][tablegen] Support zero-instruction emission.
Summary:
Support the case where an operand of a pattern is also the whole of the
result pattern. In this case the original result and all its uses must be
replaced by the operand. However, register class restrictions can require
a COPY. This patch handles both cases by always emitting the copy and
leaving it for the register allocator to optimize.
The previous commit failed on Windows machines due to a flaw in the sort
predicate which allowed both A < B < C and B == C to be satisfied
simultaneously. The cause of this was some sloppiness in the priority order of
G_CONSTANT instructions compared to other instructions. These had equal priority
because it makes no difference, however there were operands had higher priority
than G_CONSTANT but lower priority than any other instruction. As a result, a
priority order between G_CONSTANT and other instructions must be enforced to
ensure the predicate defines a strict weak order.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Subscribers: javed.absar, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D36084
llvm-svn: 311076
2017-08-17 17:26:14 +08:00
|
|
|
unsigned TempOpIdx = 0;
|
|
|
|
auto InsnMatcherOrError =
|
2017-10-16 02:22:54 +08:00
|
|
|
createAndImportSelDAGMatcher(M, InsnMatcherTemp, Src, TempOpIdx);
|
Re-commit: [globalisel][tablegen] Support zero-instruction emission.
Summary:
Support the case where an operand of a pattern is also the whole of the
result pattern. In this case the original result and all its uses must be
replaced by the operand. However, register class restrictions can require
a COPY. This patch handles both cases by always emitting the copy and
leaving it for the register allocator to optimize.
The previous commit failed on Windows machines due to a flaw in the sort
predicate which allowed both A < B < C and B == C to be satisfied
simultaneously. The cause of this was some sloppiness in the priority order of
G_CONSTANT instructions compared to other instructions. These had equal priority
because it makes no difference, however there were operands had higher priority
than G_CONSTANT but lower priority than any other instruction. As a result, a
priority order between G_CONSTANT and other instructions must be enforced to
ensure the predicate defines a strict weak order.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Subscribers: javed.absar, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D36084
llvm-svn: 311076
2017-08-17 17:26:14 +08:00
|
|
|
if (auto Error = InsnMatcherOrError.takeError())
|
|
|
|
return std::move(Error);
|
|
|
|
InstructionMatcher &InsnMatcher = InsnMatcherOrError.get();
|
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
if (Dst->isLeaf()) {
|
|
|
|
Record *RCDef = getInitValueAsRegClass(Dst->getLeafValue());
|
Re-commit: [globalisel][tablegen] Support zero-instruction emission.
Summary:
Support the case where an operand of a pattern is also the whole of the
result pattern. In this case the original result and all its uses must be
replaced by the operand. However, register class restrictions can require
a COPY. This patch handles both cases by always emitting the copy and
leaving it for the register allocator to optimize.
The previous commit failed on Windows machines due to a flaw in the sort
predicate which allowed both A < B < C and B == C to be satisfied
simultaneously. The cause of this was some sloppiness in the priority order of
G_CONSTANT instructions compared to other instructions. These had equal priority
because it makes no difference, however there were operands had higher priority
than G_CONSTANT but lower priority than any other instruction. As a result, a
priority order between G_CONSTANT and other instructions must be enforced to
ensure the predicate defines a strict weak order.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Subscribers: javed.absar, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D36084
llvm-svn: 311076
2017-08-17 17:26:14 +08:00
|
|
|
|
|
|
|
const CodeGenRegisterClass &RC = Target.getRegisterClass(RCDef);
|
|
|
|
if (RCDef) {
|
|
|
|
// We need to replace the def and all its uses with the specified
|
|
|
|
// operand. However, we must also insert COPY's wherever needed.
|
|
|
|
// For now, emit a copy and let the register allocator clean up.
|
|
|
|
auto &DstI = Target.getInstruction(RK.getDef("COPY"));
|
|
|
|
const auto &DstIOperand = DstI.Operands[0];
|
|
|
|
|
|
|
|
OperandMatcher &OM0 = InsnMatcher.getOperand(0);
|
|
|
|
OM0.setSymbolicName(DstIOperand.Name);
|
2017-10-14 08:31:58 +08:00
|
|
|
M.defineOperand(OM0.getSymbolicName(), OM0);
|
Re-commit: [globalisel][tablegen] Support zero-instruction emission.
Summary:
Support the case where an operand of a pattern is also the whole of the
result pattern. In this case the original result and all its uses must be
replaced by the operand. However, register class restrictions can require
a COPY. This patch handles both cases by always emitting the copy and
leaving it for the register allocator to optimize.
The previous commit failed on Windows machines due to a flaw in the sort
predicate which allowed both A < B < C and B == C to be satisfied
simultaneously. The cause of this was some sloppiness in the priority order of
G_CONSTANT instructions compared to other instructions. These had equal priority
because it makes no difference, however there were operands had higher priority
than G_CONSTANT but lower priority than any other instruction. As a result, a
priority order between G_CONSTANT and other instructions must be enforced to
ensure the predicate defines a strict weak order.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Subscribers: javed.absar, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D36084
llvm-svn: 311076
2017-08-17 17:26:14 +08:00
|
|
|
OM0.addPredicate<RegisterBankOperandMatcher>(RC);
|
|
|
|
|
2017-11-01 08:29:47 +08:00
|
|
|
auto &DstMIBuilder =
|
|
|
|
M.addAction<BuildMIAction>(M.allocateOutputInsnID(), &DstI);
|
|
|
|
DstMIBuilder.addRenderer<CopyRenderer>(DstIOperand.Name);
|
2018-06-15 04:32:58 +08:00
|
|
|
DstMIBuilder.addRenderer<CopyRenderer>(Dst->getName());
|
Re-commit: [globalisel][tablegen] Support zero-instruction emission.
Summary:
Support the case where an operand of a pattern is also the whole of the
result pattern. In this case the original result and all its uses must be
replaced by the operand. However, register class restrictions can require
a COPY. This patch handles both cases by always emitting the copy and
leaving it for the register allocator to optimize.
The previous commit failed on Windows machines due to a flaw in the sort
predicate which allowed both A < B < C and B == C to be satisfied
simultaneously. The cause of this was some sloppiness in the priority order of
G_CONSTANT instructions compared to other instructions. These had equal priority
because it makes no difference, however there were operands had higher priority
than G_CONSTANT but lower priority than any other instruction. As a result, a
priority order between G_CONSTANT and other instructions must be enforced to
ensure the predicate defines a strict weak order.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Subscribers: javed.absar, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D36084
llvm-svn: 311076
2017-08-17 17:26:14 +08:00
|
|
|
M.addAction<ConstrainOperandToRegClassAction>(0, 0, RC);
|
|
|
|
|
|
|
|
// We're done with this pattern! It's eligible for GISel emission; return
|
|
|
|
// it.
|
|
|
|
++NumPatternImported;
|
|
|
|
return std::move(M);
|
|
|
|
}
|
|
|
|
|
2017-05-24 03:33:16 +08:00
|
|
|
return failedImport("Dst pattern root isn't a known leaf");
|
Re-commit: [globalisel][tablegen] Support zero-instruction emission.
Summary:
Support the case where an operand of a pattern is also the whole of the
result pattern. In this case the original result and all its uses must be
replaced by the operand. However, register class restrictions can require
a COPY. This patch handles both cases by always emitting the copy and
leaving it for the register allocator to optimize.
The previous commit failed on Windows machines due to a flaw in the sort
predicate which allowed both A < B < C and B == C to be satisfied
simultaneously. The cause of this was some sloppiness in the priority order of
G_CONSTANT instructions compared to other instructions. These had equal priority
because it makes no difference, however there were operands had higher priority
than G_CONSTANT but lower priority than any other instruction. As a result, a
priority order between G_CONSTANT and other instructions must be enforced to
ensure the predicate defines a strict weak order.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Subscribers: javed.absar, kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D36084
llvm-svn: 311076
2017-08-17 17:26:14 +08:00
|
|
|
}
|
2017-05-24 03:33:16 +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
|
|
|
// Start with the defined operands (i.e., the results of the root operator).
|
2018-06-15 04:32:58 +08:00
|
|
|
Record *DstOp = Dst->getOperator();
|
2017-03-29 23:37:18 +08:00
|
|
|
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);
|
2018-06-15 04:32:58 +08:00
|
|
|
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 (" +
|
2018-06-15 04:32:58 +08:00
|
|
|
to_string(Src->getExtTypes().size()) + " def(s) vs " +
|
2017-04-13 17:45:37 +08:00
|
|
|
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
|
|
|
// The root of the match also has constraints on the register bank so that it
|
|
|
|
// matches the result instruction.
|
|
|
|
unsigned OpIdx = 0;
|
2018-06-15 04:32:58 +08:00
|
|
|
for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
|
2017-09-15 00:56:21 +08:00
|
|
|
(void)VTy;
|
2017-03-29 23:37:18 +08:00
|
|
|
|
|
|
|
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") {
|
2018-06-15 04:32:58 +08:00
|
|
|
DstIOpRec = getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
|
2017-06-20 20:36:34 +08:00
|
|
|
|
|
|
|
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") {
|
2018-06-15 04:32:58 +08:00
|
|
|
if (!Dst->getChild(0)->isLeaf())
|
2017-06-27 18:11:39 +08:00
|
|
|
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.
|
2018-06-15 04:32:58 +08:00
|
|
|
DstIOpRec = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
|
2017-06-27 18:11:39 +08:00
|
|
|
|
|
|
|
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"))
|
2018-06-15 04:32:58 +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);
|
2017-10-14 08:31:58 +08:00
|
|
|
M.defineOperand(OM.getSymbolicName(), OM);
|
2017-03-29 23:37:18 +08:00
|
|
|
OM.addPredicate<RegisterBankOperandMatcher>(
|
|
|
|
Target.getRegisterClass(DstIOpRec));
|
|
|
|
++OpIdx;
|
2016-12-22 07:26:20 +08:00
|
|
|
}
|
|
|
|
|
2017-11-01 02:50:24 +08:00
|
|
|
auto DstMIBuilderOrError = createAndImportInstructionRenderer(M, Dst);
|
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-11-01 02:50:24 +08:00
|
|
|
DstMIBuilder.chooseInsnToMutate(M);
|
|
|
|
|
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 =
|
2018-06-15 04:32:58 +08:00
|
|
|
getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
|
2017-06-20 20:36:34 +08:00
|
|
|
|
|
|
|
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.
|
2018-06-15 04:32:58 +08:00
|
|
|
if (!Dst->getChild(0)->isLeaf())
|
2017-06-27 18:11:39 +08:00
|
|
|
return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
|
|
|
|
|
2018-06-15 04:32:58 +08:00
|
|
|
DefInit *SubRegInit = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
|
2017-06-28 23:16:03 +08:00
|
|
|
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 =
|
2018-06-15 04:32:58 +08:00
|
|
|
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.
|
2018-06-15 04:32:58 +08:00
|
|
|
assert(Src->getExtTypes().size() == 1 &&
|
2017-06-28 23:16:03 +08:00
|
|
|
"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
|
|
|
}
|
|
|
|
|
[aarch64] Support APInt and APFloat in ImmLeaf subclasses and make AArch64 use them.
Summary:
The purpose of this patch is to expose more information about ImmLeaf-like
PatLeaf's so that GlobalISel can learn to import them. Previously, ImmLeaf
could only be used to test int64_t's produced by sign-extending an APInt.
Other tests on immediates had to use the generic PatLeaf and extract the
constant using C++.
With this patch, tablegen will know how to generate predicates for APInt,
and APFloat. This will allow it to 'do the right thing' for both SelectionDAG
and GlobalISel which require different methods of extracting the immediate
from the IR.
This is NFC for SelectionDAG since the new code is equivalent to the
previous code. It's also NFC for FastISel because FastIselShouldIgnore is 1
for the ImmLeaf subclasses. Enabling FastIselShouldIgnore == 0 for these new
subclasses will require a significant re-factor of FastISel.
For GlobalISel, it's currently NFC because the relevant code to import the
affected rules is not yet present. This will be added in a later patch.
Depends on D36086
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: bjope, aemerson, rengolin, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36534
llvm-svn: 315747
2017-10-14 04:42:18 +08:00
|
|
|
// Emit imm predicate table and an enum to reference them with.
|
|
|
|
// The 'Predicate_' part of the name is redundant but eliminating it is more
|
|
|
|
// trouble than it's worth.
|
2018-06-16 07:13:43 +08:00
|
|
|
void GlobalISelEmitter::emitCxxPredicateFns(
|
|
|
|
raw_ostream &OS, StringRef CodeFieldName, StringRef TypeIdentifier,
|
|
|
|
StringRef ArgType, StringRef ArgName, StringRef AdditionalDeclarations,
|
[globalisel][tablegen] Add support for fpimm and import of APInt/APFloat based ImmLeaf.
Summary:
There's only a tablegen testcase for IntImmLeaf and not a CodeGen one
because the relevant rules are rejected for other reasons at the moment.
On AArch64, it's because there's an SDNodeXForm attached to the operand.
On X86, it's because the rule either emits multiple instructions or has
another predicate using PatFrag which cannot easily be supported at the
same time.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36569
llvm-svn: 315761
2017-10-14 05:28:03 +08:00
|
|
|
std::function<bool(const Record *R)> Filter) {
|
[aarch64] Support APInt and APFloat in ImmLeaf subclasses and make AArch64 use them.
Summary:
The purpose of this patch is to expose more information about ImmLeaf-like
PatLeaf's so that GlobalISel can learn to import them. Previously, ImmLeaf
could only be used to test int64_t's produced by sign-extending an APInt.
Other tests on immediates had to use the generic PatLeaf and extract the
constant using C++.
With this patch, tablegen will know how to generate predicates for APInt,
and APFloat. This will allow it to 'do the right thing' for both SelectionDAG
and GlobalISel which require different methods of extracting the immediate
from the IR.
This is NFC for SelectionDAG since the new code is equivalent to the
previous code. It's also NFC for FastISel because FastIselShouldIgnore is 1
for the ImmLeaf subclasses. Enabling FastIselShouldIgnore == 0 for these new
subclasses will require a significant re-factor of FastISel.
For GlobalISel, it's currently NFC because the relevant code to import the
affected rules is not yet present. This will be added in a later patch.
Depends on D36086
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: bjope, aemerson, rengolin, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36534
llvm-svn: 315747
2017-10-14 04:42:18 +08:00
|
|
|
std::vector<const Record *> MatchedRecords;
|
|
|
|
const auto &Defs = RK.getAllDerivedDefinitions("PatFrag");
|
|
|
|
std::copy_if(Defs.begin(), Defs.end(), std::back_inserter(MatchedRecords),
|
|
|
|
[&](Record *Record) {
|
2018-06-16 07:13:43 +08:00
|
|
|
return !Record->getValueAsString(CodeFieldName).empty() &&
|
[aarch64] Support APInt and APFloat in ImmLeaf subclasses and make AArch64 use them.
Summary:
The purpose of this patch is to expose more information about ImmLeaf-like
PatLeaf's so that GlobalISel can learn to import them. Previously, ImmLeaf
could only be used to test int64_t's produced by sign-extending an APInt.
Other tests on immediates had to use the generic PatLeaf and extract the
constant using C++.
With this patch, tablegen will know how to generate predicates for APInt,
and APFloat. This will allow it to 'do the right thing' for both SelectionDAG
and GlobalISel which require different methods of extracting the immediate
from the IR.
This is NFC for SelectionDAG since the new code is equivalent to the
previous code. It's also NFC for FastISel because FastIselShouldIgnore is 1
for the ImmLeaf subclasses. Enabling FastIselShouldIgnore == 0 for these new
subclasses will require a significant re-factor of FastISel.
For GlobalISel, it's currently NFC because the relevant code to import the
affected rules is not yet present. This will be added in a later patch.
Depends on D36086
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: bjope, aemerson, rengolin, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36534
llvm-svn: 315747
2017-10-14 04:42:18 +08:00
|
|
|
Filter(Record);
|
|
|
|
});
|
|
|
|
|
[globalisel][tablegen] Add support for fpimm and import of APInt/APFloat based ImmLeaf.
Summary:
There's only a tablegen testcase for IntImmLeaf and not a CodeGen one
because the relevant rules are rejected for other reasons at the moment.
On AArch64, it's because there's an SDNodeXForm attached to the operand.
On X86, it's because the rule either emits multiple instructions or has
another predicate using PatFrag which cannot easily be supported at the
same time.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36569
llvm-svn: 315761
2017-10-14 05:28:03 +08:00
|
|
|
if (!MatchedRecords.empty()) {
|
|
|
|
OS << "// PatFrag predicates.\n"
|
|
|
|
<< "enum {\n";
|
2017-10-14 05:51:20 +08:00
|
|
|
std::string EnumeratorSeparator =
|
[globalisel][tablegen] Add support for fpimm and import of APInt/APFloat based ImmLeaf.
Summary:
There's only a tablegen testcase for IntImmLeaf and not a CodeGen one
because the relevant rules are rejected for other reasons at the moment.
On AArch64, it's because there's an SDNodeXForm attached to the operand.
On X86, it's because the rule either emits multiple instructions or has
another predicate using PatFrag which cannot easily be supported at the
same time.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36569
llvm-svn: 315761
2017-10-14 05:28:03 +08:00
|
|
|
(" = GIPFP_" + TypeIdentifier + "_Invalid + 1,\n").str();
|
|
|
|
for (const auto *Record : MatchedRecords) {
|
|
|
|
OS << " GIPFP_" << TypeIdentifier << "_Predicate_" << Record->getName()
|
|
|
|
<< EnumeratorSeparator;
|
|
|
|
EnumeratorSeparator = ",\n";
|
|
|
|
}
|
|
|
|
OS << "};\n";
|
[aarch64] Support APInt and APFloat in ImmLeaf subclasses and make AArch64 use them.
Summary:
The purpose of this patch is to expose more information about ImmLeaf-like
PatLeaf's so that GlobalISel can learn to import them. Previously, ImmLeaf
could only be used to test int64_t's produced by sign-extending an APInt.
Other tests on immediates had to use the generic PatLeaf and extract the
constant using C++.
With this patch, tablegen will know how to generate predicates for APInt,
and APFloat. This will allow it to 'do the right thing' for both SelectionDAG
and GlobalISel which require different methods of extracting the immediate
from the IR.
This is NFC for SelectionDAG since the new code is equivalent to the
previous code. It's also NFC for FastISel because FastIselShouldIgnore is 1
for the ImmLeaf subclasses. Enabling FastIselShouldIgnore == 0 for these new
subclasses will require a significant re-factor of FastISel.
For GlobalISel, it's currently NFC because the relevant code to import the
affected rules is not yet present. This will be added in a later patch.
Depends on D36086
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: bjope, aemerson, rengolin, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36534
llvm-svn: 315747
2017-10-14 04:42:18 +08:00
|
|
|
}
|
[globalisel][tablegen] Add support for fpimm and import of APInt/APFloat based ImmLeaf.
Summary:
There's only a tablegen testcase for IntImmLeaf and not a CodeGen one
because the relevant rules are rejected for other reasons at the moment.
On AArch64, it's because there's an SDNodeXForm attached to the operand.
On X86, it's because the rule either emits multiple instructions or has
another predicate using PatFrag which cannot easily be supported at the
same time.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36569
llvm-svn: 315761
2017-10-14 05:28:03 +08:00
|
|
|
|
2018-06-16 07:13:43 +08:00
|
|
|
OS << "bool " << Target.getName() << "InstructionSelector::test" << ArgName
|
|
|
|
<< "Predicate_" << TypeIdentifier << "(unsigned PredicateID, " << ArgType << " "
|
|
|
|
<< ArgName << ") const {\n"
|
|
|
|
<< AdditionalDeclarations;
|
|
|
|
if (!AdditionalDeclarations.empty())
|
|
|
|
OS << "\n";
|
2017-12-21 04:09:30 +08:00
|
|
|
if (!MatchedRecords.empty())
|
|
|
|
OS << " switch (PredicateID) {\n";
|
2017-12-20 22:41:51 +08:00
|
|
|
for (const auto *Record : MatchedRecords) {
|
|
|
|
OS << " case GIPFP_" << TypeIdentifier << "_Predicate_"
|
|
|
|
<< Record->getName() << ": {\n"
|
2018-06-16 07:13:43 +08:00
|
|
|
<< " " << Record->getValueAsString(CodeFieldName) << "\n"
|
|
|
|
<< " llvm_unreachable(\"" << CodeFieldName
|
|
|
|
<< " should have returned\");\n"
|
2017-12-20 22:41:51 +08:00
|
|
|
<< " return false;\n"
|
|
|
|
<< " }\n";
|
|
|
|
}
|
2017-12-21 04:09:30 +08:00
|
|
|
if (!MatchedRecords.empty())
|
|
|
|
OS << " }\n";
|
|
|
|
OS << " llvm_unreachable(\"Unknown predicate\");\n"
|
2017-12-20 22:41:51 +08:00
|
|
|
<< " return false;\n"
|
|
|
|
<< "}\n";
|
[aarch64] Support APInt and APFloat in ImmLeaf subclasses and make AArch64 use them.
Summary:
The purpose of this patch is to expose more information about ImmLeaf-like
PatLeaf's so that GlobalISel can learn to import them. Previously, ImmLeaf
could only be used to test int64_t's produced by sign-extending an APInt.
Other tests on immediates had to use the generic PatLeaf and extract the
constant using C++.
With this patch, tablegen will know how to generate predicates for APInt,
and APFloat. This will allow it to 'do the right thing' for both SelectionDAG
and GlobalISel which require different methods of extracting the immediate
from the IR.
This is NFC for SelectionDAG since the new code is equivalent to the
previous code. It's also NFC for FastISel because FastIselShouldIgnore is 1
for the ImmLeaf subclasses. Enabling FastIselShouldIgnore == 0 for these new
subclasses will require a significant re-factor of FastISel.
For GlobalISel, it's currently NFC because the relevant code to import the
affected rules is not yet present. This will be added in a later patch.
Depends on D36086
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: bjope, aemerson, rengolin, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36534
llvm-svn: 315747
2017-10-14 04:42:18 +08:00
|
|
|
}
|
|
|
|
|
2018-06-16 07:13:43 +08:00
|
|
|
void GlobalISelEmitter::emitImmPredicateFns(
|
|
|
|
raw_ostream &OS, StringRef TypeIdentifier, StringRef ArgType,
|
|
|
|
std::function<bool(const Record *R)> Filter) {
|
|
|
|
return emitCxxPredicateFns(OS, "ImmediateCode", TypeIdentifier, ArgType,
|
|
|
|
"Imm", "", Filter);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GlobalISelEmitter::emitMIPredicateFns(raw_ostream &OS) {
|
|
|
|
return emitCxxPredicateFns(
|
|
|
|
OS, "GISelPredicateCode", "MI", "const MachineInstr &", "MI",
|
|
|
|
" const MachineFunction &MF = *MI.getParent()->getParent();\n"
|
2018-06-26 15:05:08 +08:00
|
|
|
" const MachineRegisterInfo &MRI = MF.getRegInfo();\n"
|
|
|
|
" (void)MRI;",
|
2018-06-16 07:13:43 +08:00
|
|
|
[](const Record *R) { return true; });
|
|
|
|
}
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
template <class GroupT>
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
std::vector<Matcher *> GlobalISelEmitter::optimizeRules(
|
2018-05-03 04:08:14 +08:00
|
|
|
ArrayRef<Matcher *> Rules,
|
2018-05-22 07:28:51 +08:00
|
|
|
std::vector<std::unique_ptr<Matcher>> &MatcherStorage) {
|
|
|
|
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
std::vector<Matcher *> OptRules;
|
2018-05-22 07:28:51 +08:00
|
|
|
std::unique_ptr<GroupT> CurrentGroup = make_unique<GroupT>();
|
|
|
|
assert(CurrentGroup->empty() && "Newly created group isn't empty!");
|
|
|
|
unsigned NumGroups = 0;
|
|
|
|
|
|
|
|
auto ProcessCurrentGroup = [&]() {
|
|
|
|
if (CurrentGroup->empty())
|
|
|
|
// An empty group is good to be reused:
|
|
|
|
return;
|
|
|
|
|
|
|
|
// If the group isn't large enough to provide any benefit, move all the
|
|
|
|
// added rules out of it and make sure to re-create the group to properly
|
|
|
|
// re-initialize it:
|
|
|
|
if (CurrentGroup->size() < 2)
|
|
|
|
for (Matcher *M : CurrentGroup->matchers())
|
|
|
|
OptRules.push_back(M);
|
|
|
|
else {
|
|
|
|
CurrentGroup->finalize();
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
OptRules.push_back(CurrentGroup.get());
|
2018-05-22 07:28:51 +08:00
|
|
|
MatcherStorage.emplace_back(std::move(CurrentGroup));
|
|
|
|
++NumGroups;
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
CurrentGroup = make_unique<GroupT>();
|
|
|
|
};
|
|
|
|
for (Matcher *Rule : Rules) {
|
|
|
|
// Greedily add as many matchers as possible to the current group:
|
|
|
|
if (CurrentGroup->addMatcher(*Rule))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
ProcessCurrentGroup();
|
|
|
|
assert(CurrentGroup->empty() && "A group wasn't properly re-initialized");
|
|
|
|
|
|
|
|
// Try to add the pending matcher to a newly created empty group:
|
|
|
|
if (!CurrentGroup->addMatcher(*Rule))
|
|
|
|
// If we couldn't add the matcher to an empty group, that group type
|
|
|
|
// doesn't support that kind of matchers at all, so just skip it:
|
|
|
|
OptRules.push_back(Rule);
|
2018-05-22 06:21:24 +08:00
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
ProcessCurrentGroup();
|
|
|
|
|
2018-05-23 23:09:29 +08:00
|
|
|
LLVM_DEBUG(dbgs() << "NumGroups: " << NumGroups << "\n");
|
2018-05-22 07:28:51 +08:00
|
|
|
assert(CurrentGroup->empty() && "The last group wasn't properly processed");
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
return OptRules;
|
|
|
|
}
|
|
|
|
|
2018-05-03 04:08:14 +08:00
|
|
|
MatchTable
|
|
|
|
GlobalISelEmitter::buildMatchTable(MutableArrayRef<RuleMatcher> Rules,
|
2018-05-03 04:15:11 +08:00
|
|
|
bool Optimize, bool WithCoverage) {
|
2018-05-03 04:08:14 +08:00
|
|
|
std::vector<Matcher *> InputRules;
|
|
|
|
for (Matcher &Rule : Rules)
|
|
|
|
InputRules.push_back(&Rule);
|
|
|
|
|
|
|
|
if (!Optimize)
|
2018-05-03 04:15:11 +08:00
|
|
|
return MatchTable::buildTable(InputRules, WithCoverage);
|
2018-05-03 04:08:14 +08:00
|
|
|
|
2018-05-23 00:54:27 +08:00
|
|
|
unsigned CurrentOrdering = 0;
|
|
|
|
StringMap<unsigned> OpcodeOrder;
|
|
|
|
for (RuleMatcher &Rule : Rules) {
|
|
|
|
const StringRef Opcode = Rule.getOpcode();
|
|
|
|
assert(!Opcode.empty() && "Didn't expect an undefined opcode");
|
|
|
|
if (OpcodeOrder.count(Opcode) == 0)
|
|
|
|
OpcodeOrder[Opcode] = CurrentOrdering++;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::stable_sort(InputRules.begin(), InputRules.end(),
|
|
|
|
[&OpcodeOrder](const Matcher *A, const Matcher *B) {
|
|
|
|
auto *L = static_cast<const RuleMatcher *>(A);
|
|
|
|
auto *R = static_cast<const RuleMatcher *>(B);
|
|
|
|
return std::make_tuple(OpcodeOrder[L->getOpcode()],
|
|
|
|
L->getNumOperands()) <
|
|
|
|
std::make_tuple(OpcodeOrder[R->getOpcode()],
|
|
|
|
R->getNumOperands());
|
|
|
|
});
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
for (Matcher *Rule : InputRules)
|
|
|
|
Rule->optimize();
|
|
|
|
|
|
|
|
std::vector<std::unique_ptr<Matcher>> MatcherStorage;
|
2018-05-03 04:08:14 +08:00
|
|
|
std::vector<Matcher *> OptRules =
|
2018-05-22 07:28:51 +08:00
|
|
|
optimizeRules<GroupMatcher>(InputRules, MatcherStorage);
|
|
|
|
|
|
|
|
for (Matcher *Rule : OptRules)
|
|
|
|
Rule->optimize();
|
2018-05-03 04:08:14 +08:00
|
|
|
|
[GlobalISel][InstructionSelect] Switching MatchTable over opcodes, perf patch 4
This patch continues a series of patches started by r332907 (reapplied
as r332917)
In this commit we introduce a new matching opcode GIM_SwitchOpcode
that implements a jump table over opcodes and start emitting them for
root instructions.
This is expected to decrease time GlobalISel spends in its
InstructionSelect pass by roughly 20% for an -O0 build as measured on
sqlite3-amalgamation (http://sqlite.org/download.html) targeting
AArch64.
To some degree, we assume here that the opcodes form a dense set,
which is true at the moment for all upstream targets given the
limitations of our rule importing mechanism.
It might not be true for out of tree targets, specifically due to
pseudo's. If so, we might noticeably increase the size of the
MatchTable with this patch due to padding zeros. This will be
addressed later.
Reviewers: qcolombet, dsanders, bogner, aemerson, javed.absar
Reviewed By: qcolombet
Subscribers: rovka, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D44700
llvm-svn: 333017
2018-05-23 03:37:59 +08:00
|
|
|
OptRules = optimizeRules<SwitchMatcher>(OptRules, MatcherStorage);
|
|
|
|
|
2018-05-03 04:15:11 +08:00
|
|
|
return MatchTable::buildTable(OptRules, WithCoverage);
|
2018-05-03 04:08:14 +08:00
|
|
|
}
|
|
|
|
|
2018-05-23 10:04:19 +08:00
|
|
|
void GroupMatcher::optimize() {
|
2018-05-24 05:30:16 +08:00
|
|
|
// Make sure we only sort by a specific predicate within a range of rules that
|
|
|
|
// all have that predicate checked against a specific value (not a wildcard):
|
|
|
|
auto F = Matchers.begin();
|
|
|
|
auto T = F;
|
|
|
|
auto E = Matchers.end();
|
|
|
|
while (T != E) {
|
|
|
|
while (T != E) {
|
|
|
|
auto *R = static_cast<RuleMatcher *>(*T);
|
|
|
|
if (!R->getFirstConditionAsRootType().get().isValid())
|
|
|
|
break;
|
|
|
|
++T;
|
|
|
|
}
|
|
|
|
std::stable_sort(F, T, [](Matcher *A, Matcher *B) {
|
|
|
|
auto *L = static_cast<RuleMatcher *>(A);
|
|
|
|
auto *R = static_cast<RuleMatcher *>(B);
|
|
|
|
return L->getFirstConditionAsRootType() <
|
|
|
|
R->getFirstConditionAsRootType();
|
|
|
|
});
|
|
|
|
if (T != E)
|
|
|
|
F = ++T;
|
|
|
|
}
|
2018-05-23 10:04:19 +08:00
|
|
|
GlobalISelEmitter::optimizeRules<GroupMatcher>(Matchers, MatcherStorage)
|
|
|
|
.swap(Matchers);
|
2018-05-24 08:24:15 +08:00
|
|
|
GlobalISelEmitter::optimizeRules<SwitchMatcher>(Matchers, MatcherStorage)
|
|
|
|
.swap(Matchers);
|
2018-05-23 10:04:19 +08:00
|
|
|
}
|
|
|
|
|
2016-12-22 07:26:20 +08:00
|
|
|
void GlobalISelEmitter::run(raw_ostream &OS) {
|
[globalisel][tablegen] Generate rule coverage and use it to identify untested rules
Summary:
This patch adds a LLVM_ENABLE_GISEL_COV which, like LLVM_ENABLE_DAGISEL_COV,
causes TableGen to instrument the generated table to collect rule coverage
information. However, LLVM_ENABLE_GISEL_COV goes a bit further than
LLVM_ENABLE_DAGISEL_COV. The information is written to files
(${CMAKE_BINARY_DIR}/gisel-coverage-* by default). These files can then be
concatenated into ${LLVM_GISEL_COV_PREFIX}-all after which TableGen will
read this information and use it to emit warnings about untested rules.
This technique could also be used by SelectionDAG and can be further
extended to detect hot rules and give them priority over colder rules.
Usage:
* Enable LLVM_ENABLE_GISEL_COV in CMake
* Build the compiler and run some tests
* cat gisel-coverage-[0-9]* > gisel-coverage-all
* Delete lib/Target/*/*GenGlobalISel.inc*
* Build the compiler
Known issues:
* ${LLVM_GISEL_COV_PREFIX}-all must be generated as a manual
step due to a lack of a portable 'cat' command. It should be the
concatenation of all ${LLVM_GISEL_COV_PREFIX}-[0-9]* files.
* There's no mechanism to discard coverage information when the ruleset
changes
Depends on D39742
Reviewers: ab, qcolombet, t.p.northover, aditya_nandakumar, rovka
Reviewed By: rovka
Subscribers: vsk, arsenm, nhaehnle, mgorny, kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D39747
llvm-svn: 318356
2017-11-16 08:46:35 +08:00
|
|
|
if (!UseCoverageFile.empty()) {
|
|
|
|
RuleCoverage = CodeGenCoverage();
|
|
|
|
auto RuleCoverageBufOrErr = MemoryBuffer::getFile(UseCoverageFile);
|
|
|
|
if (!RuleCoverageBufOrErr) {
|
|
|
|
PrintWarning(SMLoc(), "Missing rule coverage data");
|
|
|
|
RuleCoverage = None;
|
|
|
|
} else {
|
|
|
|
if (!RuleCoverage->parse(*RuleCoverageBufOrErr.get(), Target.getName())) {
|
|
|
|
PrintWarning(SMLoc(), "Ignoring invalid or missing rule coverage data");
|
|
|
|
RuleCoverage = None;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
// Track the run-time opcode values
|
|
|
|
gatherOpcodeValues();
|
|
|
|
// Track the run-time LLT ID values
|
|
|
|
gatherTypeIDValues();
|
|
|
|
|
2016-12-22 07:26:20 +08:00
|
|
|
// 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-11-11 11:23:44 +08:00
|
|
|
|
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
|
|
|
|
[globalisel][tablegen] Generate rule coverage and use it to identify untested rules
Summary:
This patch adds a LLVM_ENABLE_GISEL_COV which, like LLVM_ENABLE_DAGISEL_COV,
causes TableGen to instrument the generated table to collect rule coverage
information. However, LLVM_ENABLE_GISEL_COV goes a bit further than
LLVM_ENABLE_DAGISEL_COV. The information is written to files
(${CMAKE_BINARY_DIR}/gisel-coverage-* by default). These files can then be
concatenated into ${LLVM_GISEL_COV_PREFIX}-all after which TableGen will
read this information and use it to emit warnings about untested rules.
This technique could also be used by SelectionDAG and can be further
extended to detect hot rules and give them priority over colder rules.
Usage:
* Enable LLVM_ENABLE_GISEL_COV in CMake
* Build the compiler and run some tests
* cat gisel-coverage-[0-9]* > gisel-coverage-all
* Delete lib/Target/*/*GenGlobalISel.inc*
* Build the compiler
Known issues:
* ${LLVM_GISEL_COV_PREFIX}-all must be generated as a manual
step due to a lack of a portable 'cat' command. It should be the
concatenation of all ${LLVM_GISEL_COV_PREFIX}-[0-9]* files.
* There's no mechanism to discard coverage information when the ruleset
changes
Depends on D39742
Reviewers: ab, qcolombet, t.p.northover, aditya_nandakumar, rovka
Reviewed By: rovka
Subscribers: vsk, arsenm, nhaehnle, mgorny, kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D39747
llvm-svn: 318356
2017-11-16 08:46:35 +08:00
|
|
|
if (RuleCoverage) {
|
|
|
|
if (RuleCoverage->isCovered(MatcherOrErr->getRuleID()))
|
|
|
|
++NumPatternsTested;
|
|
|
|
else
|
|
|
|
PrintWarning(Pat.getSrcRecord()->getLoc(),
|
|
|
|
"Pattern is not covered by a test");
|
|
|
|
}
|
2017-02-20 22:31:27 +08:00
|
|
|
Rules.push_back(std::move(MatcherOrErr.get()));
|
|
|
|
}
|
|
|
|
|
2018-01-17 02:44:05 +08:00
|
|
|
// Comparison function to order records by name.
|
|
|
|
auto orderByName = [](const Record *A, const Record *B) {
|
|
|
|
return A->getName() < B->getName();
|
|
|
|
};
|
|
|
|
|
[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");
|
llvm::sort(C.begin(), C.end(), ...) -> llvm::sort(C, ...)
Summary: The convenience wrapper in STLExtras is available since rL342102.
Reviewers: dblaikie, javed.absar, JDevlieghere, andreadb
Subscribers: MatzeB, sanjoy, arsenm, dschuff, mehdi_amini, sdardis, nemanjai, jvesely, nhaehnle, sbc100, jgravelle-google, eraman, aheejin, kbarton, JDevlieghere, javed.absar, gbedwell, jrtc27, mgrang, atanasyan, steven_wu, george.burgess.iv, dexonsmith, kristina, jsji, llvm-commits
Differential Revision: https://reviews.llvm.org/D52573
llvm-svn: 343163
2018-09-27 10:13:45 +08:00
|
|
|
llvm::sort(ComplexPredicates, orderByName);
|
2018-01-17 02:44:05 +08:00
|
|
|
|
|
|
|
std::vector<Record *> CustomRendererFns =
|
|
|
|
RK.getAllDerivedDefinitions("GICustomOperandRenderer");
|
llvm::sort(C.begin(), C.end(), ...) -> llvm::sort(C, ...)
Summary: The convenience wrapper in STLExtras is available since rL342102.
Reviewers: dblaikie, javed.absar, JDevlieghere, andreadb
Subscribers: MatzeB, sanjoy, arsenm, dschuff, mehdi_amini, sdardis, nemanjai, jvesely, nhaehnle, sbc100, jgravelle-google, eraman, aheejin, kbarton, JDevlieghere, javed.absar, gbedwell, jrtc27, mgrang, atanasyan, steven_wu, george.burgess.iv, dexonsmith, kristina, jsji, llvm-commits
Differential Revision: https://reviews.llvm.org/D52573
llvm-svn: 343163
2018-09-27 10:13:45 +08:00
|
|
|
llvm::sort(CustomRendererFns, orderByName);
|
2018-01-17 02:44:05 +08:00
|
|
|
|
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 "
|
2017-10-21 04:55:29 +08:00
|
|
|
"ComplexRendererFns("
|
[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
|
|
|
<< Target.getName()
|
|
|
|
<< "InstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const;\n"
|
2018-01-17 02:44:05 +08:00
|
|
|
|
|
|
|
<< " typedef void(" << Target.getName()
|
|
|
|
<< "InstructionSelector::*CustomRendererFn)(MachineInstrBuilder &, const "
|
|
|
|
"MachineInstr&) "
|
|
|
|
"const;\n"
|
|
|
|
<< " const ISelInfoTy<PredicateBitset, ComplexMatcherMemFn, "
|
|
|
|
"CustomRendererFn> "
|
|
|
|
"ISelInfo;\n";
|
|
|
|
OS << " static " << Target.getName()
|
2017-10-16 11:36:29 +08:00
|
|
|
<< "InstructionSelector::ComplexMatcherMemFn ComplexPredicateFns[];\n"
|
2018-01-17 02:44:05 +08:00
|
|
|
<< " static " << Target.getName()
|
|
|
|
<< "InstructionSelector::CustomRendererFn CustomRenderers[];\n"
|
2018-05-03 04:07:15 +08:00
|
|
|
<< " bool testImmPredicate_I64(unsigned PredicateID, int64_t Imm) const "
|
2017-12-20 22:41:51 +08:00
|
|
|
"override;\n"
|
2018-05-03 04:07:15 +08:00
|
|
|
<< " bool testImmPredicate_APInt(unsigned PredicateID, const APInt &Imm) "
|
2017-12-20 22:41:51 +08:00
|
|
|
"const override;\n"
|
2018-05-03 04:07:15 +08:00
|
|
|
<< " bool testImmPredicate_APFloat(unsigned PredicateID, const APFloat "
|
2017-12-20 22:41:51 +08:00
|
|
|
"&Imm) const override;\n"
|
2018-05-03 04:07:15 +08:00
|
|
|
<< " const int64_t *getMatchTable() const override;\n"
|
2018-06-16 07:13:43 +08:00
|
|
|
<< " bool testMIPredicate_MI(unsigned PredicateID, const MachineInstr &MI) "
|
|
|
|
"const override;\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
|
|
|
<< "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n";
|
|
|
|
|
|
|
|
OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n"
|
|
|
|
<< ", State(" << MaxTemporaries << "),\n"
|
2018-05-22 07:28:51 +08:00
|
|
|
<< "ISelInfo(TypeObjects, NumTypeObjects, FeatureBitsets"
|
|
|
|
<< ", ComplexPredicateFns, CustomRenderers)\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
|
|
|
<< "#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.
|
2017-08-17 21:18:35 +08:00
|
|
|
std::vector<LLTCodeGen> TypeObjects;
|
[globalisel] Update GlobalISel emitter to match new representation of extending loads
Summary:
Previously, a extending load was represented at (G_*EXT (G_LOAD x)).
This had a few drawbacks:
* G_LOAD had to be legal for all sizes you could extend from, even if
registers didn't naturally hold those sizes.
* All sizes you could extend from had to be allocatable just in case the
extend went missing (e.g. by optimization).
* At minimum, G_*EXT and G_TRUNC had to be legal for these sizes. As we
improve optimization of extends and truncates, this legality requirement
would spread without considerable care w.r.t when certain combines were
permitted.
* The SelectionDAG importer required some ugly and fragile pattern
rewriting to translate patterns into this style.
This patch changes the representation to:
* (G_[SZ]EXTLOAD x)
* (G_LOAD x) any-extends when MMO.getSize() * 8 < ResultTy.getSizeInBits()
which resolves these issues by allowing targets to work entirely in their
native register sizes, and by having a more direct translation from
SelectionDAG patterns.
Each extending load can be lowered by the legalizer into separate extends
and loads, however a target that supports s1 will need the any-extending
load to extend to at least s8 since LLVM does not represent memory accesses
smaller than 8 bit. The legalizer can widenScalar G_LOAD into an
any-extending load but sign/zero-extending loads need help from something
else like a combiner pass. A follow-up patch that adds combiner helpers for
for this will follow.
The new representation requires that the MMO correctly reflect the memory
access so this has been corrected in a couple tests. I've also moved the
extending loads to their own tests since they are (mostly) separate opcodes
now. Additionally, the re-write appears to have invalidated two tests from
select-with-no-legality-check.mir since the matcher table no longer contains
loads that result in s1's and they aren't legal in AArch64 anymore.
Depends on D45540
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, javed.absar
Reviewed By: rtereshin
Subscribers: javed.absar, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D45541
llvm-svn: 331601
2018-05-06 04:53:24 +08:00
|
|
|
for (const auto &Ty : KnownTypes)
|
2017-08-17 21:18:35 +08:00
|
|
|
TypeObjects.push_back(Ty);
|
llvm::sort(C.begin(), C.end(), ...) -> llvm::sort(C, ...)
Summary: The convenience wrapper in STLExtras is available since rL342102.
Reviewers: dblaikie, javed.absar, JDevlieghere, andreadb
Subscribers: MatzeB, sanjoy, arsenm, dschuff, mehdi_amini, sdardis, nemanjai, jvesely, nhaehnle, sbc100, jgravelle-google, eraman, aheejin, kbarton, JDevlieghere, javed.absar, gbedwell, jrtc27, mgrang, atanasyan, steven_wu, george.burgess.iv, dexonsmith, kristina, jsji, llvm-commits
Differential Revision: https://reviews.llvm.org/D52573
llvm-svn: 343163
2018-09-27 10:13:45 +08:00
|
|
|
llvm::sort(TypeObjects);
|
2017-08-23 18:09:25 +08:00
|
|
|
OS << "// LLT Objects.\n"
|
|
|
|
<< "enum {\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
|
|
|
for (const auto &TypeObject : TypeObjects) {
|
|
|
|
OS << " ";
|
|
|
|
TypeObject.emitCxxEnumValue(OS);
|
|
|
|
OS << ",\n";
|
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
OS << "};\n";
|
|
|
|
OS << "const static size_t NumTypeObjects = " << TypeObjects.size() << ";\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
|
|
|
<< "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());
|
2018-10-01 06:31:29 +08:00
|
|
|
llvm::sort(FeatureBitsets, [&](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())
|
[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 false;
|
2018-10-01 06:31:29 +08:00
|
|
|
}
|
|
|
|
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
|
|
|
FeatureBitsets.erase(
|
|
|
|
std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
|
|
|
|
FeatureBitsets.end());
|
2017-08-23 18:09:25 +08:00
|
|
|
OS << "// Feature bitsets.\n"
|
|
|
|
<< "enum {\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
|
|
|
<< " 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.
|
2017-08-23 18:09:25 +08:00
|
|
|
OS << "// ComplexPattern predicates.\n"
|
|
|
|
<< "enum {\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
|
|
|
<< " GICP_Invalid,\n";
|
|
|
|
for (const auto &Record : ComplexPredicates)
|
|
|
|
OS << " GICP_" << Record->getName() << ",\n";
|
|
|
|
OS << "};\n"
|
|
|
|
<< "// See constructor for table contents\n\n";
|
|
|
|
|
2018-06-16 07:13:43 +08:00
|
|
|
emitImmPredicateFns(OS, "I64", "int64_t", [](const Record *R) {
|
[aarch64] Support APInt and APFloat in ImmLeaf subclasses and make AArch64 use them.
Summary:
The purpose of this patch is to expose more information about ImmLeaf-like
PatLeaf's so that GlobalISel can learn to import them. Previously, ImmLeaf
could only be used to test int64_t's produced by sign-extending an APInt.
Other tests on immediates had to use the generic PatLeaf and extract the
constant using C++.
With this patch, tablegen will know how to generate predicates for APInt,
and APFloat. This will allow it to 'do the right thing' for both SelectionDAG
and GlobalISel which require different methods of extracting the immediate
from the IR.
This is NFC for SelectionDAG since the new code is equivalent to the
previous code. It's also NFC for FastISel because FastIselShouldIgnore is 1
for the ImmLeaf subclasses. Enabling FastIselShouldIgnore == 0 for these new
subclasses will require a significant re-factor of FastISel.
For GlobalISel, it's currently NFC because the relevant code to import the
affected rules is not yet present. This will be added in a later patch.
Depends on D36086
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: bjope, aemerson, rengolin, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36534
llvm-svn: 315747
2017-10-14 04:42:18 +08:00
|
|
|
bool Unset;
|
|
|
|
return !R->getValueAsBitOrUnset("IsAPFloat", Unset) &&
|
|
|
|
!R->getValueAsBit("IsAPInt");
|
|
|
|
});
|
2018-06-16 07:13:43 +08:00
|
|
|
emitImmPredicateFns(OS, "APFloat", "const APFloat &", [](const Record *R) {
|
[globalisel][tablegen] Add support for fpimm and import of APInt/APFloat based ImmLeaf.
Summary:
There's only a tablegen testcase for IntImmLeaf and not a CodeGen one
because the relevant rules are rejected for other reasons at the moment.
On AArch64, it's because there's an SDNodeXForm attached to the operand.
On X86, it's because the rule either emits multiple instructions or has
another predicate using PatFrag which cannot easily be supported at the
same time.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36569
llvm-svn: 315761
2017-10-14 05:28:03 +08:00
|
|
|
bool Unset;
|
|
|
|
return R->getValueAsBitOrUnset("IsAPFloat", Unset);
|
|
|
|
});
|
2018-06-16 07:13:43 +08:00
|
|
|
emitImmPredicateFns(OS, "APInt", "const APInt &", [](const Record *R) {
|
[globalisel][tablegen] Add support for fpimm and import of APInt/APFloat based ImmLeaf.
Summary:
There's only a tablegen testcase for IntImmLeaf and not a CodeGen one
because the relevant rules are rejected for other reasons at the moment.
On AArch64, it's because there's an SDNodeXForm attached to the operand.
On X86, it's because the rule either emits multiple instructions or has
another predicate using PatFrag which cannot easily be supported at the
same time.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar
Reviewed By: qcolombet
Subscribers: aemerson, javed.absar, igorb, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D36569
llvm-svn: 315761
2017-10-14 05:28:03 +08:00
|
|
|
return R->getValueAsBit("IsAPInt");
|
|
|
|
});
|
2018-06-16 07:13:43 +08:00
|
|
|
emitMIPredicateFns(OS);
|
2017-10-16 11:36:29 +08:00
|
|
|
OS << "\n";
|
|
|
|
|
|
|
|
OS << Target.getName() << "InstructionSelector::ComplexMatcherMemFn\n"
|
|
|
|
<< Target.getName() << "InstructionSelector::ComplexPredicateFns[] = {\n"
|
|
|
|
<< " nullptr, // GICP_Invalid\n";
|
|
|
|
for (const auto &Record : ComplexPredicates)
|
|
|
|
OS << " &" << Target.getName()
|
|
|
|
<< "InstructionSelector::" << Record->getValueAsString("MatcherFn")
|
|
|
|
<< ", // " << Record->getName() << "\n";
|
|
|
|
OS << "};\n\n";
|
2017-08-24 17:11:20 +08:00
|
|
|
|
2018-01-17 02:44:05 +08:00
|
|
|
OS << "// Custom renderers.\n"
|
|
|
|
<< "enum {\n"
|
|
|
|
<< " GICR_Invalid,\n";
|
|
|
|
for (const auto &Record : CustomRendererFns)
|
|
|
|
OS << " GICR_" << Record->getValueAsString("RendererFn") << ", \n";
|
|
|
|
OS << "};\n";
|
|
|
|
|
|
|
|
OS << Target.getName() << "InstructionSelector::CustomRendererFn\n"
|
|
|
|
<< Target.getName() << "InstructionSelector::CustomRenderers[] = {\n"
|
|
|
|
<< " nullptr, // GICP_Invalid\n";
|
|
|
|
for (const auto &Record : CustomRendererFns)
|
|
|
|
OS << " &" << Target.getName()
|
|
|
|
<< "InstructionSelector::" << Record->getValueAsString("RendererFn")
|
|
|
|
<< ", // " << Record->getName() << "\n";
|
|
|
|
OS << "};\n\n";
|
|
|
|
|
2019-04-23 22:51:27 +08:00
|
|
|
llvm::stable_sort(Rules, [&](const RuleMatcher &A, const RuleMatcher &B) {
|
2018-02-17 06:37:15 +08:00
|
|
|
int ScoreA = RuleMatcherScores[A.getRuleID()];
|
|
|
|
int ScoreB = RuleMatcherScores[B.getRuleID()];
|
|
|
|
if (ScoreA > ScoreB)
|
|
|
|
return true;
|
|
|
|
if (ScoreB > ScoreA)
|
|
|
|
return false;
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +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;
|
|
|
|
});
|
2018-05-03 04:07:15 +08:00
|
|
|
|
|
|
|
OS << "bool " << Target.getName()
|
|
|
|
<< "InstructionSelector::selectImpl(MachineInstr &I, CodeGenCoverage "
|
|
|
|
"&CoverageInfo) const {\n"
|
|
|
|
<< " MachineFunction &MF = *I.getParent()->getParent();\n"
|
|
|
|
<< " MachineRegisterInfo &MRI = MF.getRegInfo();\n"
|
|
|
|
<< " // FIXME: This should be computed on a per-function basis rather "
|
|
|
|
"than per-insn.\n"
|
|
|
|
<< " AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, "
|
|
|
|
"&MF);\n"
|
|
|
|
<< " const PredicateBitset AvailableFeatures = getAvailableFeatures();\n"
|
|
|
|
<< " NewMIVector OutMIs;\n"
|
|
|
|
<< " State.MIs.clear();\n"
|
|
|
|
<< " State.MIs.push_back(&I);\n\n"
|
|
|
|
<< " if (executeMatchTable(*this, OutMIs, State, ISelInfo"
|
|
|
|
<< ", getMatchTable(), TII, MRI, TRI, RBI, AvailableFeatures"
|
|
|
|
<< ", CoverageInfo)) {\n"
|
2017-07-27 19:03:45 +08:00
|
|
|
<< " return true;\n"
|
2018-05-03 04:07:15 +08:00
|
|
|
<< " }\n\n"
|
|
|
|
<< " return false;\n"
|
|
|
|
<< "}\n\n";
|
2016-12-22 07:26:20 +08:00
|
|
|
|
2018-05-03 04:15:11 +08:00
|
|
|
const MatchTable Table =
|
|
|
|
buildMatchTable(Rules, OptimizeMatchTable, GenerateCoverage);
|
2018-05-03 04:07:15 +08:00
|
|
|
OS << "const int64_t *" << Target.getName()
|
|
|
|
<< "InstructionSelector::getMatchTable() const {\n";
|
|
|
|
Table.emitDeclaration(OS);
|
|
|
|
OS << " return ";
|
|
|
|
Table.emitUse(OS);
|
|
|
|
OS << ";\n}\n";
|
|
|
|
OS << "#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()));
|
|
|
|
}
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
void RuleMatcher::optimize() {
|
|
|
|
for (auto &Item : InsnVariableIDs) {
|
|
|
|
InstructionMatcher &InsnMatcher = *Item.first;
|
|
|
|
for (auto &OM : InsnMatcher.operands()) {
|
2018-05-24 07:58:10 +08:00
|
|
|
// Complex Patterns are usually expensive and they relatively rarely fail
|
|
|
|
// on their own: more often we end up throwing away all the work done by a
|
|
|
|
// matching part of a complex pattern because some other part of the
|
|
|
|
// enclosing pattern didn't match. All of this makes it beneficial to
|
|
|
|
// delay complex patterns until the very end of the rule matching,
|
|
|
|
// especially for targets having lots of complex patterns.
|
2018-05-22 07:28:51 +08:00
|
|
|
for (auto &OP : OM->predicates())
|
2018-05-24 07:58:10 +08:00
|
|
|
if (isa<ComplexPatternOperandMatcher>(OP))
|
2018-05-22 07:28:51 +08:00
|
|
|
EpilogueMatchers.emplace_back(std::move(OP));
|
|
|
|
OM->eraseNullPredicates();
|
|
|
|
}
|
|
|
|
InsnMatcher.optimize();
|
|
|
|
}
|
2018-10-01 06:31:29 +08:00
|
|
|
llvm::sort(EpilogueMatchers, [](const std::unique_ptr<PredicateMatcher> &L,
|
|
|
|
const std::unique_ptr<PredicateMatcher> &R) {
|
|
|
|
return std::make_tuple(L->getKind(), L->getInsnVarID(), L->getOpIdx()) <
|
|
|
|
std::make_tuple(R->getKind(), R->getInsnVarID(), R->getOpIdx());
|
|
|
|
});
|
2018-05-22 07:28:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool RuleMatcher::hasFirstCondition() const {
|
|
|
|
if (insnmatchers_empty())
|
|
|
|
return false;
|
|
|
|
InstructionMatcher &Matcher = insnmatchers_front();
|
|
|
|
if (!Matcher.predicates_empty())
|
|
|
|
return true;
|
|
|
|
for (auto &OM : Matcher.operands())
|
|
|
|
for (auto &OP : OM->predicates())
|
|
|
|
if (!isa<InstructionOperandMatcher>(OP))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const PredicateMatcher &RuleMatcher::getFirstCondition() const {
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
assert(!insnmatchers_empty() &&
|
2018-05-22 07:28:51 +08:00
|
|
|
"Trying to get a condition from an empty RuleMatcher");
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
|
|
|
|
InstructionMatcher &Matcher = insnmatchers_front();
|
|
|
|
if (!Matcher.predicates_empty())
|
2018-05-22 07:28:51 +08:00
|
|
|
return **Matcher.predicates_begin();
|
|
|
|
// If there is no more predicate on the instruction itself, look at its
|
|
|
|
// operands.
|
|
|
|
for (auto &OM : Matcher.operands())
|
|
|
|
for (auto &OP : OM->predicates())
|
|
|
|
if (!isa<InstructionOperandMatcher>(OP))
|
|
|
|
return *OP;
|
|
|
|
|
|
|
|
llvm_unreachable("Trying to get a condition from an InstructionMatcher with "
|
|
|
|
"no conditions");
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
}
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
std::unique_ptr<PredicateMatcher> RuleMatcher::popFirstCondition() {
|
|
|
|
assert(!insnmatchers_empty() &&
|
|
|
|
"Trying to pop a condition from an empty RuleMatcher");
|
|
|
|
|
|
|
|
InstructionMatcher &Matcher = insnmatchers_front();
|
|
|
|
if (!Matcher.predicates_empty())
|
|
|
|
return Matcher.predicates_pop_front();
|
|
|
|
// If there is no more predicate on the instruction itself, look at its
|
|
|
|
// operands.
|
|
|
|
for (auto &OM : Matcher.operands())
|
|
|
|
for (auto &OP : OM->predicates())
|
|
|
|
if (!isa<InstructionOperandMatcher>(OP)) {
|
|
|
|
std::unique_ptr<PredicateMatcher> Result = std::move(OP);
|
|
|
|
OM->eraseNullPredicates();
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm_unreachable("Trying to pop a condition from an InstructionMatcher with "
|
|
|
|
"no conditions");
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GroupMatcher::candidateConditionMatches(
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
const PredicateMatcher &Predicate) const {
|
2018-05-22 07:28:51 +08:00
|
|
|
|
|
|
|
if (empty()) {
|
|
|
|
// Sharing predicates for nested instructions is not supported yet as we
|
|
|
|
// currently don't hoist the GIM_RecordInsn's properly, therefore we can
|
|
|
|
// only work on the original root instruction (InsnVarID == 0):
|
|
|
|
if (Predicate.getInsnVarID() != 0)
|
|
|
|
return false;
|
|
|
|
// ... otherwise an empty group can handle any predicate with no specific
|
|
|
|
// requirements:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Matcher &Representative = **Matchers.begin();
|
|
|
|
const auto &RepresentativeCondition = Representative.getFirstCondition();
|
|
|
|
// ... if not empty, the group can only accomodate matchers with the exact
|
|
|
|
// same first condition:
|
|
|
|
return Predicate.isIdentical(RepresentativeCondition);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GroupMatcher::addMatcher(Matcher &Candidate) {
|
|
|
|
if (!Candidate.hasFirstCondition())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
const PredicateMatcher &Predicate = Candidate.getFirstCondition();
|
|
|
|
if (!candidateConditionMatches(Predicate))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
Matchers.push_back(&Candidate);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GroupMatcher::finalize() {
|
|
|
|
assert(Conditions.empty() && "Already finalized?");
|
|
|
|
if (empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
Matcher &FirstRule = **Matchers.begin();
|
[GlobalISel][InstructionSelect] Maximizing # of Group's common conditions, perf patch 8
This patch continues a series of patches started by r332907 (reapplied
as r332917).
In this commit we greedily stuff 2nd level GroupMatcher's common
conditions with as many predicates as possible. This is purely
post-processing and it doesn't change which rules are put into the
groups in the first place: that decision is made by looking at the
first common predicate only.
The compile time improvements are minor and well within error margin,
however, it's highly improbable that this transformation could
pessimize performance, thus I'm still committing it for potential
gains for targets not implementing GlobalISel yet and out of tree
targets.
Reviewers: qcolombet, dsanders, bogner, aemerson, javed.absar
Reviewed By: qcolombet
Subscribers: rovka, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D44700
llvm-svn: 333139
2018-05-24 06:50:53 +08:00
|
|
|
for (;;) {
|
|
|
|
// All the checks are expected to succeed during the first iteration:
|
|
|
|
for (const auto &Rule : Matchers)
|
|
|
|
if (!Rule->hasFirstCondition())
|
|
|
|
return;
|
|
|
|
const auto &FirstCondition = FirstRule.getFirstCondition();
|
|
|
|
for (unsigned I = 1, E = Matchers.size(); I < E; ++I)
|
|
|
|
if (!Matchers[I]->getFirstCondition().isIdentical(FirstCondition))
|
|
|
|
return;
|
2018-05-22 07:28:51 +08:00
|
|
|
|
[GlobalISel][InstructionSelect] Maximizing # of Group's common conditions, perf patch 8
This patch continues a series of patches started by r332907 (reapplied
as r332917).
In this commit we greedily stuff 2nd level GroupMatcher's common
conditions with as many predicates as possible. This is purely
post-processing and it doesn't change which rules are put into the
groups in the first place: that decision is made by looking at the
first common predicate only.
The compile time improvements are minor and well within error margin,
however, it's highly improbable that this transformation could
pessimize performance, thus I'm still committing it for potential
gains for targets not implementing GlobalISel yet and out of tree
targets.
Reviewers: qcolombet, dsanders, bogner, aemerson, javed.absar
Reviewed By: qcolombet
Subscribers: rovka, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D44700
llvm-svn: 333139
2018-05-24 06:50:53 +08:00
|
|
|
Conditions.push_back(FirstRule.popFirstCondition());
|
|
|
|
for (unsigned I = 1, E = Matchers.size(); I < E; ++I)
|
|
|
|
Matchers[I]->popFirstCondition();
|
|
|
|
}
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GroupMatcher::emit(MatchTable &Table) {
|
2018-05-22 07:28:51 +08:00
|
|
|
unsigned LabelID = ~0U;
|
|
|
|
if (!Conditions.empty()) {
|
|
|
|
LabelID = Table.allocateLabelID();
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
Table << MatchTable::Opcode("GIM_Try", +1)
|
|
|
|
<< MatchTable::Comment("On fail goto")
|
|
|
|
<< MatchTable::JumpTarget(LabelID) << MatchTable::LineBreak;
|
|
|
|
}
|
2018-05-22 07:28:51 +08:00
|
|
|
for (auto &Condition : Conditions)
|
|
|
|
Condition->emitPredicateOpcodes(
|
|
|
|
Table, *static_cast<RuleMatcher *>(*Matchers.begin()));
|
|
|
|
|
|
|
|
for (const auto &M : Matchers)
|
|
|
|
M->emit(Table);
|
|
|
|
|
|
|
|
// Exit the group
|
|
|
|
if (!Conditions.empty())
|
|
|
|
Table << MatchTable::Opcode("GIM_Reject", -1) << MatchTable::LineBreak
|
[TableGen][GlobalISel] Optimize MatchTable for faster instruction selection
*** Context ***
Prior to this patchw, the table generated for matching instruction was
straight forward but highly inefficient.
Basically, each pattern generates its own set of self contained checks
and actions.
E.g., TableGen generated:
// First pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDrr
// Second pattern
CheckNumOperand 3
CheckOpcode G_ADD
...
Build ADDri
// Third pattern
CheckNumOperand 3
CheckOpcode G_SUB
...
Build SUBrr
*** Problem ***
Because of that generation, a *lot* of check were redundant between each
pattern and were checked every single time until we reach the pattern
that matches.
E.g., Taking the previous table, let say we are matching a G_SUB, that
means we were going to check all the rules for G_ADD before looking at
the G_SUB rule. In particular we are going to do:
check 3 operands; PASS
check G_ADD; FAIL
; Next rule
check 3 operands; PASS (but we already knew that!)
check G_ADD; FAIL (well it is still not true)
; Next rule
check 3 operands; PASS (really!!)
check G_SUB; PASS (at last :P)
*** Proposed Solution ***
This patch introduces a concept of group of rules (GroupMatcher) that
share some predicates and only get checked once for the whole group.
This patch only creates groups with one nesting level. Conceptually
there is nothing preventing us for having deeper nest level. However,
the current implementation is not smart enough to share the recording
(aka capturing) of values. That limits its ability to do more sharing.
For the given example the current patch will generate:
// First group
CheckOpcode G_ADD
// First pattern
CheckNumOperand 3
...
Build ADDrr
// Second pattern
CheckNumOperand 3
...
Build ADDri
// Second group
CheckOpcode G_SUB
// Third pattern
CheckNumOperand 3
...
Build SUBrr
But if we allowed several nesting level, it could create a sub group
for the checknumoperand 3.
(We would need to call optimizeRules on the rules within a group.)
*** Result ***
With only one level of nesting, the instruction selection pass is up
to 4x faster. For instance, one instruction now takes 500 checks,
instead of 24k! With more nesting we could get in the tens I believe.
Differential Revision: https://reviews.llvm.org/D39034
rdar://problem/34670699
llvm-svn: 321017
2017-12-19 03:47:41 +08:00
|
|
|
<< MatchTable::Label(LabelID);
|
|
|
|
}
|
|
|
|
|
[GlobalISel][InstructionSelect] Switching MatchTable over opcodes, perf patch 4
This patch continues a series of patches started by r332907 (reapplied
as r332917)
In this commit we introduce a new matching opcode GIM_SwitchOpcode
that implements a jump table over opcodes and start emitting them for
root instructions.
This is expected to decrease time GlobalISel spends in its
InstructionSelect pass by roughly 20% for an -O0 build as measured on
sqlite3-amalgamation (http://sqlite.org/download.html) targeting
AArch64.
To some degree, we assume here that the opcodes form a dense set,
which is true at the moment for all upstream targets given the
limitations of our rule importing mechanism.
It might not be true for out of tree targets, specifically due to
pseudo's. If so, we might noticeably increase the size of the
MatchTable with this patch due to padding zeros. This will be
addressed later.
Reviewers: qcolombet, dsanders, bogner, aemerson, javed.absar
Reviewed By: qcolombet
Subscribers: rovka, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D44700
llvm-svn: 333017
2018-05-23 03:37:59 +08:00
|
|
|
bool SwitchMatcher::isSupportedPredicateType(const PredicateMatcher &P) {
|
2018-05-24 08:24:15 +08:00
|
|
|
return isa<InstructionOpcodeMatcher>(P) || isa<LLTOperandMatcher>(P);
|
[GlobalISel][InstructionSelect] Switching MatchTable over opcodes, perf patch 4
This patch continues a series of patches started by r332907 (reapplied
as r332917)
In this commit we introduce a new matching opcode GIM_SwitchOpcode
that implements a jump table over opcodes and start emitting them for
root instructions.
This is expected to decrease time GlobalISel spends in its
InstructionSelect pass by roughly 20% for an -O0 build as measured on
sqlite3-amalgamation (http://sqlite.org/download.html) targeting
AArch64.
To some degree, we assume here that the opcodes form a dense set,
which is true at the moment for all upstream targets given the
limitations of our rule importing mechanism.
It might not be true for out of tree targets, specifically due to
pseudo's. If so, we might noticeably increase the size of the
MatchTable with this patch due to padding zeros. This will be
addressed later.
Reviewers: qcolombet, dsanders, bogner, aemerson, javed.absar
Reviewed By: qcolombet
Subscribers: rovka, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D44700
llvm-svn: 333017
2018-05-23 03:37:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool SwitchMatcher::candidateConditionMatches(
|
|
|
|
const PredicateMatcher &Predicate) const {
|
|
|
|
|
|
|
|
if (empty()) {
|
|
|
|
// Sharing predicates for nested instructions is not supported yet as we
|
|
|
|
// currently don't hoist the GIM_RecordInsn's properly, therefore we can
|
|
|
|
// only work on the original root instruction (InsnVarID == 0):
|
|
|
|
if (Predicate.getInsnVarID() != 0)
|
|
|
|
return false;
|
|
|
|
// ... while an attempt to add even a root matcher to an empty SwitchMatcher
|
|
|
|
// could fail as not all the types of conditions are supported:
|
|
|
|
if (!isSupportedPredicateType(Predicate))
|
|
|
|
return false;
|
|
|
|
// ... or the condition might not have a proper implementation of
|
|
|
|
// getValue() / isIdenticalDownToValue() yet:
|
|
|
|
if (!Predicate.hasValue())
|
|
|
|
return false;
|
|
|
|
// ... otherwise an empty Switch can accomodate the condition with no
|
|
|
|
// further requirements:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Matcher &CaseRepresentative = **Matchers.begin();
|
|
|
|
const auto &RepresentativeCondition = CaseRepresentative.getFirstCondition();
|
|
|
|
// Switch-cases must share the same kind of condition and path to the value it
|
|
|
|
// checks:
|
|
|
|
if (!Predicate.isIdenticalDownToValue(RepresentativeCondition))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
const auto Value = Predicate.getValue();
|
|
|
|
// ... but be unique with respect to the actual value they check:
|
|
|
|
return Values.count(Value) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SwitchMatcher::addMatcher(Matcher &Candidate) {
|
|
|
|
if (!Candidate.hasFirstCondition())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
const PredicateMatcher &Predicate = Candidate.getFirstCondition();
|
|
|
|
if (!candidateConditionMatches(Predicate))
|
|
|
|
return false;
|
|
|
|
const auto Value = Predicate.getValue();
|
|
|
|
Values.insert(Value);
|
|
|
|
|
|
|
|
Matchers.push_back(&Candidate);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SwitchMatcher::finalize() {
|
|
|
|
assert(Condition == nullptr && "Already finalized");
|
|
|
|
assert(Values.size() == Matchers.size() && "Broken SwitchMatcher");
|
|
|
|
if (empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
std::stable_sort(Matchers.begin(), Matchers.end(),
|
|
|
|
[](const Matcher *L, const Matcher *R) {
|
|
|
|
return L->getFirstCondition().getValue() <
|
|
|
|
R->getFirstCondition().getValue();
|
|
|
|
});
|
|
|
|
Condition = Matchers[0]->popFirstCondition();
|
|
|
|
for (unsigned I = 1, E = Values.size(); I < E; ++I)
|
|
|
|
Matchers[I]->popFirstCondition();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SwitchMatcher::emitPredicateSpecificOpcodes(const PredicateMatcher &P,
|
|
|
|
MatchTable &Table) {
|
|
|
|
assert(isSupportedPredicateType(P) && "Predicate type is not supported");
|
|
|
|
|
|
|
|
if (const auto *Condition = dyn_cast<InstructionOpcodeMatcher>(&P)) {
|
|
|
|
Table << MatchTable::Opcode("GIM_SwitchOpcode") << MatchTable::Comment("MI")
|
|
|
|
<< MatchTable::IntValue(Condition->getInsnVarID());
|
|
|
|
return;
|
|
|
|
}
|
2018-05-24 08:24:15 +08:00
|
|
|
if (const auto *Condition = dyn_cast<LLTOperandMatcher>(&P)) {
|
|
|
|
Table << MatchTable::Opcode("GIM_SwitchType") << MatchTable::Comment("MI")
|
|
|
|
<< MatchTable::IntValue(Condition->getInsnVarID())
|
|
|
|
<< MatchTable::Comment("Op")
|
|
|
|
<< MatchTable::IntValue(Condition->getOpIdx());
|
|
|
|
return;
|
|
|
|
}
|
[GlobalISel][InstructionSelect] Switching MatchTable over opcodes, perf patch 4
This patch continues a series of patches started by r332907 (reapplied
as r332917)
In this commit we introduce a new matching opcode GIM_SwitchOpcode
that implements a jump table over opcodes and start emitting them for
root instructions.
This is expected to decrease time GlobalISel spends in its
InstructionSelect pass by roughly 20% for an -O0 build as measured on
sqlite3-amalgamation (http://sqlite.org/download.html) targeting
AArch64.
To some degree, we assume here that the opcodes form a dense set,
which is true at the moment for all upstream targets given the
limitations of our rule importing mechanism.
It might not be true for out of tree targets, specifically due to
pseudo's. If so, we might noticeably increase the size of the
MatchTable with this patch due to padding zeros. This will be
addressed later.
Reviewers: qcolombet, dsanders, bogner, aemerson, javed.absar
Reviewed By: qcolombet
Subscribers: rovka, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D44700
llvm-svn: 333017
2018-05-23 03:37:59 +08:00
|
|
|
|
|
|
|
llvm_unreachable("emitPredicateSpecificOpcodes is broken: can not handle a "
|
|
|
|
"predicate type that is claimed to be supported");
|
|
|
|
}
|
|
|
|
|
|
|
|
void SwitchMatcher::emit(MatchTable &Table) {
|
|
|
|
assert(Values.size() == Matchers.size() && "Broken SwitchMatcher");
|
|
|
|
if (empty())
|
|
|
|
return;
|
|
|
|
assert(Condition != nullptr &&
|
|
|
|
"Broken SwitchMatcher, hasn't been finalized?");
|
|
|
|
|
|
|
|
std::vector<unsigned> LabelIDs(Values.size());
|
|
|
|
std::generate(LabelIDs.begin(), LabelIDs.end(),
|
|
|
|
[&Table]() { return Table.allocateLabelID(); });
|
|
|
|
const unsigned Default = Table.allocateLabelID();
|
|
|
|
|
|
|
|
const int64_t LowerBound = Values.begin()->getRawValue();
|
|
|
|
const int64_t UpperBound = Values.rbegin()->getRawValue() + 1;
|
|
|
|
|
|
|
|
emitPredicateSpecificOpcodes(*Condition, Table);
|
|
|
|
|
|
|
|
Table << MatchTable::Comment("[") << MatchTable::IntValue(LowerBound)
|
|
|
|
<< MatchTable::IntValue(UpperBound) << MatchTable::Comment(")")
|
|
|
|
<< MatchTable::Comment("default:") << MatchTable::JumpTarget(Default);
|
|
|
|
|
|
|
|
int64_t J = LowerBound;
|
|
|
|
auto VI = Values.begin();
|
|
|
|
for (unsigned I = 0, E = Values.size(); I < E; ++I) {
|
|
|
|
auto V = *VI++;
|
|
|
|
while (J++ < V.getRawValue())
|
|
|
|
Table << MatchTable::IntValue(0);
|
|
|
|
V.turnIntoComment();
|
|
|
|
Table << MatchTable::LineBreak << V << MatchTable::JumpTarget(LabelIDs[I]);
|
|
|
|
}
|
|
|
|
Table << MatchTable::LineBreak;
|
|
|
|
|
|
|
|
for (unsigned I = 0, E = Values.size(); I < E; ++I) {
|
|
|
|
Table << MatchTable::Label(LabelIDs[I]);
|
|
|
|
Matchers[I]->emit(Table);
|
|
|
|
Table << MatchTable::Opcode("GIM_Reject") << MatchTable::LineBreak;
|
|
|
|
}
|
|
|
|
Table << MatchTable::Label(Default);
|
|
|
|
}
|
|
|
|
|
2018-05-22 07:28:51 +08:00
|
|
|
unsigned OperandMatcher::getInsnVarID() const { return Insn.getInsnVarID(); }
|
2017-12-16 07:07:42 +08:00
|
|
|
|
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
|