Commit Graph

149 Commits

Author SHA1 Message Date
Erik Eckstein
c2776c455b Rename SILBasicBlock::getID() -> getDebugID()
Swift SVN r24321
2015-01-09 19:37:03 +00:00
Erik Eckstein
12b43dde74 Change the algorithm for computing the availability in DefiniteInitialization.
The old recursive algorithm had exponential complexity in worst case.
The new algorithm is a simple iterative dataflow algorithm.

This fixes <rdar://problem/19259710> Swift project locks up "indexing" or building (LifetimeChecker::doIt())

In the new algorithm I didn't specialize for the NumElements==1 case (as the old algorithm did),
because IMO it does not make a significant difference.



Swift SVN r24309
2015-01-09 17:09:10 +00:00
Chris Lattner
3a7d8df92b fix <rdar://problem/19259730> Using mutating methods in a struct initializer with a let property is rejected
while we're at it, improve the QoI for actually-invalid mutating method calls in struct initalizers.


Swift SVN r24030
2014-12-19 06:52:37 +00:00
Chris Lattner
e5bbc8988b stoop to even more grotty AST crawling to get descent diagnostics from DI.
Swift SVN r23885
2014-12-12 06:34:45 +00:00
Chris Lattner
66ab73bf69 Pour some QoI love on the DI mutation diagnostics when an inout use
happens due to a method call.


Swift SVN r23884
2014-12-12 06:19:24 +00:00
Chris Lattner
d513803d84 Sigificantly replumb how SILGen generates mark_uninitialized instructions, generating
them in a more consistent and principled way.  Two changes here: MUI is generated
when a vardecl is emitted, not as a separate "MarkPatternUninitialized" pass.  Second,
when generating a MUI for self parameters with a temporary alloc_stack (due to the
possibility of superclass remapping of self) emit the MUI on the allocation itself,
not on the incoming argument.  This is a lot more consistent (dissolving a bunch of 
hacks in DI).

In terms of behavior changes, this only changes the raw sil generated by SILGen and
consumed by DI, so there is no user-visible change.  This simply unblocks future work.



Swift SVN r23823
2014-12-10 00:29:40 +00:00
Chris Lattner
674a50df2f refactor how "getPathStringToElement" in DI works, to clean it up and simplify
clients.  NFC except for slightly better diagnostic in .sil testcases.  


Swift SVN r23809
2014-12-09 17:51:06 +00:00
Chris Lattner
cb8a65e831 Clean up the semantics of 'let' properties in a number of ways:
- We switch to a model where let properties may be "initialized", but never
  reassigned.  Specifically, immutable properties in structs/classes may have
  an init value specified in their declaration (but can then never be reset
  in any init implementation) or not (in which case they must be initialized 
  exactly once on all paths through every init.  This makes a lot more sense 
  for immutability, defines several problems away, and provides a path to
  supporting things like (rdar://16181314)

- We now *never* default initialize an immutable property.  Formerly
  we would default initialize optional let properties to nil, but this
  isn't actually useful, and allows an error of omission with let 
  properties.  

This resolves: <rdar://problem/19035287> let properties should only be initializable, not reassignable
and possibly other radars.





Swift SVN r23779
2014-12-08 20:59:53 +00:00
Ben Langmuir
e9e1666ab0 Update for upstream LLVM changes
* removal of StringMap's GetOrCreateValue
* SmallSet::insert now returns a pair like std::set

Swift SVN r23435
2014-11-19 16:49:30 +00:00
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