The specific case of interest I ran into was:
sil-extract(struct(string_literal[2]))
which using the old logic would fail since we would be trying to replace all
sil-extract arguments with string_literal arguments. The different result arity
would then hit an assertion.
Swift SVN r11607
simplifyInstruction does not use the builder implying that if we successfully
simplify the instruction and continue, we will have initialized the builder for
nothing.
Swift SVN r10759
I am preparing an additional patch after this that gives the user the option of
just replacing the ith result of the instruction with the jth result of the
value type. Only the users of the ith result of the instruction in that method
will be added to the worklist.
Swift SVN r10755
This reapplies commit r10605 with the relevant fixes. The specific bug
had to do with the original code inserting the new
load/struct_element_addr at the struct_extract instead of at the load
instruction. As an example of this consider the following:
%y = (load %x)
(do_stuff)
(struct_extract %y #vardecl)
if (do_stuff) modifies the memory at %x that aliases what we would be
extracting from %y, then transforming the code to:
(do_stuff)
%y = (struct_element_addr %x #vardecl)
(load %y)
would yield an incorrect value. This patch changes the transformation so that we
perform the following transformation instead:
%y = (struct_element_addr %x #vardecl)
(load %y)
(do_stuff)
which will resolve the issue.
This peephole triggers 365 times in the stdlib.
Swift SVN r10619
This peephole transforms struct_extract of a load into a load of a
struct_element_addr. This eliminates unnecessary creation of a non-trivial
non-reference counted types and additionally reduces the size of loads.
An example of this from RC4 is:
%24 = struct_element_addr %1 : $*RC4, #State // user: %25
%25 = struct_element_addr %24 : $*Slice<UInt8>, #count // user: %26
%26 = load %25 : $*Int64 // user: %29
...
%29 = struct_extract %26 : $Int64, #value // user: %30
%30 = apply %28(%29, %27) : $@thin (Builtin.Int64, Builtin.Int64) -> %Builtin.Int1 // user: %33
In this case there is no use of the load besides the struct_extract. This
becomes even more interesting when the type one is attempting to retrieve from
the non-trivial non-reference counted type is reference counted itself.
Swift SVN r10605
tuple-producing results (like those produced by folding overflow builtins).
Before the pass would just RAUW the apply_inst with a tuple_inst, but this
would leave around a bunch of tuple extracts. Now we seek and destroy them.
This unblocks other transformations and allows the stdlib to shrink by another
1700 LOC.
Swift SVN r9900
clean up a couple random things in silcombiner:
- it shouldn't return "made any changes" out of the pass.
- statistics should be spelled out more and don't end with periods.
Swift SVN r9755
There are no values other than instructions that can use other values. BBArguments are
defs, not uses. This eliminates a bunch of casts in clients that use getUser().
Swift SVN r9701
This pass is a port of InstCombine from LLVM to SIL. Thus if you are familiar
with the code from InstCombine you will feel right at home.
Keep in mind that in order to help with review, this is just a skeleton with no
optimizations in it besides a simple DCE based off of isInstructionTriviallyDead
(which this patch exposes in Local.h like LLVM does) to ensure that trivial
testing of the pass can be accomplished since otherwise it would do nothing
implying that no tests could be written at all.
I additionally modified one test which no longer passed due to SILCombine
removing 1x unused metatype instruction from the standard library.
Swift SVN r9404