[PATCH] D59339: [GISel][Legalizer][WIP][RFC] Retry legalization for failing instrs when artifacts are around
Petar Avramovic via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 15 07:12:23 PDT 2019
Petar.Avramovic added a comment.
I did not consider the case where sequence of instruction is legal, but individual instructions are not.
Condition when we throw an error might become
`if (ArtifactList.empty() && TryLaterArtifactList.empty()) `
but other then that, there is no conflicts with artifact combining so it should not be a problem.
here is a small example:
i64 is held as two i32s.
define i64 @f(i32 %x) {
entry:
%conv = zext i32 %x to i64
ret i64 %conv
}
IRTranslator gives:
%0:_(s32) = COPY $a0
%1:_(s64) = G_ZEXT %0(s32)
%2:_(s32), %3:_(s32) = G_UNMERGE_VALUES %1(s64)
$v0 = COPY %2(s32)
$v1 = COPY %3(s32)
RetRA implicit $v0, implicit $v1
In Legalizer, ArtifactList contains:
%1:_(s64) = G_ZEXT %0:_(s32)
%2:_(s32), %3:_(s32) = G_UNMERGE_VALUES %1:_(s64)
and we go bottom up.
Here
Artifact `%2:_(s32), %3:_(s32) = G_UNMERGE_VALUES %1:_(s64) `
Has nothing to combine with at the moment, but it has artifact use (zext) and goes to TryLaterArtifactList
Artifact `%1:_(s64) = G_ZEXT %0:_(s32)` had nothing to combine with, and is moved to InstList
Instruction `%1:_(s64) = G_ZEXT %0:_(s32)` gets narrowScalar-ed:
%0:_(s32) = COPY $a0
%1:_(s64) = G_ZEXT %0:_(s32)
Into:
%4:_(s32) = G_CONSTANT i32 0
%1:_(s64) = G_MERGE_VALUES %0:_(s32), %4:_(s32)
ArtifactList contains:
%1:_(s64) = G_MERGE_VALUES %0:_(s32), %4:_(s32)
G_MERGE_VALUES gets turned into instruction and legalized (it is legal).
now we move TryLaterArtifactList to ArtifactList
ArtifactList contains:
` %2:_(s32), %3:_(s32) = G_UNMERGE_VALUES %1:_(s64)`
it gets combined with
`%1:_(s64) = G_MERGE_VALUES %0:_(s32), %4:_(s32)`
we get:
%0:_(s32) = COPY $a0
%4:_(s32) = G_CONSTANT i32 0
$v0 = COPY %0(s32)
$v1 = COPY %4(s32)
RetRA implicit $v0, implicit $v1
>> We could try to implement some constant elimination once they are properly legalized.
>
> Don't we have that for free already? If something is not dead we keep it, otherwise we remove it. What am I missing?
Constant combining is probably a better term.
For example when we want to store i1 true/false, target decides if it wants it zero/sign extended to size that it specifies. Here we can combine away explicit sign/zero extend + G_CONSTANT and create appropriate constant.
I am not completely sure how to treat constants, this is just an idea.
Btw, we might want to perform combine of (-O0 in clang frontend)
%0:_(s32) = COPY $a0
%1:_(s32) = G_CONSTANT i32 2
%2:_(s32) = G_CONSTANT i32 3
%3:_(s32) = G_ADD %0, %1
%4:_(s32) = G_ADD %3, %2
into
%0:_(s32) = COPY $a0
%5:_(s32) = G_CONSTANT i32 5
%6:_(s32) = G_ADD %0, %5
There are passes in middle-end that perform this kind of optimization so we might want to skip this.
On the other hand SDAG can perform this kind of optimization.
Repository:
rL LLVM
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D59339/new/
https://reviews.llvm.org/D59339
More information about the llvm-commits
mailing list