Commit Graph

94 Commits

Author SHA1 Message Date
Michael Gottesman
e1a616f1d4 Merge pull request #35198 from gottesmm/pr-0d922ed7f7078d21e2bbfc5273730703a61d7c08
[sil-combine] Update RefToRawPointer simplifications for ossa.
2020-12-22 21:28:24 -08:00
Michael Gottesman
0d2047a359 [sil-combine] Update RefToRawPointer simplifications for ossa.
These are always safe in OSSA since what we are doing here is hoisting the
ref_to_raw_pointer up the def-use chain without deleting any instructions unless
we know that they do not have any uses (in a strict sense so destroy_value is
considered a use). E.x.:

```
%0 = ...
%1 = unchecked_ref_cast %0
%2 = ref_to_raw_pointer %1
```

->

```
%0 = ...
%1 = unchecked_ref_cast %0
%2 = ref_to_raw_pointer %0
```

Notice, how we are actually not changing %1 at all. Instead we are just moving
an instantaneous use earlier. One thing that is important to realize is that
this /does/ cause us to need to put the ref_to_raw_pointer at the insert
location of %0 since %0's lifetime ends at the unchecked_ref_cast if the value
is owned.

NOTE: I also identified the tests from sil_combine.sil that had to do with these
simplifications and extracted them into sil_combine_casts.sil and did the
ossa/non-ossa tests side by side. I am trying to fix up the SILCombine tests as
I update stuff, so if I find opportunities to move tests into a more descriptive
sub-file, I am going to do so.

As an aside, to make it easier to transition SILCombine away from using a
central builder, I added a withBuilder method that creates a new SILBuilder at a
requested insertPt and uses the same context as the main builder of
SILCombine. It also through the usage of auto makes really concise pieces of
code. Today to do this just using builder, we would do:

```
SILBuilderWithScope builder(insertPt, Builder);
builder.createInst1(insertPt->getLoc(), ...);
builder.createInst2(insertPt->getLoc(), ...);
builder.createInst3(insertPt->getLoc(), ...);
auto *finalValue = builder.createInst4(insertPt->getLoc(), ...);
```

Thats a lot of typing and wastes a really commonly used temp name (builder) in
the local scope! Instead, using this API, one can write:

auto *finalValue = withBuilder(insertPt, [&](auto &b, auto l) {
  b.createInst1(l, ...);
  b.createInst2(l, ...);
  b.createInst3(l, ...);
  return b.createInst4(l, ...);
});

There is significantly less to type and auto handles the types for us. The
withBuilder construct is just syntactic since we always inline it.
2020-12-22 17:25:47 -08:00
Michael Gottesman
6f3e88013e [sil-combine] Update unchecked_ref_cast_addr -> unchecked_ref_cast given loadable types for OSSA.
This involves just performing a load [take] + unchecked_ref_cast + store [init].

The test is ported from sil_combine_cast_foldings.sil
2020-12-22 16:34:43 -08:00
Michael Gottesman
5720d30c9a [sil-combine] Enable convert_escape_to_no_escape -> thin_to_thick_function for ossa.
Also begin a test file for casts specifically.
2020-12-21 13:10:40 -08:00
Meghana Gupta
06eaf6bba4 Disable SILCombine of unchecked_bitwise_cast to unchecked_ref_cast in OSSA
unchecked_ref_cast is a forwarding cast while unchecked_bitwise_cast is
not. We cannot just convert one to other in OSSA. Disable it now.
2020-10-20 20:44:59 -07:00
Erik Eckstein
662f03ec4c SILCombine: optimize casts of existential boxes.
Optimize the unconditional_checked_cast_addr in this pattern:

   %box = alloc_existential_box $Error, $ConcreteError
   %a = project_existential_box $ConcreteError in %b : $Error
   store %value to %a : $*ConcreteError
   %err = alloc_stack $Error
   store %box to %err : $*Error
   %dest = alloc_stack $ConcreteError
   unconditional_checked_cast_addr Error in %err : $*Error to ConcreteError in %dest : $*ConcreteError

to:
   ...
   retain_value %value : $ConcreteError
   destroy_addr %err : $*Error
   store %value to %dest $*ConcreteError

This lets the alloc_existential_box become dead and it can be removed in following optimizations.
The same optimization is also done for conditional_checked_cast_addr.

There is also an implication for debugging:
Each "throw" in the code calls the runtime function swift_willThrow. The function is used by the debugger to set a breakpoint and also add hooks.
This optimization can completely eliminate a "throw", including the runtime call.
So, with optimized code, the user might not see the program to break at a throw, whereas in the source code it is actually throwing.
On the other hand, eliminating the existential box is a significant performance win and we don't guarantee any debugging behavior for optimized code anyway. So I think this is a reasonable trade-off.
I added an option "-Xllvm -keep-will-throw-call" to keep the runtime call which can be used if someone want's to reliably break on "throw" in optimized builds.

rdar://problem/66055678
2020-07-29 21:57:51 +02:00
Erik Eckstein
01465d9ba4 SILCombine: Remove a cast if it's only used by an end_cow_mutation.
(end_cow_mutation (upcast X)) -> (end_cow_mutation X)
(end_cow_mutation (unchecked_ref_cast X)) -> (end_cow_mutation X)
2020-05-26 18:01:17 +02:00
Meghana Gupta
96b774f2e5 Recommit #31595 with fixes (#31732)
Add new pattern in SILCombine to optimize redundant thick to objc metatype conversions

Add pattern to catch the following redundant conversion:

%tmp1 = thick_to_objc_metatype %x
%tmp2 = objc_to_thick_metatype %tmp1
...
%tmp3 = <sil operation> %tmp2

to:

%tmp3 = <sil operation> %x

Similarly add pattern for redundant conversion of objc_to_thick_metatype
followed by thick_to_objc_metatype.

Fixes rdar://62932799
2020-05-12 16:26:30 -07:00
Arnold Schwaighofer
7ce30d7fd0 Revert "Add new pattern in SILCombine to optimize redundant thick to objc metatype conversions (#31595)"
This reverts commit 488333c4a2.

It looks like this might have caused a heap-use-after free on an asan
bot.

rdar://63135437
2020-05-12 07:07:53 -07:00
Meghana Gupta
488333c4a2 Add new pattern in SILCombine to optimize redundant thick to objc metatype conversions (#31595)
Add pattern to catch the following redundant conversion:

%tmp1 = thick_to_objc_metatype %x
%tmp2 = objc_to_thick_metatype %tmp1
...
%tmp3 = <sil operation> %tmp2

to:

%tmp3 = <sil operation> %x

Similarly add pattern for redundant conversion of objc_to_thick_metatype
followed by thick_to_objc_metatype.

Fixes rdar://62932799
2020-05-12 01:08:19 -07:00
zoecarver
d3a01131d7 Update all relevant visitors in SILCombine to skip ownership functions.
Instead of bailing on ownership functions in SILCombine::run, we will
bail in individual visitors. This way, as SILCombine is updated we can
paritially support ownership across the pass.
2020-03-24 19:55:08 -07:00
Joe Groff
96a5d2cae0 SILCombiner: Recognize convert_function patterns that only change substitutions
We can eliminate `convert_function`s that are immediately used as the callee of
an `apply` or `partial_apply`, as well as stacked `convert_function`s that may
arise from this transformation.
2020-02-24 12:14:21 -08:00
Slava Pestov
3997aa5754 SIL: Remove SILBuilder::tryCreateUncheckedRefCast() 2020-01-03 15:37:19 -05:00
Michael Gottesman
df6d25fa8a [gardening] Be more defensive around a potentially uninitialized Store by initializing it to nullptr and asserting that it is not nullptr (i.e. was assigned) before using it. 2019-12-18 13:54:11 -08:00
Andrew Trick
bddc69c8a6 Organize SILOptimizer/Utils headers. Remove Local.h.
The XXOptUtils.h convention is already established and parallels
the SIL/XXUtils convention.

New:
- InstOptUtils.h
- CFGOptUtils.h
- BasicBlockOptUtils.h
- ValueLifetime.h

Removed:
- Local.h
- Two conflicting CFG.h files

This reorganization is helpful before I introduce more
utilities for block cloning similar to SinkAddressProjections.

Move the control flow utilies out of Local.h, which was an
unreadable, unprincipled mess. Rename it to InstOptUtils.h, and
confine it to small APIs for working with individual instructions.
These are the optimizer's additions to /SIL/InstUtils.h.

Rename CFG.h to CFGOptUtils.h and remove the one in /Analysis. Now
there is only SIL/CFG.h, resolving the naming conflict within the
swift project (this has always been a problem for source tools). Limit
this header to low-level APIs for working with branches and CFG edges.

Add BasicBlockOptUtils.h for block level transforms (it makes me sad
that I can't use BBOptUtils.h, but SIL already has
BasicBlockUtils.h). These are larger APIs for cloning or removing
whole blocks.
2019-10-02 11:34:54 -07:00
Michael Gottesman
9c58e4b0a3 [patternmatch] Add InstructionOperand_match to support for matching against instructions with misc number of operands.
NOTE:

1. To test this I changed UnaryOp_match to use this under the hood.

2. These types of m_##ID##Inst matchers now will only accept compound types and
I added a static assert to verify that this mistake doesn't happen. We
previously had matchers that would take an int or the like to match tuple
extract patterns. I converted those to use TupleExtractOperation that also
properly handles destructures.
2019-08-05 17:26:02 -07:00
Slava Pestov
16d5716e71 SIL: Use the best resilience expansion when lowering types
This is a large patch; I couldn't split it up further while still
keeping things working. There are four things being changed at
once here:

- Places that call SILType::isAddressOnly()/isLoadable() now call
  the SILFunction overload and not the SILModule one.

- SILFunction's overloads of getTypeLowering() and getLoweredType()
  now pass the function's resilience expansion down, instead of
  hardcoding ResilienceExpansion::Minimal.

- Various other places with '// FIXME: Expansion' now use a better
  resilience expansion.

- A few tests were updated to reflect SILGen's improved code
  generation, and some new tests are added to cover more code paths
  that previously were uncovered and only manifested themselves as
  standard library build failures while I was working on this change.
2019-04-26 22:47:59 -04:00
Slava Pestov
8915f96e3e SIL: Replace SILType::isTrivial(SILModule) with isTrivial(SILFunction) 2019-03-12 01:16:04 -04:00
Slava Pestov
903721cdc5 SIL: Remove SILType::getMetatypeInstanceType() 2019-03-01 02:07:16 -05:00
Andrew Trick
65c95dd840 Fix SILCombine metatype cast optimization to avoid extending lifetimes.
This cannot be correctly done as a SILCombine because it must create
new instructions at a previous location. Move the optimization into
CastOptimizer. Insert the new metatype instructions in the correct
spot. And manually do the replaceAllUsesWith and eraseInstruction
steps.

Fixes <rdar://problem/46746188> crash in swift_getObjCClassFromObject.
2018-12-21 09:52:38 -08:00
Slava Pestov
e85b68e151 SILOptimizer: Remove unused variable 2018-05-09 22:49:36 -04:00
Erik Eckstein
df6a3af5a5 SILCombine: remove a problematic cast peephole optimization.
This optimization inserted bit casts based on structural properties of types.
It caused a miscompile in case of imported C structs. Also, by inspection, I found that checks for resilient types are missing.
As this optimization does not have any noticeable impact on the benchmarks it's better to remove it at all, together with the complexity for checking the types.

rdar://problem/40074362
2018-05-09 13:28:20 -07:00
Arnold Schwaighofer
a05f0398a1 SILCombiner: Fixes for convert_escape_to_noescape
- also combine thin_to_thick_function and convert_escape_to_noescape
2018-02-13 04:19:59 -08:00
Andrew Trick
abedb192bc Rename canUnsafeCastValue to checkABIForUnsafeScalarCast and comment.
This is an ABI-dependent routine, so at least should have ABI in the name.  In
the future, the compiler may introduce new ABI layout rules for select types
based on the deployment target. Code like this needs to be reviewed at that time.

Clarify the comments.
2018-01-08 14:17:36 -08:00
Chris Lattner
415cd50ba2 Reduce array abstraction on apple platforms dealing with literals (#13665)
* Reduce array abstraction on apple platforms dealing with literals

Part of the ongoing quest to reduce swift array literal abstraction
penalties: make the SIL optimizer able to eliminate bridging overhead
 when dealing with array literals.

Introduce a new classify_bridge_object SIL instruction to handle the
logic of extracting platform specific bits from a Builtin.BridgeObject
value that indicate whether it contains a ObjC tagged pointer object,
or a normal ObjC object. This allows the SIL optimizer to eliminate
these, which allows constant folding a ton of code. On the example
added to test/SILOptimizer/static_arrays.swift, this results in 4x
less SIL code, and also leads to a lot more commonality between linux
and apple platform codegen when passing an array literal.

This also introduces a couple of SIL combines for patterns that occur
in the array literal passing case.
2018-01-02 15:23:48 -08:00
John McCall
ab3f77baf2 Make SILInstruction no longer a subclass of ValueBase and
introduce a common superclass, SILNode.

This is in preparation for allowing instructions to have multiple
results.  It is also a somewhat more elegant representation for
instructions that have zero results.  Instructions that are known
to have exactly one result inherit from a class, SingleValueInstruction,
that subclasses both ValueBase and SILInstruction.  Some care must be
taken when working with SILNode pointers and testing for equality;
please see the comment on SILNode for more information.

A number of SIL passes needed to be updated in order to handle this
new distinction between SIL values and SIL instructions.

Note that the SIL parser is now stricter about not trying to assign
a result value from an instruction (like 'return' or 'strong_retain')
that does not produce any.
2017-09-25 02:06:26 -04:00
John McCall
3c5de5fa0a Preserve type canonicality better in several places and
idiomatize some uses of SILType::getSwiftRValueType().
2017-03-14 14:59:43 -04:00
Joe Groff
39ecc53a25 Add a loadInvariant builtin.
Lowers to an invariant load in LLVM; probably useful for SIL too at some point too, but NFC at that level yet.
2017-03-08 21:02:03 -08:00
Slava Pestov
0611d663b8 SIL: Remove SILType::getSwiftType() 2017-02-27 20:01:35 -08:00
practicalswift
6d1ae2a39c [gardening] 2016 → 2017 2017-01-06 16:41:22 +01:00
practicalswift
797b80765f [gardening] Use the correct base URL (https://swift.org) in references to the Swift website
Remove all references to the old non-TLS enabled base URL (http://swift.org)
2016-11-20 17:36:03 +01:00
Michael Gottesman
bffa7addaf [semantic-arc] Eliminate default {Load,Store}OwnershipQualification argument to SILBuilder::create{Load,Store}(...)
Today, loads and stores are treated as having @unowned(unsafe) ownership
semantics. This leaves the user to specify ownership changes on the loaded or
stored value independently of the load/store by inserting ARC operations. With
the change to Semantic SIL, this will no longer be true. Instead loads, stores
have ownership semantics that one must reason about such as copy, take, and
trivial.

This change moves us closer to that world by eliminating the default
OwnershipQualification argument from create{Load,Store}. This means that the
compiler developer cannot ignore reasoning about the ownership semantics of the
memory operation that they are creating.

Operationally, this is a NFC change since I have just gone through the compiler
and updated all places where we create loads, stores to pass in the former
default argument ({Load,Store}OwnershipQualifier::Unqualified), to
SILBuilder::create{Load,Store}(...). For now, one can just do that in situations
where one needs to create loads/stores, but over time, I am going to tighten the
semantics up via the verifier.

rdar://28685236
2016-10-30 13:07:06 -07:00
Erik Eckstein
7c374066e6 Remove the strideof_nonzero builtin.
Because now the stride of all types is at least one, anyway.
2016-09-14 13:24:19 -07:00
Andrew Trick
c47687da2c Add an isStrict flag to SIL pointer_to_address. (#3529)
Strict aliasing only applies to memory operations that use strict
addresses. The optimizer needs to be aware of this flag. Uses of raw
addresses should not have their address substituted with a strict
address.

Also add Builtin.LoadRaw which will be used by raw pointer loads.
2016-07-15 15:04:02 -05:00
Joe Groff
77dd9b2992 Split exact-subclass and bindable-to-subclass queries.
In many places, we're interested in whether a type with archetypes *might be* a superclass of another type with the right bindings, particularly in the optimizer. Provide a separate Type::isBindableToSuperclassOf method that performs this check. Use it in the devirtualizer to fix rdar://problem/24993618. Using it might unblock other places where the optimizer is conservative, but we can fix those separately.
2016-03-09 11:14:45 -08:00
Xin Tong
92b16cde75 Remove unncessary headers 2016-02-07 13:56:12 -08:00
Erik Eckstein
74d44b74e7 SIL: remove SILValue::getDef and add a cast operator to ValueBase * as a repelacement. NFC. 2016-01-25 15:00:49 -08:00
Erik Eckstein
506ab9809f SIL: remove getTyp() from SILValue 2016-01-25 15:00:49 -08:00
Erik Eckstein
f2c0283437 Simplify DebugUtils
With the changes in SILValue there is no need for template functions in DebugUtils anymore.
2016-01-21 16:04:30 -08:00
Erik Eckstein
2db6f3d213 SIL: remove multiple result values from SILValue
As there are no instructions left which produce multiple result values, this is a NFC regarding the generated SIL and generated code.
Although this commit is large, most changes are straightforward adoptions to the changes in the ValueBase and SILValue classes.
2016-01-21 10:30:31 -08:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
practicalswift
db13bcb22e Fix typos. 2015-12-26 14:11:42 +01:00
practicalswift
1cb0c69086 Fix typo: convertions → conversions 2015-12-14 00:11:29 +01:00
Andrew Trick
739b0e9c56 Reorganize SILOptimizer directories for better discoverability.
(libraries now)

It has been generally agreed that we need to do this reorg, and now
seems like the perfect time. Some major pass reorganization is in the
works.

This does not have to be the final word on the matter. The consensus
among those working on the code is that it's much better than what we
had and a better starting point for future bike shedding.

Note that the previous organization was designed to allow separate
analysis and optimization libraries. It turns out this is an
artificial distinction and not an important goal.
2015-12-11 15:14:23 -08:00