Commit Graph

3719 Commits

Author SHA1 Message Date
Michael Gottesman
83c4266e18 [gardening] Make SILUndef::get(..., SILModule &) the impl method and the one that takes the SILModule * the helper method instead of vis-a-versa.
We already assume in the given static method that the module is a non-null
pointer. So rather than us indirecting a ref to a pointer and then dereferencing
the pointer, we instead use the ref in the module implementation and dereference
the pointer.

rdar://46294760
2018-11-27 17:31:08 -08:00
Michael Gottesman
f984eaf768 [gardening] Make SILUndef's private deleted operators public.
rdar://46294760
2018-11-27 17:31:08 -08:00
Marc Rasi
390daeaeea address comments 2018-11-26 17:25:21 -08:00
Marc Rasi
44d7cdd4e6 constant interpreter: basic integer operations
Implements a constant interpreter that can deal with basic integer operations.

Summary of the features that it includes:
* builtin integer values, and builtin integer insts
* struct and tuple values, and insts that construct and extract them (necessary to use stdlib integers)
* function referencing and application (necessary to call stdlib integer functions)
* error handling data structures and logic, for telling you why your value is not evaluatable
* metatype values (not necessary for integers, but it's only a few extra lines, so I thought it would be more trouble than it's worth to put them in a separate PR)
* conditional branches (ditto)
2018-11-26 14:27:10 -08:00
Andrew Trick
702981f775 Fix MandatoryInlining to not be quadratic.
Inlining has always been quadratic for no good reason. There was a
special hack for single-block callees that allowed linear inlining.

Instead, the now iterates over blocks and instructions in reverse,
splitting blocks as it inlines. There no longer needs to be special
case for single block callees, and the inliner is linear for all kinds
of callees.

This further simplifies and cleans up the code. There are just a few
basic invariants that the common inliner needs to provide about how
blocks are split and laid out. We can do this if we don't add hacks
for special cases within the inliner. Those invariants allow the
inliner clients to be much simpler and more efficient.

PerformanceInliner still needs to be fixed.

Fixes SR-9223: Inliner exhibits slow compilation time with a large
static array.
2018-11-26 09:41:28 -08:00
David Zarzycki
fef48a52e7 Merge pull request #20649 from davezarzycki/fix_Wdefaulted-function-deleted-warnings
[Misc] NFC: Fix -Wdefaulted-function-deleted warnings
2018-11-18 11:40:00 -05:00
David Zarzycki
bf7f91b834 [Misc] NFC: Fix -Wdefaulted-function-deleted warnings 2018-11-17 08:30:59 -05:00
Slava Pestov
9d1c8eb9b4 SILGen: Use resilient access pattern for keypaths referenced from inlinable functions
Even if we're in the same module, we have to take the resilience
expansion into account, so plumb it through.
2018-11-16 23:18:30 -05:00
Andrew Trick
8664da6d9d Merge pull request #20620 from atrick/fix-access-phi
Fix SIL verification of findAccessedStorage for address phis.
2018-11-15 23:08:49 -08:00
Andrew Trick
dd08f6aa77 Fix SIL verification of findAccessedStorage for address phis.
The SIL verifier was asserting while attempting to prove that all
formal accesses are well-formed. This is necessary because
unrecognized access could lead to invalid whole-module optimization.

We would like to eliminate address-phis from SIL, but there are still
optimizer passes that produce them. For now, the best we can do is
hope to recover the original base of each phi value and prove they are
actually the same value. They should be because the optimizer
produced the phi through block cloning.

Fixes <rdar://problem/46114512> SIL verification failed: Unknown
formal access pattern: storage
2018-11-15 19:31:32 -08:00
Slava Pestov
e07dcb6889 Merge pull request #20562 from slavapestov/evolution-symbol-diff
Evolution: Compare symbols before and after
2018-11-15 20:54:54 -05:00
John McCall
5553224fd4 Support the explicit representation of self-conformances.
Big, but actually NFC because we're never actually creating them.
2018-11-15 16:42:03 -05:00
Slava Pestov
3b10ed5eaf SIL: Non-final public methods of resilient classes don't need public linkage
Part of <rdar://problem/40432647>.
2018-11-15 14:55:44 -05:00
Michael Gottesman
099cae5692 [semantic-arc-opts] Handle arg extract + copy + borrow + use.
Specifically, now the optimizer can take the following code:

sil @foo: $@convention(thin) (@guaranteed NativeObjectPair) -> () {
bb0(%0 : @guaranteed $NativeObjectPair):
  %1 = struct_extract %0 : $NativeObjectPair, #NativeObjectPair.obj1
  %2 = copy_value %1 : $Builtin.NativeObject
  %3 = begin_borrow %2 : $Builtin.NativeObject
  %foo = function_ref ...
  apply %foo(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
  end_borrow %3 : $Builtin.NativeObject
  destroy_value %2 : $Builtin.NativeObject
  ...
}

and eliminate all ownership instructions. I.e.:

sil @foo: $@convention(thin) (@guaranteed NativeObjectPair) -> () {
bb0(%0 : @guaranteed $NativeObjectPair):
  %1 = struct_extract %0 : $NativeObjectPair, #NativeObjectPair.obj1
  %foo = function_ref ....
  apply %foo(%1)
  ...
}

Before this the optimizer could only eliminate 200 insts in the stdlib. With
this change, we now can eliminate ~7000.
2018-11-13 12:07:48 -08:00
Michael Gottesman
fed6145922 [sil] Change all single value instructions with forwarding ownership to have static ownership.
Previously we would always calculate these instructions ownership dynamically
when asked and rely on the ownership verifier to catch if we made any
mistakes. Instead with this commit we move to a more static model where the
ownership that these instructions can take are frozen on construction. This is a
more static model that simplifies the ownership model.

I also eliminated a few asserts that are enforced in other places that caused
problems when parsing since we may not have a Function while Parsing (it was
generally asserts if a type was trivial).
2018-11-11 15:23:36 -08:00
Jordan Rose
d3edf7c9ff [SILGen] Always serialize witness tables in non-resilient modules (#20390)
...even if the conforming nominal type is resilient. It's the owner
of the conformance whose resilience matters.

I also factored this part out into a separate check at the AST level
so we can tweak it, and also so I can use it to (slightly) speed up
compiling a resilient swiftinterface.
2018-11-08 15:34:00 -08:00
Arnold Schwaighofer
44b3a47e56 Merge pull request #20333 from aschwaighofer/dynamic_function_replacement
Dynamic function replacement
2018-11-07 13:08:46 -08:00
Andrew Trick
5983aae176 Fix AccessEnforcementReleaseSinking. Check for illegal cases.
In the included, test case, the optimization was sinking
releases past is_escaping_closure.

Rewrite the isBarrier logic to be conservative and define the
mayCheckRefCount property in SIL/InstructionUtils. Properties that may
need to be updated when SIL changes belong there.

Note that it is particularly bad behavior if the presence of access
markers in the code cause miscompiles unrelated to access enforcement.

Fixes <rdar://problem/45846920> TestFoundation, TestProcess, closure
argument passed as @noescape to Objective-C has escaped.
2018-11-06 13:52:03 -08:00
Arnold Schwaighofer
b102c7f6b4 Parser/Sema/SILGen changes for @_dynamicReplacement(for:)
Dynamic replacements are currently written in extensions as

extension ExtendedType {
  @_dynamicReplacement(for: replacedFun())
  func replacement() { }
}

The runtime implementation allows an implementation in the future where
dynamic replacements are gather in a scope and can be dynamically
enabled and disabled.

For example:

dynamic_extension_scope CollectionOfReplacements {
  extension ExtentedType {
    func replacedFun() {}
  }

  extension ExtentedType2 {
    func replacedFun() {}
  }
}

CollectionOfReplacements.enable()
CollectionOfReplacements.disable()
2018-11-06 09:58:36 -08:00
Arnold Schwaighofer
52c1903e54 Add SIL support for [dynamic_replacement_for: ] functions 2018-11-06 09:58:28 -08:00
Arnold Schwaighofer
7e32c68e1d Add new SIL instruction for calling dynamically_replaceable funtions
%0 = dynamic_function_ref @dynamically_replaceable_function
  apply %0()
  Calls a [dynamically_replaceable] function.

  %0 = prev_dynamic_function_ref @dynamic_replacement_function
  apply %0
  Calls the previous implementation that dynamic_replacement_function
  replaced.
2018-11-06 09:53:22 -08:00
Arnold Schwaighofer
5f4e183302 Add [dynamically_replacable] to SILFunctions
'dynamic' functions are marked as [dynamically_replaceable].
2018-11-06 09:53:21 -08:00
John McCall
cf511445e2 Basic support for Builtin.IntegerLiteral. 2018-10-31 18:42:34 -04:00
Andrew Trick
063bbfcf7d Merge pull request #20136 from atrick/silcloner-cleanup
[NFC] SILCloner rewrite stage 2: "threading" cloners.
2018-10-30 16:33:50 -07:00
Michael Gottesman
71c13b7594 [sil] Rename ValueOwnershipKindClassifier.cpp -> ValueOwnership.cpp and remove ValueOwnershipKindClassifier.h
This matches the name of OperandOwnership.cpp which performs an anologous
function. I also was able to eliminate an unneeded header.  The key thing here
is that the only reason that we had ValueOwnershipKindClassifier.h was because
we needed some defs from it in SILValue.cpp for SILValue::getOwnershipKind()
... which is great except for the fact that ValueOwnershipKindClassifier is
basically the implementation of SILValue::getOwnershipKind().

So what this patch does is moves the implementation of
SILValue::getOwnershipKind() from SILValue.cpp -> ValueOwnership.cpp and then
puts the visitor into an anonymous namespace in that file.

I also added a little comment in SILValue.h that says that
SILValue::getOwnershipKind() is implemented in ValueOwnership.cpp, not
SILValue.cpp.
2018-10-29 23:50:54 -07:00
Andrew Trick
1446952521 Merge pull request #20111 from atrick/critedge-util
NFC: SILBasicBlock utilties for handling critical edges.
2018-10-29 15:42:07 -07:00
Andrew Trick
903a9821ab SILCloner rewrite stage 2: "threading" cloners.
Rewrite the SILCLoners used in SimplifyCFG. For convenience, there is
now simply a BasicBlockCloner and a SILFunctionCloner. It's pretty
obvious what they do and almost impossible to use incorrectly.

This is worthwhile on its own just to make the usage clear, but the
real reason is that after this cleanup, it will be possible to remove
many extraneous calls to global critical edge splitting related to
cloning.
2018-10-29 08:57:19 -07:00
Andrew Trick
2aa8427dc6 SILCloner: rename 'remapValue' to 'getMappedValue' to avoid confusion.
A follow up commit adds an API for SILCloner clients to set mapped
values. Calling the map lookup "remap" would be unacceptably misleading.
2018-10-27 16:30:37 -07:00
Andrew Trick
3aebfa9bf0 SILBuilder: add a createFallThroughBlock convenience. 2018-10-26 23:18:37 -07:00
Andrew Trick
1a9e13429c SILBuilder: add comments to constructors. 2018-10-26 23:18:37 -07:00
Joe Shajrawi
22d411c4ae Merge pull request #20053 from shajrawi/enforce_dom
[Exclusivity] Remove dominated access checks with no nested conflict.
2018-10-26 13:22:37 -07:00
Joe Shajrawi
b5508f5488 [Exclusivity] Remove dominated access checks with no nested conflict:
Simplification of the code (bail on unpaired accesses) + change the implementation so we can avoid quadratic behavior
2018-10-26 11:19:21 -07:00
Michael Gottesman
e4607a7191 [closure-lifetime-fixup] When emitting a load_borrow, make sure to emit the end_borrow for it as well.
In this commit I added a more convenient API for doing this sort of operation.
Specifically: SILBuilder::emitScopedBorrowOperation. This performs either a
load_borrow or begin_borrow, then calls a user provided closure, and finally
inserts the end_borrow after the scope has closed.

rdar://43398898
2018-10-26 11:11:01 -07:00
Erik Eckstein
ac2b5720b0 SILOptimizer: support static large string literal generation for the new UTF8 String implementation
In the new string implementation there is a subtract of a (small) constant from the literal pointer. We convert

((ptr - offset) | bits

to

(ptr + (bits - offset))

which can still be represented as a relocation.
2018-10-25 10:18:23 -07:00
Michael Gottesman
f41f75ca3c [sil] Improve comments on macro definitions in SILNodes.def.
Specifically:

1. The comment for SINGLE_VALUE_INST did not match its actual macro definition
with Parent and TextualName being swapped.
2. I noticed that there were a few macros without any documentation. I added
documentation for them.
2018-10-23 21:16:12 -07:00
Andrew Trick
12bb49f57a Expose SIL/BasicBlockUtils for critical edge splitting.
The primary interfaces for CFG manipulation belong in SIL. This is
just what's necessary to fix SILCloner.
2018-10-22 08:34:57 -07:00
Andrew Trick
a03d7bfac3 Add FIXME comments with suggestions to improve test case maintenance. 2018-10-19 23:14:17 -07:00
Andrew Trick
2ccc089b27 SILGenFunction::mergeCleanupBlocks.
Avoid emitting unnecessary basic block for cleanup chains. This is a
general approach that handles all cases while simplifying SILGen
emission and keeping the CFG in a valid state during SILGen.
2018-10-19 22:22:23 -07:00
Andrew Trick
f6f9accb96 Add SILBuilder constructors that take a DebugScope.
Allow a new SILBuilder to be created for an insertion point, while
providing all of its necessary context.

Ultimately, the builder's constructor should take an insertion point,
DebugLocation, and context. Then we won't need to pass SILLocation to
all of its methods.

This makes much more sense and is much safer than saving the insertion
point via an RAII object or defining a separate
SILBuilderWithScope. Those broken abstractions should go away.
2018-10-19 22:22:23 -07:00
Michael Gottesman
e7671d1650 [gardening] Change a file comment into a proper doxygen file comment.
NFC.
2018-10-13 21:18:17 -07:00
Andrew Trick
c6865c0dff Merge pull request #19786 from atrick/silcloner-cleanup
SILCloner and SILInliner rewrite.
2018-10-11 14:23:32 -07:00
Michael Gottesman
e9b0f12c42 Merge pull request #19772 from gottesmm/pr-a6c84965d1903f06da9c5c62ff4b58d915cc4807
[sil] Add a new CastConsumptionKind called BorrowAlways.
2018-10-11 11:19:44 -07:00
Michael Gottesman
62b5110357 [sil] Add a new CastConsumptionKind called BorrowAlways.
This means that:

1. SILGenPattern always borrows the object before it emits a case.
2. Any cast with this cast has a +0 result.

NOTE: That one can not use this with address types (so we assert if you
pass this checked_cast_addr_br).
NOTE: Once we have opaque values, checked_cast_br of a guaranteed value will
lower to a copy + checked_cast_addr_br (assuming the operation is a consuming
cast). To make sure this does not become a problem in terms of performance, we
will need a pass that can transform SILGenPattern +0 cases to +1 cases. This is
something that we have talked about in the past and I think it is reasonable to
implement.

This is an incremental commit towards fixing SILGenPattern for ownership.

rdar://29791263
2018-10-10 21:02:58 -07:00
Andrew Trick
9e440d13a6 Rename SILCloner doPostProcess and foldValue to recordClonedInstruction and recordFoldedValue. 2018-10-10 18:01:12 -07:00
Michael Gottesman
1baf38cb07 [sil] Split operand ownership classification from SILOwnershipVerifier.cpp into OperandOwnership.cpp.
Last week I split out operand ownership classification from the
SILOwnershipVerifier into the OperandOwnershipKindClassifier. Now move that
classifier code to another file so that SILOwnershipVerifier.cpp just consists
of the actual checker code. This makes sense since this type of classifier is
describing a separate structural aspect of SIL rather than something intrinsic
to the ownership verifier.

Keep in mind that this is not the final form of this classifier. Just an
incremental step forward.
2018-10-10 17:24:53 -07:00
Andrew Trick
c781d78782 Fix #includes. Arnold's review. 2018-10-09 22:36:33 -07:00
Andrew Trick
81fa786d6a Comments, typos, and cleanup from review. 2018-10-09 20:11:38 -07:00
Harlan
00cc011621 [SILOptimizer] Don't diagnose infinite recursion if a branch terminates the program (#19781)
* [SILOptimizer] Don't diagnose infinite recursion if a branch terminates the program

This patch augments the infinite recursion checker to not warn if a
branch terminates, but still warns if a branch calls into something with
@_semantics("programtermination_point"). This way, calling fatalError
doesn't disqualify you for the diagnostic, but calling exit does.

This also removes the warning workaround in the standard library, and
annotates the internal _assertionFailure functions as
programtermination_points, so they get this treatment too.

* Fix formatting in SILInstructions.cpp

* Re-add missing test
2018-10-09 09:46:37 -07:00
Andrew Trick
bd28b0ea1b SILCloner and SILInliner rewrite.
Mostly functionally neutral:
- may fix latent bugs.
- may reduce useless basic blocks after inlining.

This rewrite encapsulates the cloner's internal state, providing a
clean API for the CRTP subclasses. The subclasses are rewritten to use
the exposed API and extension points. This makes it much easier to
understand, work with, and extend SIL cloners, which are central to
many optimization passes. Basic SIL invariants are now clearly
expressed and enforced. There is no longer a intricate dance between
multiple levels of subclasses operating on underlying low-level data
structures. All of the logic needed to keep the original SIL in a
consistent state is contained within the SILCloner itself. Subclasses
only need to be responsible for their own modifications.

The immediate motiviation is to make CFG updates self-contained so
that SIL remains in a valid state. This will allow the removal of
critical edge splitting hacks and will allow general SIL utilities to
take advantage of the fact that we don't allow critical edges.

This rewrite establishes a simple principal that should be followed
everywhere: aside from the primitive mutation APIs on SIL data types,
each SIL utility is responsibile for leaving SIL in a valid state and
the logic for doing so should exist in one central location.

This includes, for example:
- Generating a valid CFG, splitting edges if needed.
- Returning a valid instruction iterator if any instructions are removed.
- Updating dominance.
- Updating SSA (block arguments).

(Dominance info and SSA properties are fundamental to SIL verification).

LoopInfo is also somewhat fundamental to SIL, and should generally be
updated, but it isn't required.

This also fixes some latent bugs related to iterator invalidation in
recursivelyDeleteTriviallyDeadInstructions and SILInliner. Note that
the SILModule deletion callback should be avoided. It can be useful as
a simple cache invalidation mechanism, but it is otherwise bug prone,
too limited to be very useful, and basically bad design. Utilities
that mutate should return a valid instruction iterator and provide
their own deletion callbacks.
2018-10-08 19:30:09 -07:00
Slava Pestov
ac7664357a SIL: Correctly substitute type parameters in opened existential types
This wasn't possible when the SIL cloner was first written, but subclass
existentials can involve generic classes, so you can have an opened
archetype type with a superclass constraint involving a type constraint.
2018-10-08 17:02:19 -07:00