tag things known from SILGen to be initializers (e.g., copyaddrs with
the bit set) and when we analyze the DI properties for an assign, we
can move it to this classification. This allows stuff that wants to
reason about the difference (e.g. the conditional destroy logic) to
do so precisely.
Swift SVN r10658
logic for destroy_addrs of memory that is only live on some
paths. This finally wraps up rdar://15209088.
The final missing DI feature for local/global variables is the
conditional "assign" vs "init" case now.
Swift SVN r10654
each element has a known yes/no liveness, as a generalization of the
"none are alive" logic. Now the only piece missing is the
flow sensitive liveness case.
It is pretty nice that DI is able to transform the testcase into this
simple logic:
sil @release_some_constructed : $@thin () -> () {
bb0:
%0 = tuple ()
%1 = function_ref @getSomeClass : $@thin () -> @owned SomeClass // user: %2
%2 = apply %1() : $@thin () -> @owned SomeClass // user: %3
strong_release %2 : $SomeClass // id: %3
%4 = tuple () // user: %5
return %4 : $() // id: %5
}
Swift SVN r10629
into two methods: one that determines the liveness of a set of
elements at a point in the CFG, and one the merges the result
across the elements used by a particular access. The
getLivenessAtUse is useful for traditional DI properties, but
the vector-returning one is important for analyzing the liveness
at a release. Still no functionality change.
Swift SVN r10625
that wraps llvm::SmallVector of bit pairs - centralizing the logic
for working on it, and abstracting the bit pair encoding. Also
add a comment describing what this is doing in lattice theoretic
terms.
Swift SVN r10624
This fixes up various testcases. Note that 3 debug info tests are asserting
in IRGen for a common but unknown-to-me reason, I've XFAILed them for now.
Swift SVN r10613
Doing this exposed that the dataflow analysis in DI was pretty fundamentaly broken:
it was trying to compute blocks where the (tuple elements of the) memory were either
initialized, uninitialized, or partially initialized (initialized only on some paths)
but it conflated partial with its unknown state, causing it to get the wrong results
a lot of the time. Rewrite things so that it is correct.
Swift SVN r10594
loading from our current allocation, we'd sometimes add loads
corresponding to the "assign" to the use list for this memory
object.
No testcase as this will be tested by Joe's forthcoming patch
to produce more copyaddrs from silgen.
Swift SVN r10559
Fix DI to not delete non-trivial memory allocations that are still
used by destroy_addr or strong_release, since just dropping those operations
will cause a memory leak.
This is simple, but prevents DI from removing most allocations. To
avoid having to update all the testcases :), teach it also to promote
non-address-only destroy_addrs into a load+release sequence when the
load's value is available, as part of normal load promotion.
Swift SVN r10542
so they don't need code motion on releases. This fixes Jordan's testcase from
rdar://15209088, though non-trivial types still don't work.
Swift SVN r10539
instead of working a tuple-element at a time. This requires it
to use bitvectors to compute each tuple element's liveness separately.
A big part of this is introducing the new MemoryUse type, which wraps
up the tuple elements accessed by a user of the memory object in addition
to its kind, and extending the NonLoadUses set to keep an index into the
Uses map, and a lot of other things.
This wraps up:
<rdar://problem/15228619> Eliminate the notion of Element from DefiniteInitialization
Swift SVN r10520
since they are handled in a completely different way from other uses
and already had to be std::partitioned to the end anyway. They will
only become more different over time.
Swift SVN r10500
We were incorrectly treating init_existential as equivalent to a struct
access, where for DI purposes, it is much more like an enum access: a store
to the result of a (not further indexed) init_existential pointer should be
treated as a full store, not a partial store.
Swift SVN r9933
functions. Before it would only delete them once they got inlined,
which is a waste of compile time and serves no purpose.
This exposed a bug in mandatory inlining, which is now fixed. It
strinks the stdlib by 4500 lines, almost 10%.
Swift SVN r9906
- Introduce emitTupleExtract / emitStructExtract, which fold when their operand is a tuple/struct.
- Rename SILBuilder::createTupleExtractInst -> createTupleExtract, "Inst" isn't used as a suffix.
- Switch capture promotion and DI to use the new functions.
This trims 300 lines out of the stdlib.
Swift SVN r9897
in transparent functions. They will be deleted anyway when they get inlined
into callers, so there is no reason to do the work to carry them around and
inline them, only to delete them.
This shrinks the sil for the stdlib by about 5%: from 71672 lines to 67718 lines.
Swift SVN r9818
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
us to diagnose things that span multiple blocks, e.g.:
var xu8_3 : UInt8 = 240 // Global (cross block) analysis.
for i in 0..10 {}
xu8_3 += 40 // expected-error {{arithmetic operation '240 + 40' (on type 'UInt8') results in an overflow}}
This doesn't do full SSA construction in that it won't generate "phi" nodes, but will promote any loads that can be substituted with a (potentially field sensitive and decomposed) single value. Given that no diagnostics passes are going to be looking through BB args anyway, this seems like the right level of sophistication for definite init.
Swift SVN r9523
exploding them on demand. This finally resolves rdar://15170149,
which allows a bunch of tests in SILPasses/constant_propagation.swift
to work.
Swift SVN r9346
- Enhance the driver of definite initialization to scalarize copyaddrs
that span multiple tuple elements so that DI can only thing of a single
element at a time (when it comes to copy_addrs - inout and escapes can
span anything of course)
- Teach load eliminate to explode copyaddrs into its components when
doing so would allow eliminating a load.
- Fix a bug where indexing into a tuple inside an enum could cause
accesses to be attributed to the wrong element, which manifested
as a crash on the testsuite now that DI is being more aggressive.
Unfortunately, DI is now exploding some copyaddrs that feed inout shadows,
disabling the inout shadow optimization on something important for
stdlib/String.swift. This is a regression, but is less important than
unblocking work dependent on rdar://15170149, so I'm just dialing back
the testcase and tracking this with rdar://15228172.
Swift SVN r9345
Previously, the definite init pass would check to see if there was a
load available to optimize out the load of a non-trivial assign. Now
we just unconditionally lower an assign to a load/copy/store sequence,
and lead later load elimination zap the load if it is redundant.
This allows us to remove the old mechanics for doing reasoning about
load elimination, including all the "AccessPath" stuff.
Swift SVN r9340
into SSA form, moving to resolving rdar://15170149.
Instead of promoting loads in the middle of the process of proving
that everything passes DI requirements, do this after a full element
is ok.
Doing this requires changing just about everything about how we modeled
elements and subelements being promoted, but this is good for a lot of
reasons:
1) we now don't eagerly scalarize all loads to struct members, now we
just scalarize top-level tuples. This is good for preserving higher
level operations.
2) Even without scalarization, we can still model things at an extremely
fine grain, but we can also keep aggregate operations together.
This means that load promotion doesn't insert a kajillion
struct_extract + struct sequences to decompose then recompose things.
This is just patch #1 of a series, but this is the bulk of the hard work.
Swift SVN r9338
set. This is the last fix required to get copy_addr to forward to the
load in this trivial example from rdar://15170149:
func testTrivial(a : @inout Int) -> Int {
return a
}
on to more testing.
Swift SVN r9167