Commit Graph

140 Commits

Author SHA1 Message Date
Adrian Prantl
c41b30299f Audit all SILPasses to ensure that new instructions are never created
without a valid SILDebugScope. An assertion in IRGenSIL prevents future
optimizations from regressing in this regard.
Introducing SILBuilderWithScope and SILBuilderwithPostprocess to ease the
transition.

This patch is large, but mostly mechanical.
<rdar://problem/18494573> Swift: Debugger is not stopping at the set breakpoint

Swift SVN r22978
2014-10-28 01:49:11 +00:00
Joe Groff
e3f9a2035c SIL: Move SILGen and passes over to use "builtin" instead of "apply (builtin_function_ref)".
Swift SVN r22785
2014-10-15 23:37:22 +00:00
Jordan Rose
042569a3be Optional: Replace uses of Nothing with None.
llvm::Optional (like Swift.Optional!) uses None as its placeholder value,
not Nothing.

Swift SVN r22476
2014-10-02 18:51:42 +00:00
Chris Lattner
a2df9c650e reapply r22223 with a testcase update:
Dramatically improve DI diagnostics in initializers fixing rdar://18414728.

As one small example of the improvement, where an initializer like this:

class Foo {
    var path:String? {
        return "boo"
    }
    
    let aaaaa:String
    
    init() {
        if let p1 = path {

used to  produce the error: "error: variable 'self.aaaaa' used before being initialized" on path,
we now produce:

x.swift:9:21: error: use of 'self' in property access 'path' before all stored properties are initialized
        if let p1 = path {
                    ^
x.swift:6:9: note: 'self.aaaaa' not initialized
    let aaaaa:String
        ^

which is more useful.





Swift SVN r22238
2014-09-23 23:17:29 +00:00
Dmitri Hrybenko
5de6540670 Revert "Dramatically improve DI diagnostics in initializers fixing rdar://18414728."
This reverts commit r22223.

Swift SVN r22233
2014-09-23 21:52:04 +00:00
Chris Lattner
88750f6ff3 Dramatically improve DI diagnostics in initializers fixing rdar://18414728.
As one small example of the improvement, where an initializer like this:

class Foo {
    var path:String? {
        return "boo"
    }
    
    let aaaaa:String
    
    init() {
        if let p1 = path {

used to  produce the error: "error: variable 'self.aaaaa' used before being initialized" on path,
we now produce:

x.swift:9:21: error: use of 'self' in property access 'path' before all stored properties are initialized
        if let p1 = path {
                    ^
x.swift:6:9: note: 'self.aaaaa' not initialized
    let aaaaa:String
        ^

which is more useful.



Swift SVN r22223
2014-09-23 19:28:36 +00:00
Chris Lattner
160438e14e Fix <rdar://problem/18199087> DI doesn't catch use of super properties lexically inside super.init call
When analyzing a super.init call, we have several instructions involved including an upcast
to the parent type and an applyinst to call super.init.  DI was using the location of the upcast
as the point at which it modeled the super.init requirement, not at the point of the applyinst.  This
meant that code like:

 %x = upcast self to basetype
 ... stuff ...
 apply super.init(%x)

would not catch invalid uses of super in the "stuff" range, because DI thought that super.init was
called at the upcast.  Fix this by using the apply as the super.init use, not the upcast.




Swift SVN r22101
2014-09-18 21:52:11 +00:00
Chris Lattner
cc06b7d7a2 tweak the prediate that currently failure from inits where the object is partially
initialized to also cover the delegating init case.  The location info is pretty awful
on these, but it is more important that we reject these in Beta 1 than it is to be pretty.


Swift SVN r21673
2014-09-03 16:08:00 +00:00
Joe Groff
5e57dc13fe DI: Complain if an initializer 'self' is released before being fully initialized.
This raises an error for some cases we don't implement correctly yet, though not ones that require super.init or self.init delegation yet.

Swift SVN r21669
2014-09-03 04:47:31 +00:00
Chris Lattner
c16cdf656d implement support for cleaning up early returns from class initializers that
are delegating and/or derived.


Swift SVN r21623
2014-09-01 06:14:10 +00:00
Chris Lattner
ffdba8fd36 Teach the derived init class 'self' analyzer to look at the refcount result of the
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
2014-09-01 05:19:25 +00:00
Chris Lattner
f154cb1961 implement full support for partial liveness tracking of class elements in class initializers,
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
2014-09-01 04:30:42 +00:00
Chris Lattner
5425835c79 Rework handling of retain and release instructions in init methods of classes
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
2014-09-01 04:10:31 +00:00
Chris Lattner
14024ea13c fix <rdar://problem/15631987> QoI: DI emits two errors for the same problem at the same location
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
2014-09-01 03:38:02 +00:00
Chris Lattner
a1d4f47930 fix <rdar://problem/18089574> Protocol member in struct + delegating init miscompilation
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
2014-08-27 06:22:39 +00:00
Nadav Rotem
f5549dce0f A small cleanup suggested by Chris. NFC.
Swift SVN r20657
2014-07-28 23:38:12 +00:00
Nadav Rotem
a09e0d58ba DI: Handle 'assert' instructions in the SelfInit state.
rdar://17746401



Swift SVN r20646
2014-07-28 21:46:55 +00:00
Chris Lattner
d214e1a75c fix <rdar://problem/17686667> If super.init is implicitly inserted, DI diagnostics have no location info
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
2014-07-17 17:44:16 +00:00
Chris Lattner
86df649f90 Fix <rdar://problem/16797372> Bogus error: self.init called multiple times in initializer
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
2014-05-04 00:22:33 +00:00
Chris Lattner
2aa3e50343 fix <rdar://problem/16660680> QoI: fatal() in init method complains about super.init being called multiple times
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
2014-04-26 23:39:00 +00:00
Joe Groff
8adaab0233 Fold ExtInfo::isThin and ::isBlock into a "Representation" enum.
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
2014-04-09 00:37:26 +00:00
Chris Lattner
3b29fb68a8 fit in 80 columns and format more nicely :)
Swift SVN r15803
2014-04-02 16:22:45 +00:00
Chris Lattner
afea47b621 rename "destroy_value" to "release_value", part of rdar://15889208.
Swift SVN r15777
2014-04-02 05:33:52 +00:00
Chris Lattner
6051a5e9a4 improve the QoI of DI's diagnostics when calling a method or accessing a computed
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
2014-03-23 05:51:41 +00:00
Chris Lattner
001c1890e5 put all the SIL*Transform classes in anonymous namespaces, there is
no need for their symbols to be exported out of their implementation
file.


Swift SVN r14714
2014-03-06 01:49:53 +00:00
Chris Lattner
7baac64e94 fix rdar://16119509 - <unknown>:0: error: super.init called multiple times in initializer
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
2014-02-24 23:23:22 +00:00
Joe Groff
b19cfb27ea Drop the context generic params from SILFunctionType.
SILFunctionType is now 100% context free!

Swift SVN r13775
2014-02-11 04:21:20 +00:00
Joe Groff
481fbb7b91 Drop the non-interface types from SILFunctionType.
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
2014-02-09 22:39:01 +00:00
Andrew Trick
0825258b80 SIL transforms should only invalidate when things change.
-sil-print-all shows a nice readable evolution now.

Oh yeah, and we don't unnecessarilly rerun passes.

Swift SVN r13677
2014-02-08 08:20:45 +00:00
Andrew Trick
731000b4cd Added -sil-print-all and -sil-verify-all options.
Swift SVN r13662
2014-02-07 23:07:11 +00:00
Nadav Rotem
27a1a63134 Remove unneeded empty virtual destructors.
Swift SVN r13599
2014-02-06 22:24:33 +00:00
Nadav Rotem
1ef0d157ca PassManager: Inject the function/module into the Transformation.
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
2014-02-06 22:11:21 +00:00
Nadav Rotem
99b075c32a Rename SILFunctionTrans -> SILFunctionTransform
Swift SVN r13536
2014-02-06 01:32:10 +00:00
Nadav Rotem
f8c7b54d28 Delete the unused performXXX() functions.
Swift SVN r13531
2014-02-06 00:57:28 +00:00
Michael Gottesman
631f9326ab [PM] Change enum => enum class everywhere in the PM code. Additionally fix some typos.
Swift SVN r13507
2014-02-05 21:25:15 +00:00
Nadav Rotem
1df8e93bbb Convert the diagnostic methods into passes.
Swift SVN r13503
2014-02-05 20:30:49 +00:00
Joe Groff
71379f5bad SILGen: Explicitly mark uninitialized locals with mark_uninitialized, and have DI only consider mark_uninitialized storage.
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
2014-01-31 22:50:21 +00:00
Joe Groff
1f5fd1366c DefiniteInit: Assert that DI doesn't mess with copy_addrs that are already [initialization].
We should only be applying the [initialization] attribute to ambivalent copy_addrs from raw SIL.

Swift SVN r13187
2014-01-31 00:31:12 +00:00
Nadav Rotem
a07aed9d1f Change errs() -> dbgs() in a few files.
Swift SVN r12572
2014-01-20 06:36:50 +00:00
Joe Groff
0776c4b6b8 SIL: Reorient function type lowering toward interface types.
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
2014-01-18 19:42:02 +00:00
Jordan Rose
11008f0ed1 Split diagnostics out into separate files.
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
2014-01-17 00:15:12 +00:00
Doug Gregor
c6b880a9b7 Definite initialization for initializers relying on a separate ivar initializer.
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
2014-01-13 19:41:16 +00:00
Chris Lattner
22545ffe1f Stop treating escape points as definitions for liveness purposes. While it
is a cute microoptimization (given that escape points *must* be live at their
point in the CFG), it leads to worse diagnostic QoI.



Swift SVN r11985
2014-01-07 06:20:36 +00:00
Chris Lattner
95d05b6b2f emit a custom diagnostics from DI when some path forgets to call self.init
in a delegating initializer.


Swift SVN r11984
2014-01-07 06:13:38 +00:00
Chris Lattner
408011ae59 Implement silgen and DI support for delegating initializers
in value types.


Swift SVN r11982
2014-01-07 06:04:59 +00:00
Chris Lattner
3a970678a1 implement definite initialization enforcement for delegating class
initializers.


Swift SVN r11980
2014-01-07 05:31:33 +00:00
Chris Lattner
40d8536d20 fix a nasty iterator invalidation problem exposed by a patch
Joe is working on.


Swift SVN r11820
2014-01-02 18:37:02 +00:00
Chris Lattner
6fc4d292d6 don't verify each function twice in DI anymore now that DI is stabilized.
If someone passes -debug to the compiler, we still do the check.


Swift SVN r11732
2013-12-30 06:44:33 +00:00
Chris Lattner
23564a20b8 special case a diagnostic to produce a more sensible message when using
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
2013-12-19 21:32:15 +00:00
Chris Lattner
7c41f9e2d7 more diagnostic QoI improvements, refer to properties, not ivars.
Swift SVN r11094
2013-12-10 21:29:04 +00:00