self box as well as the address result, so that it picks up retains and releases.
Classify releases as interesting usepoints, and ignore the dealloc_stack.
Similarly, teach the logic in DefiniteInit's conditional destruction stuff to handle
the derived self case (basically, teaching it to special case the self box).
Swift SVN r21622
allowing partially initialized and conditionally uninitialized elements at failure points.
For example, we compile (with optimizations enabled to clean up the branching) this code:
class SomeClass {}
class RootClassWithNontrivialStoredProperties {
let x, y: SomeClass
init?(failAfterPartialInitialization: ()) {
x = SomeClass()
return nil
}
}
into:
sil @...
bb0(%0 : $RootClassWithNontrivialStoredProperties):
%1 = alloc_ref $SomeClass // users: %3, %4
%2 = ref_element_addr %0 : $RootClassWithNontrivialStoredProperties, #RootClassWithNontrivialStoredProperties.x // user: %3
store %1 to %2 : $*SomeClass // id: %3
strong_release %1 : $SomeClass // id: %4
dealloc_ref %0 : $RootClassWithNontrivialStoredProperties // id: %5
%6 = enum $Optional<RootClassWithNontrivialStoredProperties>, #Optional.None!enumelt // user: %7
return %6 : $Optional<RootClassWithNontrivialStoredProperties> // id: %7
}
where the elements of the class are all individually tracked and destroyed if necessary before the class is dealloc'd.
Swift SVN r21621
to track the release as something that needs the class reference to be alive at.
This implements the first piece of that: if all elements of the class are uninitialized
at the time of the release, just turn the release into a dealloc_ref. This is correct
because we know that the value would have had to be fully initialized at a retain, and
though careful construction, this only triggers in the init case.
This allows us to compile this:
class RootClassWithNontrivialStoredProperties {
let x, y: SomeClass
init?(failBeforeInitialization: ()) {
return nil
}
}
into:
sil @_TFC1t39RootClassWithNontrivialStoredPropertiesCfMS0_FT24failBeforeInitializationT__GSqS0__ : $@thin (@thick RootClassWithNontrivialStoredProperties.Type) -> @owned Optional<RootClassWithNontrivialStoredProperties> {
bb0(%0 : $@thick RootClassWithNontrivialStoredProperties.Type):
%1 = alloc_ref $RootClassWithNontrivialStoredProperties // user: %2
dealloc_ref %1 : $RootClassWithNontrivialStoredProperties // id: %2
%3 = enum $Optional<RootClassWithNontrivialStoredProperties>, #Optional.None!enumelt // user: %4
return %3 : $Optional<RootClassWithNontrivialStoredProperties> // id: %4
}
Swift SVN r21620
This is straight-forward, we just unique based on SourceLoc instead of by SILLocation. In cases
where there are multiple SIL Instructions that map to the same file/line/column, the SourceLoc is
a better approximation of what the user cares about.
This wouldn't be super important, except that not having it causes a QoI regression
in a patch I'm working on.
Swift SVN r21619
When DI processes a delegating initializer of an address-only value type, make sure to
mark the copy_addr as an initialization (as it was already doing for an assign
instruction) to fix a miscompilation.
The change to DIMemoryUseCollector.cpp is just to facilitate writing testcases.
Swift SVN r21478
This has two changes:
- In the case when we have an invalid source loc, DI will default to emitting diagnostics
at the enclosing function's location. This makes it more robust in general against
implicitly synthesized code.
- For this diagnostic in particular, emit a tailored message, since super.init is a commonly
synthesized thing.
Swift SVN r20104
DI has two paths for analyzing initialization state: one optimize for solving a single
fact (e.g. the state of a single non-tuple variable in a function), and one that handles
the full generality of multiple states in parallel (e.g. a tuple in a function or the
fields of a struct/class during its init method).
Unfortunately, the dataflow analysis between these two implementations drifted, and I
fixed a bug in the "N" case (rdar://16119509 back in feb) that didn't get fixed in the "1"
case. This reworks all of the dataflow to make the fact propagation more similar between
the two paths and fix the bug along the way.
Swift SVN r17343
The problem here is that the implicitly generated self.init() call is unreachable,
and DCE runs after DI, so DI doesn't know it is unreachable. Fix this by adding a trivial
reachability check before emitting a diagnostic.
This isn't a wholesome solution though, as certain infinite loops and other scenarios that
rely on constant folding won't be handled properly. If anyone runs into this, we could consider
moving constant prop and DCE earlier, though that comes with its own tradeoffs.
Swift SVN r16898
These bits are orthogonal to each other, so combine them into one, and diagnose attempts to produce a type that's both. Spot-fix a bunch of places this revealed by inspection that we would have crashed in SILGen or IRGen if blocks were be handled.
Swift SVN r16088
property in a base class before calling super.init. This is a nice improvement,
and also avoids regressing on QoI when a patch I'm working on finally lands.
Swift SVN r15379
This is a problem whereby the parallel bitvector dataflow stuff in DI was
incorrectly caching speculated results in cycles. In principle, this algorithm
should be reworked to use standard oldschool RPO bitwise dataflow algorithms, but
this patch is a minimal fix and the performance of this code is unlikely to be an issue
anyway.
Swift SVN r14322
There are some straggling references to the context generic param list, but nothing uses the non-interface param or result types anymore!
Swift SVN r13725
Now the pass does not need to know about the pass manager. We also don't have
runOnFunction or runOnModule anymore because the trnasformation knows
which module it is processing. The Pass itself knows how to invalidate the
analysis, based on the injected pass manager that is internal to the
transformation.
Now our DCE transformation looks like this:
class DCE : public SILModuleTransform {
void run() {
performSILDeadCodeElimination(getModule());
invalidateAnalysis(SILAnalysis::InvalidationKind::All);
}
};
Swift SVN r13598
Have SILGen mark all variables bound from pattern bindings without initializers (and *only* ones without initializers) with mark_uninitialized [var] pseudo instructions. On the DI end, *only* consider mark_uninitialized instructions for DI analysis. This has many benefits:
- DI doesn't waste time analyzing locals that are trivially initialized in the original source code.
- DI doesn't try to mangle canonical SIL that has been inlined from transparent functions, which may have been optimized into a form DI isn't written to understand.
While we're here, fix an issue with DCE where it would try to kill unused MarkUninitialized instructions. Although MarkUninitialized has no side effects, it still is semantically important to raw SIL, and can't be killed.
Chris did most of the work here; I just finished updating tests and fixing bugs.
Swift SVN r13247
Lower types for SILDeclRefs from the interface types of their referents, dragging the old type along for the ride so we can still offer the context to clients that haven't been weaned off of it. Make SILFunctionType's interface types and generic signature independent arguments of its Derive the context types of SILFunctionType from the interface types, instead of the other way around. Do a bunch of annoying inseparable work in the AST and IRGen to accommodate the switchover.
Swift SVN r12536
Thanks to the way we've set up our diagnostics engine, there's not actually
a reason for /everything/ to get rebuilt when /one/ diagnostic changes.
I've split them up into five categories for now: Parse, Sema, SIL, IRGen,
and Frontend, plus a set of "Common" diagnostics that are used in multiple
areas of the compiler. We can massage this later.
No functionality change, but should speed up compile times!
Swift SVN r12438
When we decide to emit a separate ivar initializer method (via the
Objective-C entry point -.cxx_construct), we no longer initialize the
ivars within the initializer. This only happens for derived classes,
so teach DI about uninitialized 'self' values that require a
super.init call but don't require the ivars to be initialized.
Swift SVN r12240
Builtin.addressof on an uninitialized variable. Before:
t.swift:12:26: error: variable 'self.z' captured by a closure before being initialized
p = UnsafePointer<Y>(Builtin.addressof(&z))
^
After:
t.swift:12:26: error: address of variable 'self.z' taken before it is initialized
p = UnsafePointer<Y>(Builtin.addressof(&z))
^
This resolves rdar://15699057.
Swift SVN r11482
diagnose failure to initialize with:
"return from enum initializer method without storing to 'self'"
instead of:
"variable 'self' used before being initialized"
For partially initialized super.init() calls, emit:
"super.init not called on all paths leading to use of base object 'SomeClass'"
instead of:
"use of base object 'SomeClass' before super.init call to initializes it on some paths"
... which didn't make any sense.
Swift SVN r11075
This builds on the infrastructure we have for liveness tracking, by tracking
the "super.init'd" state as another faux memory object that has a liveness.
Each escape/base class use requires super.init to have happened, and super.init
requires super.init to NOT have happened. This gives us pretty great QoI,
full fidelity to the model, and is pretty simple.
This implements:
<rdar://problem/15579247> We need to validate super.init() invariants in initializers
Swift SVN r11073
that attempted to detect whether there was an explicit init in the body.
DI takes care of this now. It also removes the logic for generating code
to default init ivars.
Swift SVN r11044
of this diagnostic still doesn't make sense (pointing the the { of the function) but that
is tracked by rdar://15581664.
t.swift:4:3: error: instance variable 'self.x' not initialized at end of initializer
init() {
^
Swift SVN r11042
t.swift:10:5: error: instance variable 'self.y' not initialized at super.init call
super.init()
^
<unknown>:0: note: variable defined here
t.swift:15:5: error: use of base object 'SomeClass' before super.init call initializes it
x = 17
^
instead of:
variable 'self.y' captured by a closure before being initialized
for each of them. <unknown> is in the crosshairs next.
Swift SVN r11036
global "partial liveness" would overwrite local "always live"ness.
Always liveness on a local level always makes a value live-out,
even if it is partially live in.
Swift SVN r11005