Commit Graph

2202 Commits

Author SHA1 Message Date
Xin Tong
57e2bdb123 Revert "Simplify function signature optimization" 2016-04-25 16:33:17 -07:00
Xin Tong
633ca2e92b Simplify function signature optimzation.
Several functionalities have been added to FSO over time and the logic has become
muddled.

We were always looking at a static image of the SIL and try to reason about what kind of
function signature related optimizations we can do.

This can easily lead to muddled logic. e.g. we need to consider 2 different function
signature optimizations together instead of independently.

Split 1 single function to do all sorts of different analyses in FSO into several
small transformations, each of which does a specific job. After every analysis, we produce
a new function and eventually we collapse all intermediate thunks to in a single thunk.

With this change, it will be easier to implement function signature optimization as now
we can do them independently now.

Minimal modifications to the test cases.
2016-04-25 15:28:51 -07:00
Slava Pestov
2e52338d7c SIL: Rename long form of getOrCreateFunction() to createFunction(), NFC
This made call sites confusing to read because it doesn't actually
check if the function already exists.

Also fix some minor formatting issues. This came up while I was working
on a fix for a bug that turned out to not be a bug.
2016-04-21 17:58:10 -07:00
practicalswift
c760f6dfbf [gardening] Add whitespace: "foo,bar" → "foo, bar" 2016-04-12 22:31:46 +02:00
Slava Pestov
d8e1e2e289 SILOptimizer: Fixes for non-fragile references in fragile functions
Two fixes to optimization passes to maintain restrictions about what
[fragile] functions can reference:

- When devirtualizing witness methods, don't devirtualize if the caller
  is fragile and the callee is not. This matches existing logic in
  class devirtualization.

- When performing generic or function signature specialization, don't
  specialize non-fragile functions referenced from fragile functions.

Since @_transparent functions are allowed to call 'static inline'
imported functions, also be sure to mark the foreign-to-native thunk
for such a function as [fragile].

With this patch, the standard library and performance test suite
now build with -enable-resilience.

No new tests for this stuff here -- the existing tests together
with an -enable-resilience build provide coverage.

Closes out <https://bugs.swift.org/browse/SR-267> and
<https://bugs.swift.org/browse/SR-268>.
2016-04-08 02:14:33 -07:00
Slava Pestov
370b16b22a SIL: Better verifier check for references from fragile functions 2016-04-08 02:10:31 -07:00
Slava Pestov
5aa99fa346 SILOptimizer: Create non-[fragile] specializations of [fragile] functions where possible
Change the optimizer to only make specializations [fragile] if both the
original callee is [fragile] *and* the caller is [fragile].

Otherwise, the specialized callee might be [fragile] even if it is never
called from a [fragile] function, which inhibits the optimizer from
devirtualizing calls inside the specialization.

This opens up some missed optimization opportunities in the performance
inliner and devirtualization, which currently reject fragile->non-fragile
references:

TEST                                                    | OLD_MIN | NEW_MIN | DELTA (%) | SPEEDUP
---                                                     | ---     | ---     | ---       | ---
DictionaryRemoveOfObjects                               | 38391   | 35859   | -6.6%     | **1.07x**
Hanoi                                                   | 5853    | 5288    | -9.7%     | **1.11x**
Phonebook                                               | 18287   | 14988   | -18.0%    | **1.22x**
SetExclusiveOr_OfObjects                                | 20001   | 15906   | -20.5%    | **1.26x**
SetUnion_OfObjects                                      | 16490   | 12370   | -25.0%    | **1.33x**

Right now, passes other than performance inlining and devirtualization
of class methods are not checking invariants on [fragile] functions
at all, which was incorrect; as part of the work on building the
standard library with -enable-resilience, I added these checks, which
regressed performance with resilience disabled. This patch makes up for
these regressions.

Furthermore, once SIL type lowering is aware of resilience, this will
allow the stack promotion pass to make further optimizations after
specializing [fragile] callees.
2016-04-08 02:10:31 -07:00
swiftix
baf8e7d7cb Merge pull request #2067 from swiftix/SR-249
Add [nonatomic] attribute to all SIL reference counting instructions.

Support this attribute at SIL level,  IRGen and LLVM-based ARC passes.
2016-04-06 23:56:43 -07:00
John McCall
b384f5ef88 Provide isAnyClassReferenceType() on SILType. 2016-04-06 19:10:02 -07:00
Erik Eckstein
f2036fc836 SIL: remove unused function removeFromParent from SILBasicBlock.
This function does not make sense anyway because there is no way to re-insert a removed block into a function again.
2016-04-06 14:55:47 -07:00
Roman Levenstein
2e77b3990b Add [nonatomic] attribute to all SIL reference counting instructions. 2016-04-06 01:52:43 -07:00
practicalswift
abfecfde17 [gardening] if ([space]…[space]) → if (…), for(…) → for (…), while(…) → while (…), [[space]x, y[space]] → [x, y] 2016-04-04 16:22:11 +02:00
Slava Pestov
3e12eccb56 SIL: Fix miscompiles with @effects(readonly) functions that have indirect results
When resilience is enabled, some functions in the standard library that
are marked @effects(readonly) now have indirect results.

The SILCombiner pass doesn't handle @effects(readonly) with @out results
correctly, so just disable the optimizations temporarily to avoid a
mis-compile when resilience is enabled.

The LLVM readonly attribute can never be applied to such functions, so
don't set it either.

Should not have an effect when resilience is disabled.
2016-04-04 00:05:01 -07:00
Erik Eckstein
b41d3a3849 Convert an if to an exhaustive switch. NFC 2016-03-31 19:25:23 -07:00
Erik Eckstein
fd3f343dab SIL: add a utility function to check if a terminator exits a function. NFC 2016-03-31 09:29:15 -07:00
Slava Pestov
b49a4525c3 SIL: Only give type metadata public linkage if -sil-serialize-all is on
Otherwise, any types referenced from transparent functions must be
public or @_versioned.
2016-03-28 14:14:50 -07:00
Slava Pestov
a9cbab70a7 SIL: Move getLinkageForProtocolConformance() to SIL.cpp, NFC 2016-03-28 13:24:21 -07:00
Slava Pestov
a9ad760b78 SIL: Clean up duplicated "can be referenced from a fragile function" checks 2016-03-25 22:46:50 -07:00
Michael Ilseman
8759905351 Merge remote-tracking branch 'origin' into import-as-member 2016-03-24 11:37:36 -07:00
Slava Pestov
3e2d7d40e0 SIL: Serialize bodies of local functions inside @_transparent functions
A transparent function might be deserialized and inlined into a function
in another module, which would cause problems if the function referenced
local functions.

Previously we would force local functions to have public linkage instead,
which worked, but was not resilient if the body of the transparent
function changed in the module that contained it.

Add a library evolution test ensuring that such a change is resilient
now.

Part of https://bugs.swift.org/browse/SR-267.
2016-03-24 00:50:39 -07:00
Michael Ilseman
47e73ad4f1 Merge branch 'master' of github.com:apple/swift into import-as-member 2016-03-23 17:01:47 -07:00
Michael Ilseman
7867533f2c Merge commit 'b894798e461077b30a3aa4afe89639f312f44858' into import-as-member 2016-03-23 15:40:04 -07:00
Michael Ilseman
1f8e887c7e Merge commit '38ceced77984188b25af9673ea61b28dc4c90b60' into import-as-member 2016-03-23 14:30:48 -07:00
Michael Ilseman
d7581d1b36 Merge commit 'a31edf53d0580efe47f4e9ef89dccc4429c056e8' into import-as-member 2016-03-23 13:05:57 -07:00
Andrew Trick
482b264afc Reapply "Merge pull request #1725 from atrick/specialize"
This was mistakenly reverted in an attempt to fix buildbots.
Unfortunately it's now smashed into one commit.

---
Introduce @_specialize(<type list>) internal attribute.

This attribute can be attached to generic functions. The attribute's
arguments must be a list of concrete types to be substituted in the
function's generic signature. Any number of specializations may be
associated with a generic function.

This attribute provides a hint to the compiler. At -O, the compiler
will generate the specified specializations and emit calls to the
specialized code in the original generic function guarded by type
checks.

The current attribute is designed to be an internal tool for
performance experimentation. It does not affect the language or
API. This work may be extended in the future to add user-visible
attributes that do provide API guarantees and/or direct dispatch to
specialized code.

This attribute works on any generic function: a freestanding function
with generic type parameters, a nongeneric method declared in a
generic class, a generic method in a nongeneric class or a generic
method in a generic class. A function's generic signature is a
concatenation of the generic context and the function's own generic
type parameters.

e.g.

struct S<T> {
var x: T
@_specialize(Int, Float)
mutating func exchangeSecond<U>(u: U, _ t: T) -> (U, T) {
x = t
return (u, x)
}
}
// Substitutes: <T, U> with <Int, Float> producing:
// S<Int>::exchangeSecond<Float>(u: Float, t: Int) -> (Float, Int)

---
[SILOptimizer] Introduce an eager-specializer pass.

This pass finds generic functions with @_specialized attributes and
generates specialized code for the attribute's concrete types. It
inserts type checks and guarded dispatch at the beginning of the
generic function for each specialization. Since we don't currently
expose this attribute as API and don't specialize vtables and witness
tables yet, the only way to reach the specialized code is by calling
the generic function which performs the guarded dispatch.

In the future, we can build on this work in several ways:
- cross module dispatch directly to specialized code
- dynamic dispatch directly to specialized code
- automated specialization based on less specific hints
- partial specialization
- and so on...

I reorganized and refactored the optimizer's generic utilities to
support direct function specialization as opposed to apply
specialization.
2016-03-21 12:43:05 -07:00
Xin Tong
cff61d7fe7 Implement a function signature cloner and rewriter.
This split the function signature module pass into 2 functin passes.

By doing so,  this allows us to rewrite to using the FSO-optimized
function prior to attempting inlining, but allow us to do a substantial
amount of optimization on the current function before attempting to do
FSO on that function.

And also helps us to move to a model which module pass is NOT used unless
necesary.

I do not see regression nor improvement for on the performance test suite.

functionsignopts.sil and functionsignopt_sroa.sil are modified because the
mangler now takes into account of information in the projection tree.
2016-03-19 23:57:37 -07:00
Andrew Trick
5bda28e1cb Revert "Merge pull request #1725 from atrick/specialize"
Temporarily reverting @_specialize because stdlib unit tests are
failing on an internal branch during deserialization.

This reverts commit e2c43cfe14, reversing
changes made to 9078011f93.
2016-03-18 22:31:29 -07:00
practicalswift
a942bb76d0 [gardening] Fix formatting of recently introduced headers. 2016-03-19 00:37:37 +01:00
Erik Eckstein
6d654aa3e8 Debugging on SIL level.
This change follows up on an idea from Michael (thanks!).
It enables debugging and profiling on SIL level, which is useful for compiler debugging.

There is a new frontend option -gsil which lets the compiler write a SIL file and generated debug info for it.
For details see docs/DebuggingTheCompiler.rst and the comments in SILDebugInfoGenerator.cpp.
2016-03-18 14:02:06 -07:00
Erik Eckstein
8f78085e8b Refactor SILPrinter.
Introduce a new SILPrintContext class which is the main handle passed to the SILModule's and SILFunction's print functions.
It also allows to let derived classes implement call backs on instruction printing.
NFC for now, but needed for the upcoming SIL-debuginfo change.
2016-03-18 14:01:38 -07:00
Erik Eckstein
b871d45775 Small refactoring in SILLocation.
Needed for the upcoming commits.
2016-03-18 13:44:08 -07:00
Andrew Trick
e2c43cfe14 Merge pull request #1725 from atrick/specialize
@_specialize attribute
2016-03-18 13:24:31 -07:00
Joe Groff
aec7be3930 SILGen: Handle C functions imported as property accessors. 2016-03-18 13:23:40 -07:00
Vedant Kumar
dc11f8bf01 [Coverage] Re-apply "Respect function linkage in PGO name variables"
Fix a crash in emitBuiltinCall() which occurs because we drop function
linkage information when creating SILCoverageMaps.

This re-applies 45c7e4e86 with the MachO-specific checks in the test
case removed.
2016-03-17 22:44:35 -07:00
Andrew Trick
4c052274e6 Introduce @_specialize(<type list>) internal attribute.
This attribute can be attached to generic functions. The attribute's
arguments must be a list of concrete types to be substituted in the
function's generic signature. Any number of specializations may be
associated with a generic function.

This attribute provides a hint to the compiler. At -O, the compiler
will generate the specified specializations and emit calls to the
specialized code in the original generic function guarded by type
checks.

The current attribute is designed to be an internal tool for
performance experimentation. It does not affect the language or
API. This work may be extended in the future to add user-visible
attributes that do provide API guarantees and/or direct dispatch to
specialized code.

This attribute works on any generic function: a freestanding function
with generic type parameters, a nongeneric method declared in a
generic class, a generic method in a nongeneric class or a generic
method in a generic class. A function's generic signature is a
concatenation of the generic context and the function's own generic
type parameters.

e.g.

  struct S<T> {
    var x: T
    @_specialize(Int, Float)
    mutating func exchangeSecond<U>(u: U, _ t: T) -> (U, T) {
      x = t
      return (u, x)
    }
  }
  // Substitutes: <T, U> with <Int, Float> producing:
  // S<Int>::exchangeSecond<Float>(u: Float, t: Int) -> (Float, Int)
2016-03-17 18:27:10 -07:00
Vedant Kumar
c59b266f93 Revert "[Coverage] Respect function linkage in PGO name variables"
This reverts commit 45c7e4e861.

The IR CHECK lines in coverage.swift are flaky.
2016-03-17 18:21:32 -07:00
Vedant Kumar
45c7e4e861 [Coverage] Respect function linkage in PGO name variables
Fix a crash in emitBuiltinCall() which occurs because we drop function
linkage information when creating SILCoverageMaps.
2016-03-17 18:06:39 -07:00
Joe Groff
f42e579040 Change SILGen to use ImportAsMemberStatus populated by ClangImporter. 2016-03-17 17:09:41 -07:00
Joe Groff
c4a69e9d5d SILGen: Basic code generation for C functions imported as methods.
Introduce abstraction patterns for curried C-functions-as-methods for type lowering, and plumb the "foreign self parameter index" through call emission so that we emit the "self" parameter in the right position. This gets us handling C functions imported as methods with explicit swift_name attributes in simple, fully-applied cases. There's still more work to be done for properties, partial applications, and initializers introduced by extensions.
2016-03-17 10:43:25 -07:00
Slava Pestov
be3631a878 SIL: Introduce SILModule::lookUpFunctionInDefaultWitnessTable() 2016-03-17 10:39:35 -07:00
Slava Pestov
116ac3d1f2 SIL Serialization: Serialize default witness tables
This will be used by SILGen to look up default witnesses for
requirements of protocols in other modules.
2016-03-17 10:39:34 -07:00
Slava Pestov
5cdacb66a9 SIL: Add SILDefaultWitnessTable::getIdentifier()
For serialization purposes, we identify default witness tables by
the mangled name of their protocol.
2016-03-17 10:39:34 -07:00
Slava Pestov
b13457daaa SILGen: Add linkage to SILDefaultWitnessTable
This is only used in the verifier, to ensure that default witness
thunks are suffiently visible.

Also this patch removes the asserts enforcing that only resilient
protocols have a default witness table. This will change in an
upcoming patch, and in this patch is necessary for the test to work.
2016-03-17 03:57:23 -07:00
Slava Pestov
25319d9d4b SILGen: Use correct linkage for default witness thunks
Don't hardcode linkage of default witness thunks, addressing a FIXME.

This will allow us to emit default witness thunks for requirements of
internal protocols, too.
2016-03-17 03:57:23 -07:00
Doug Gregor
86b7322e87 [Sema -> AST] Refactor "is representable in Objective-C?" checking.
Migrate the check for whether a given type is representable in
Objective-C, which is currently used to verify when @objc can be
inferred or verify that an explicitly-written @objc is well-formed,
from Sema into a set of queries on the Type within the AST library, so
it can be used in other parts of the compiler.

As part of this refactoring, clean up and improve a number of aspects
of this code:

* Unify the "trivially representable" and "representable" code paths
  into a single code path that covers these cases. Clarify the
  different levels of "representable" we have in both the code and
  in comments.

* Distinguish between representation in C vs. representation in
  Objective-C. While we aren't using this now, I'm anticipating it
  being useful to allow exporting C interfaces via @_cdecl (or
  similar).

* Eliminate the special cases for bridging String/Array/Dictionary/Set
  with their Foundation counterparts; we now consult
  _ObjectiveCBridgeable conformances exclusively to get this
  information.

* Cache foreign-representation information on the ASTContext in a
  manner that will let us more easily get the right answer across
  different contexts while providing more sharing than the TypeChecker
  version.

Annoyingly, this only seemed to fix a small class of error where we
were permitting Unsafe(Mutable)Pointer<T> to be representable in
Objective-C when T was representable but not trivially representable,
e.g., T=String or T=AnyObject.Type.
2016-03-16 23:53:48 -07:00
Xin Tong
5f7f05da9b Reinstate "Moves SignatureAnalyzer and ArgumentDescriptor/ResultDescriptor into
a separate analysis pass.

This pass is run on every function and the optimized signature is return'ed through the
getArgDescList and getResultDescList.

Next step is to split to cloning and callsite rewriting into their own function passes.

rdar://24730896
"
2016-03-16 07:00:57 -07:00
Erik Eckstein
c1bcb0b69d SIL: add new instruction set_deallocating
It will be used by the ReleaseDevirtualizer before calling the deallocator.
So far, this is NFC.
2016-03-15 12:56:54 -07:00
gregomni
1e3ed8bdd0 Split parsing for typealias & associatedtype, and allow typealias in protocols.
Split up parsing of typealias and associatedtype, including dropping a
now unneeded ParseDeclOptions flag.

Then made typealias in a protocol valid, and act like you would
hope for protocol conformance purposes (i.e. as an alias possibly
involved in the types of other func/var conformances, not as a hidden
generic param in itself).

Also added support for simple type aliases in generic constraints. Aliases
to simple (non-sugared) archetype types (and also - trivially - aliases to
concrete types) can now be part of same-type constraints.

The strategy here is to add type aliases to the tree of
PotentialArchetypes, and if they are an alias to an archetype, also to
immediately find the real associated type and set it as the
representative for the PA. Thus the typealias PA node becomes just a
shortcut farther down into the tree for purposes of lookup and
generating same type requirements.

Then the typealias PA nodes need to be explicitly skipped when walking
the tree for building archetype types and other types of requirements,
in order to keep from getting extra out-of-order archetypes/witness
markers of the real associated type inserted where the typealias is
defined.

Any constraint with a typealias more complex than pointing to a single
nested associated type (e.g. `typealias T = A.B.C.D`), will now get a
specialized diagnoses.
2016-03-13 21:44:23 -07:00
Max Moiseev
02006f20bc Merge remote-tracking branch 'origin/master' into swift-3-api-guidelines 2016-03-09 16:05:03 -08: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