Almost all uses of `*TreePatternNode` expect it to be non-null. There
was the occasional check that it wasn't, which I have removed. Making
them references makes it clear that they exist.
This was attempted in 2018 (1b465767d6ca69f4b7201503f5f21e6125fe049a)
for `TreePatternNode::getChild()` but that was reverted.
While working on DAGISelMatcherEmitter I've hit several runtime errors
caused by accessing TreePatternNode::Types out of bounds. These were
difficult to debug because the switch from std::vector to unique_ptr
removes bounds checking.
I don't think the slight reduction in class size is worth the extra
debugging and memory safety problems, so I suggest we revert this.
This reverts commit d34125a1a825208b592cfa8f5fc3566303d691a4.
Differential Revision: https://reviews.llvm.org/D154781
These vectors are resized in the constructor and never change size.
We can manually allocate two arrays instead.
This reduces the size of TreePatternNode by removing the
unneeded capacity end pointer fields from the std::vector.
We reserved 16 AddrSpaces in every TypeSetByHwMode. But we only ever
use the first one on targets that make use of the AddrSpace feature.
The vector was populated by pushing for each entry in the ArrayRef
passed to the TypeSetByHwMode constructor. Each entry is a
ValueTypeByHwMode that stores one VT for each HwMode.
The vector is accessed by a loop in TypeSetByHwMode::getValueTypeByHwMode.
That loop is over HwModes with in the TypeSetByHwMode. This is
unrelated to how the vector was created. The entries in the vector
don't represent HwModes.
The targets that use AddrSpace don't make use of HwModes so the
loop in getValueTypeByHwMode will only run 1 iteration. So we only
the first entry in the vector is meaningful used.
This patch simplifies things by storing only 1 AddrSpace in
TypeSetByMode. Reducing the memory used by TypeSetByHwMode.
More work will be needed to support HwModes with AddrSpace if we
need a different AddrSpace for each HwMode.
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D148194
An intrusive reference counter uses less memory than the control
block of std::shared_ptr.
This should allow some additional code simplifications if we
don't need to pass around shared_ptr in order to create new
shared_ptrs.
Previously we were passing 'this' and the std::shared_ptr version
of 'this'. This replaces all uses of 'this' with the shared_ptr and
makes the method static.
InfoByHwMode is the base class of TypeSetByHwMode. The two methods
did the same thing. No reason to have two ways to do it.
Also use the getSimple() access instead of Map.begin()->second.
RFC to add a way to ignore COPY instructions when pattern-matching MIR in GISel.
- Add a new "GISelFlags" class to TableGen. Both `Pattern` and `PatFrags` defs can use it to alter matching behaviour.
- Flags start at zero and are scoped: the setter returns a `SaveAndRestore` object so that when the current scope ends, the flags are restored to their previous values. This allows child patterns to modify the flags without affecting the parent pattern.
- Child patterns always reuse the parent's pattern, but they can override its values. For more examples, see `GlobalISelEmitterFlags.td` tests.
- [AMDGPU] Use the IgnoreCopies flag in BFI patterns, which are known to be bothered by cross-regbank copies.
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D136234
At each call to findFirstSet in this patch, the argument is known to
be nonzero, so we can safely switch to llvm::countr_zero, which will
become std::countr_zero once C++20 is available.
This change introduces the HasNoUse builtin predicate in PatFrags that
checks for the absence of use of the first result operand.
GlobalISelEmitter will allow source PatFrags with this predicate to be
matched with destination instructions with empty outs. This predicate is
required for selecting the no-return variant of atomic instructions in
AMDGPU.
Differential Revision: https://reviews.llvm.org/D125212
The operand of the second any_of in EnforceSmallerThan should be
B not S like the FP code in the if below.
Unfortunately, fixing that causes an infinite loop in the build
of RISCV. So I've added a workaround for that as well.
Fixes PR44768.
Reviewed By: RKSimon
Differential Revision: https://reviews.llvm.org/D111502
This uses to be how predicates were handled prior to HwMode being
added. When the Predicates were converted to a std::vector it
significantly increased the cost of a compare in GenerateVariants.
Since ListInit's are uniquified by tablegen, we can use a simple
pointer comparison to check for identical lists.
In order to store the HwMode, we now add a separate string to
PatternToMatch. This will be appended separately to the predicate
string in getPredicateCheck. A new getPredicateRecords is added
to allow GlobalISel and getPredicateCheck to both get the sorted
list of Records. GlobalISel was ignoring any HwMode predicates
before and still is.
There is one slight change here, ListInits with different predicate
orders aren't sorted so the filtering in GenerateVariants might
fail to detect two isomorphic patterns with different predicate
orders. This doesn't seem to be happening in tree today.
My hope is this will allow us to remove all the BitVector tracking
in GenerateVariants that was making up for predicates beeing
expensive to compare. There's a decent amount of heap allocations
there on large targets like X86, AMDGPU, and RISCV.
Differential Revision: https://reviews.llvm.org/D100691
This was causing GenerateVariants to lose some variants since
HwMode is expanded first. We were mistakenly thinking the HwMode
predicate matched and finding the variant was isomorphic to a
pattern in another HwMode and discarding it.
Found while investigating it if would be better to generate
variants before expanding HwModes to improve RISCV build time.
I noticed an increase in the number of Opc_MorphNodeTo in the table
which indicated that the number of patterns had changed.
hasMode was looking up the map once. Then we'd either call get which
would look up again, or we'd insert into the map which requires
walking the map to find the insertion point.
I believe the hasMode was needed because get has a special case
to look for DefaultMode if the mode being asked for doesn't exist.
We don't want that here so we were using hasMode to make sure we
wouldn't hit that case.
Simplify to a regular operator[] access which will default
construct a SetType if the lookup fails.
The size of VTList that is pushed into this container is usually 1, but
often 6 or 7. Change the vector to SmallVector to eliminate frequent
mallocs. This happens hundreds of thousands of times in each tablegen
execution during the LLVM/clang build.
https://reviews.llvm.org/D83849
This is how it should've been and brings it more in line with
std::string_view. There should be no functional change here.
This is mostly mechanical from a custom clang-tidy check, with a lot of
manual fixups. It uncovers a lot of minor inefficiencies.
This doesn't actually modify StringRef yet, I'll do that in a follow-up.
AMDGPU was the last in tree target to use this tablegen mode. I plan to
split up the global intrinsic enum similar to the way that clang
diagnostics are split up today. I don't plan to build on this mode.
Reviewers: arsenm, echristo, efriedma
Reviewed By: echristo
Differential Revision: https://reviews.llvm.org/D71318
AMDGPU uses some custom code predicates for testing alignments.
I'm still having trouble comprehending the behavior of predicate bits
in the PatFrag hierarchy. Any attempt to abstract these properties
unexpectdly fails to apply them.
llvm-svn: 367373
Empty condition strings are considerde always true. This removes a lot
of clutter from the generated matcher tables.
This shrinks the source size of AMDGPUGenDAGISel.inc from 7.3M to
6.1M.
llvm-svn: 367326
Currently AMDGPU uses a CodePatPred to check address spaces from the
MachineMemOperand. Introduce a new first class property so that the
existing patterns can be easily modified to uses the new generated
predicate, which will also be handled for GlobalISel.
I would prefer these to match against the pointer type of the
instruction, but that would be difficult to get working with
SelectionDAG compatbility. This is much easier for now and will avoid
a painful tablegen rewrite for all the loads and stores.
I'm also not sure if there's a better way to encode multiple address
spaces in the table, rather than putting the number to expect.
llvm-svn: 366128
When a Tablegen instruction description uses `OperandWithDefaultOps`,
isel patterns for that instruction don't have to fill in the default
value for the operand in question. But the flip side is that they
actually //can't// override the defaults even if they want to.
This will be very inconvenient for the Arm backend, when we start
wanting to write isel patterns that generate the many MVE predicated
vector instructions, in the form with predication actually enabled. So
this small Tablegen fix makes it possible to write an isel pattern
either with or without values for a defaulted operand, and have the
default values filled in only if they are not overridden.
If all the defaulted operands come at the end of the instruction's
operand list, there's a natural way to match them up to the arguments
supplied in the pattern: consume pattern arguments until you run out,
then fill in any missing instruction operands with their default
values. But if defaulted and non-defaulted operands are interleaved,
it's less clear what to do. This does happen in existing targets (the
first example I came across was KILLGT, in the AMDGPU/R600 backend),
and of course they expect the previous behaviour (that the default for
those operands is used and a pattern argument is not consumed), so for
backwards compatibility I've stuck with that.
Reviewers: nhaehnle, hfinkel, dmgreen
Subscribers: mehdi_amini, javed.absar, tpr, kristof.beyls, steven_wu, dexonsmith, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D63814
llvm-svn: 365114
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