Commit Graph

38 Commits

Author SHA1 Message Date
John McCall
338825e73d Fix the emission of r-value pointer conversions to delay the
conversions and extend lifetimes over the call.

Apply this logic to string-to-pointer conversions as well as
array-to-pointer conversions.

Fix the AST verifier to not blow up on optional pointer conversions,
and make sure we SILGen them correctly.  There's still an AST bug
here, but I'll fix that in a follow-up patch.
2017-04-26 14:15:44 -04:00
Michael Gottesman
6de8e56cbe [silgen] Add APIs for dumping/printing ManagedValues.
Saves a few key strokes in the debugger.
2017-03-29 15:36:12 -07:00
Michael Gottesman
5cbf589524 Small ease of use convenience APIs. NFC. 2017-03-27 16:00:34 -07:00
Michael Gottesman
68c581f729 [gardening] As per discussion, begin standardizing in SILGen that the SILGenFunction variable is passed around as SGF.
The reason that this is being done is that:

1. SILGenFunction is passed around all throughout SILGen, including in between
APIs some of which call the SILGenFunction variable SGF and others that call it
gen.
2. Thus when one is debugging code in SILGen, one wastes time figuring out what
the variable name of SILGenFunction is in the current frame.

I did not do this by hand. I did this by:

1. Grepping for "SILGenFunction &gen".
2. By hand inspecting that the match was truly a SILGenFunction &gen site.
3. If so, use libclang tooling to rename the variable to SGF.

So I did not update any use sites.
2017-03-11 23:38:17 -08:00
Michael Gottesman
87ca878870 [silgen] Fix another tuple explosion -> borrow + copy since we do not have the destructure operation yet.
rdar://29791263
2017-03-05 11:44:11 -08:00
Michael Gottesman
6920290de6 [silgen] Add an assert to ManagedValue::ManagedValue saying that objects with trivial ownership should never have a cleanup.
rdar://29791263
2017-03-05 11:44:08 -08:00
Slava Pestov
0611d663b8 SIL: Remove SILType::getSwiftType() 2017-02-27 20:01:35 -08:00
Michael Gottesman
5a15f880ee [silgen] Change a bunch of self accesses to use true formal evaluation scopes and formal accesses.
This is in preparation for removing the +0 self hack.

This commit in more detail does the following:

1. It adds Formal Evaluation Scopes to certain places where the scopes were
missing. Specifically:

   a. The SILGenLValue cases are places where we are invoking accessors. In each
      one of these cases, we had a formal evaluation scope in the accessor
      itself, but we did not have a scope that closed over the base access and
      the accessor access. The base access is a formal evaluation in the sense
      that just like with inout bases, we must create a new reference to the
      base and re-destroy the base in a chain of accesses. This is to ensure
      that we do not extend the lifetime of the base inappropriately.

   b. The SILGenPoly case is a place where we have never properly placed a
      Formal Evaluation Scope and have completely been relying on the +0 self
      hack to make sure that archetype callees are properly destroyed
      immediately after a +0 call.

2. It changes all of the places in SILGen that emit self to using formal access
cleanups instead of normal cleanups.

rdar://29791263
2017-02-23 10:36:48 -08:00
Michael Gottesman
5717eeba67 [silgen] Create a ManagedValue::formalAccessCopy(SILGenFunction &, SILLocation).
This is the same as the current ManagedValue::copy(...) convenience API except
that the cleanups are formal evaluation scoped.

rdar://29791263
2017-02-19 08:03:33 -08:00
Michael Gottesman
6b05692d31 [silgen] Remove incorrect assumptions in ManagedValue::copy(SILGenFunction &gen, SILLocation loc).
It was wrongly assumed that no cleanup meant a type must be trivial. This is not
true for shared borrow types.
2017-02-19 08:01:45 -08:00
Michael Gottesman
bdb4195de8 [silgen] ManagedValue::{formalEvaluationBorrow,formalAccessBorrow}()
NFC.
2017-02-19 07:58:03 -08:00
Michael Gottesman
58c3959e90 [silgen] Remove ManagedBorrowedValue in favor of the usage of FormalEvaluationScopes.
rdar://29791263
2017-02-15 15:28:14 -08:00
Michael Gottesman
7135ad3740 [silgen] Change ManagedValue::borrow to perform a *real* shared borrow and add a
new API called ManagedValue::unmanagedBorrow() for places where we were really trying to model
an exclusive borrow.

ManagedValue::unmanagedBorrow() is just the old implementation.

rdar://29791263
2017-02-05 17:07:42 -08:00
Michael Gottesman
9d5d163b11 [silgen] Add a class called BorrowedManageValue.
I am using this for implementing tight scopes around specific call sites. The
way that it works is that the class performs the copy and asserts if one has not
called the cleanup method before end of scope has occured.

rdar://29791263
2017-02-05 16:13:17 -08:00
Michael Gottesman
bcb755ef97 [silgen] Fix some parameter translation code in SILGenPoly for SILOwnership.
Everything here should be NFC after the ownership model eliminator except for 1
change where translation of unowned parameters is made more
correct. Specifically:

1. In manageParam, we make it so that if we allow PlusZero, we begin an actual
begin_borrow, end_borrow sequence. We can do this unconditionally since if the
passed in SILValue is already borrowed, we just return early.

2. In TranslateArguments::translateSingle(), we used to handle owned, unowned,
and guaranteed parameters all the same way. This is of course incorrect. Now we
do the following:

  a. If our final translated value is guaranteed, but we want an unowned or
  owned parameter, then we perform a copyUnmanaged().

  b. If our final translated value is unowned and our argument must be a
  guaranteed value, then we first transition the unowned value to an owned value
  using SILGen::emitManagedRetain() and then transition from owned to guaranteed
  using a emitBeginBorrow().

  c. If our final translated value is owned and our argument must be a
  guaranteed value, then we perform an emitBeginBorrow().

3. In forwardFunctionArguments(), if our argument requires a guaranteed
argument, we begin a begin borrow sequence.

rdar://29791263
2017-02-04 15:44:13 -08:00
Michael Gottesman
d9c2f22d9a [silgen] Add a new isa<...> API for ManagedValue.
This lets you do isa<AllocRefInst> to determine if the underlying ManagedValue
contains within it an AllocRefInst without needing to call getValue(). I would
like to restrict the number of places where getValue() needs to be called as
much as possible.
2017-02-04 13:40:26 -08:00
Michael Gottesman
4a6df2740b [semantic-sil] Remove CleanupHandle from forBorrowed*RValue methods.
I realized over the weekend the follie of storing a borrowed cleanup on
ManagedValues themselves. The reasons for this are:

1. We assume all over SILGen that ManagedValue::hasCleanup() => Owned. I would
have to fix all of those parts of the compiler.
2. The reason for having a cleanup handle on ManagedValue is to be able to
forward owned arguments, so there is really no purpose since we never want to be
able to forward these arguments.
2017-01-19 14:02:00 -08:00
Michael Gottesman
2c78ca99ac [semantic-sil] Introduce new specific static constructors for ManagedValue.
This is the first step towards eliminating:

* ManagedValue::forUnmanaged(SILValue)
* ManagedValue::ManagedValue(SILValue, CleanupHandle).

The reason why these two methods must be eliminated is that:

1. Currently non-trivial values are "borrowed" using
ManagedValue::forUnmanaged. With Semantic SIL, we are now able to represent
borrows via begin_borrow and end_borrow. This will make the semantics that
SILGen is trying to describe more accurate.

2. ManagedValue::ManagedValue can be used to add arbitrary cleanups. We want
methods that add cleanups, but that at the same time allow the caller to specify
what it expects the ownership of the given SILValue to be. This would then cause
an assertion to trip giving greater clarity.

rdar://29791263
2017-01-15 21:42:42 -08:00
Michael Gottesman
3985a11b9a [semantic-sil] Add a new API ManagedValue::transform() for transforming/forwarding a cleanup for a ManagedValue.
In SILGen, we often times want to transform a ManagedValue, while maintaining
the underlying cleanup. The ManagedValue::transform API attempts to formalize
this pattern through the usage of std::move to create a movable rvalue, but
returning a different ManagedValue as a full value. This ensure that the
original ManagedValue is destroyed at end of statement, will allowing the
underlying cleanup to be forwarded.

From an ownership perspective, I think the majority of these cases should
actually recreate the underlying cleanup since in most cases they involve
forwarding. For today though I am using this to just formalize this pattern at
the relevant call sites.

rdar://29791263
2017-01-15 21:29:48 -08:00
practicalswift
6d1ae2a39c [gardening] 2016 → 2017 2017-01-06 16:41:22 +01:00
Michael Gottesman
e9319faad1 Now that non-trivial +0 rvalues have cleanups, fix up a comment.
rdar://29791263
2017-01-03 17:01:30 -08:00
practicalswift
797b80765f [gardening] Use the correct base URL (https://swift.org) in references to the Swift website
Remove all references to the old non-TLS enabled base URL (http://swift.org)
2016-11-20 17:36:03 +01:00
Erik Eckstein
506ab9809f SIL: remove getTyp() from SILValue 2016-01-25 15:00:49 -08:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
practicalswift
cd7d8dfaff Fix alignment as requested by @gribozavr in #692 2015-12-21 08:54:24 +01:00
practicalswift
176f487d76 Fix incorrect filenames in headers. 2015-12-20 23:59:05 +01:00
John McCall
84cb0faaf3 Forward base rvalues directly to accessors instead of
conservatively copying them.

Also, fix a number of issues with mutating getters that
I noticed while examining and changing this code.  In
particular, stop relying on suppressing writeback scopes
during loads.

Fixes rdar://19002913, a bug where an unnecessary copy of
an array for a getter call left the array in a non-unique
state when a subsequent mutation occurred.

Swift SVN r23642
2014-12-03 05:13:11 +00:00
John McCall
519645daa0 Add ConsumableManagedValue, which allows a value to
declare whether it's owned by the emission code that's
working with it.

This is convenient when working extensively with values
that are being propagated into multiple, often-disjoint
paths, like switches.

Swift SVN r19333
2014-06-30 11:55:25 +00:00
Joe Groff
7941efcf57 SILGen: Remove dead forwardArgument methods from ManagedValue.
Bridging arguments is now handled by the reabstraction machinery.

Swift SVN r16175
2014-04-10 22:35:41 +00:00
Chris Lattner
827acad533 Various inout improvements:
- purge @inout from comments in the compiler except for places talking about
   the SIL argument convention.
 - change diagnostics to not refer to @inout
 - Change the astprinter to print InoutType without the @, so it doesn't show
   up in diagnostics or in closure argument types in code completion.
 - Implement type parsing support for the new inout syntax (before we just 
   handled patterns).
 - Switch the last couple of uses in the stdlib (in types) to inout.
 - Various testcase updates (more to come).



Swift SVN r13564
2014-02-06 06:22:27 +00:00
Chris Lattner
87fbce6a1a Progress on <rdar://problem/15867140> [string perf] member_ref_expr on an rvalue producing unnecessary retains/releases
- Remove my previous local hack.
- Add a new flag to SGFContext indicating that clients are ok with +0 rvalues.
- Teach emitRValueForPropertyLoad and emitRValueForDecl how to work with +0 rvalues.

This allows us to avoid retaining bases in arbitrarily nested struct rvalue
member_ref_expr's.  For example, this:

class SomeClass {}

struct AnotherStruct {
  var x : Int
  var c : SomeClass
}

struct StructMemberTest {
  var c1 : SomeClass, c2 : SomeClass
  var s : AnotherStruct

  func testRecursiveStruct() -> Int {
    return s.x
  }
}

used to compile to:

sil @_TFV1t16StructMemberTest19testRecursiveStructfS0_FT_Si : $@cc(method) @thin (@owned StructMemberTest) -> Int64 {
bb0(%0 : $StructMemberTest):
  debug_value %0 : $StructMemberTest  // let self // id: %1
  %2 = struct_extract %0 : $StructMemberTest, #s  // user: %3
  %3 = copy_value %2 : $AnotherStruct             // users: %5, %4
  %4 = struct_extract %3 : $AnotherStruct, #x     // user: %7
  destroy_value %3 : $AnotherStruct               // id: %5
  destroy_value %0 : $StructMemberTest            // id: %6
  return %4 : $Int64                              // id: %7
}

and now it compiles to:

sil @_TFV1t16StructMemberTest19testRecursiveStructfS0_FT_Si : $@cc(method) @thin (@owned StructMemberTest) -> Int64 {
bb0(%0 : $StructMemberTest):
  debug_value %0 : $StructMemberTest  // let self // id: %1
  %2 = struct_extract %0 : $StructMemberTest, #s  // user: %3
  %3 = struct_extract %2 : $AnotherStruct, #x     // user: %5
  destroy_value %0 : $StructMemberTest            // id: %4
  return %3 : $Int64                              // id: %5
}

There is more that can come from this, but it is a start.  This cuts out 50 retain/release pairs from the stdlib.



Swift SVN r12857
2014-01-23 06:54:02 +00:00
Chris Lattner
7cd0f1739a A big part of handling address-only types is making sure that various
emission routines use the SGFContext passed in.  To help with this and
to help the handshake, add a new "isInContext()" representation to 
ManagedValue.  This makes the code producing and consuming these more
explicit.  NFC.


Swift SVN r12783
2014-01-22 21:31:44 +00:00
Chris Lattner
b457be6a9f SGF::emitLValueForDecl only works on VarDecls, make its prototype more specific
to reflect that.


Swift SVN r12753
2014-01-22 18:20:06 +00:00
Chris Lattner
a7b39c21f3 emitReferenceToDecl is serving two purposes: for VarDecls it
can often produce an lvalue, for everything else it produces an RValue.

Split it up a bit so that all of the lvalue cases are handled by 
emitLValueForDecl (which it calls).  This allows clients that only
expect an lvalue back to have a simpler path, and allows one that
wants to probe to see if something is an lvalue or not to be simpler.



Swift SVN r12715
2014-01-22 07:07:05 +00:00
Chris Lattner
07970706b7 tidy some comments, add an assertion that lvalues always
have isAddress() type.


Swift SVN r12711
2014-01-22 06:39:52 +00:00
Chris Lattner
63784ca41c remove the ManagedValue::Unmanaged marker, lets just use ManagedValue::forUnmanaged()
instead, which is shorter.  It is better to have one way to do things than two.


Swift SVN r12710
2014-01-22 06:26:34 +00:00
Chris Lattner
f7597fb25d improve comments on ManagedValue, eliminate the LValue_t enum marker
in favor of ManagedValue::forLValue.  NFC.


Swift SVN r12709
2014-01-22 06:16:36 +00:00
Chris Lattner
90e1b572f0 split the ManagedValue class out to its own .h/.cpp files.
Swift SVN r12702
2014-01-22 05:42:34 +00:00