[swift-dev] DispatchQueue function in Swift 3.0

2016-10-07 Thread Yue Cui via swift-dev
Does anyone know the equivalent function of DispatchQueue in Swift 3.0?

Thanks in advance.

For the DispatchQueue, the swift 3 has changed it's properties.

The code for swift 2.xx looks like this:

let priority = DispatchQueue.GlobalQueuePriority.default
DispatchQueue.global(priority: priority).async {
// ALL the API processing..
DispatchQueue.main.async {
// ALL the UI reload..
}
}

the error messages shown in Swift 3.0 are:
'default' was deprecated in iOS 8.0: Use qos attributes instead.
'global(priority:)' was deprecated in iOS 8.0.
___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] DispatchQueue function in Swift 3.0

2016-10-07 Thread Chris Bailey via swift-dev
Are you looking for the following?

DispatchQoS.QoSClass.

Regards



C (Chris) Bailey
 

Senior Technical Staff Member (STSM)
 Hursley Park
Runtime Technologies for Java, Node.js and Swift
 Winchester, Hampshire SO21 2JN
IBM Software Group
 United Kingdom

Phone:
+44-1962-817078
IBM SDKs for Java™

Mobile:
+44-7738-310815 (272022)
IBM SDKs for Node.js™

e-mail:
bail...@uk.ibm.com
IBM Monitoring and Diagnostic Tools

Find me on:   
 





From:   Yue Cui via swift-dev 
To: swift-dev@swift.org
Date:   07/10/2016 14:12
Subject:[swift-dev] DispatchQueue function in Swift 3.0
Sent by:swift-dev-boun...@swift.org



Does anyone know the equivalent function of DispatchQueue in Swift 3.0?

Thanks in advance.

For the DispatchQueue, the swift 3 has changed it's properties.

The code for swift 2.xx looks like this:

let priority = DispatchQueue.GlobalQueuePriority.default
DispatchQueue.global(priority: priority).async {
// ALL the API processing..
DispatchQueue.main.async {
// ALL the UI reload..
}
}

the error messages shown in Swift 3.0 are:
'default' was deprecated in iOS 8.0: Use qos attributes instead.
'global(priority:)' was deprecated in iOS 8.0.
___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev



___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


[swift-dev] (Re-)compiling the stdlib

2016-10-07 Thread Christian Hoffmann via swift-dev
Hi there,

quick question from someone who likes to get started on the stdlib and
therefore sometimes likes to change an implementation, just to get a better
understanding, what is going on.

So let's say, I changed something in Bool.swift, e.g. to let the
implementation of `description` in the `CustomStringConvertible`
extension return 'YES' or 'NO'.

Ok, so doing a
`./swift/utils/build-script --debug-swift-stdlib --build-subdir=ds --`
compiles fine -> Perfect!

Running the REPL via `./build/ds/swift-macosx-x86_64/bin/swift` gives:

***  You are running Swift's integrated REPL,  ***
***  intended for compiler and stdlib  ***
***  development and testing purposes only.***
***  The full REPL is built as part of LLDB.   ***
***  Type ':help' for assistance.  ***
(swift) let someBool = true
// someBool : Bool = YES
(swift) print (someBool.description)
YES

Once again: Perfect and as expected!

So after seeing, that this was kind of a bad idea and resetting these
changes,
re-triggering the same build command
`./swift/utils/build-script --debug-swift-stdlib --build-subdir=ds --`
runs much faster (as expected), BUT:
a newly started REPL gives the same results, as before and not as I
would expect a `true` or `false`.

I also tried to add a new method:
```
let someBool = true
// someBool : Bool = YES
let someBoolStr = someBool.anotherFunc()
LLVM ERROR: Program used external function '__TFSb11anotherFuncfT_SS' which
could not be resolved!
```

Once again: After a clean build, everything seems to work perfect.
Any idea, what needs to be "retriggered", so that the REPL or `swiftc`
picks up the new stdlib?

Thank you and Regards,
Christian Hoffmann
___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


[swift-dev] KVO Context Param

2016-10-07 Thread Tyler Stromberg via swift-dev
Hey everyone,

One of the things that came up in a code review today was the type of KVO's 
context param. If you look at the function signature it gets imported as 
UnsafeMutableRawPointer?. Is there ever a need to mutate this parameter, and if 
not can we change it to be UnsafeRawPointer? instead?

We commonly define a constant (e.g. kvoContext = 0) to pass in, but in Swift we 
have to make it mutable (which we'd rather not do). Is there another 
workaround? How is everyone else handling this? (We avoid KVO whenever 
possible, but some APIs require it.)

Thanks,

-Tyler___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] (Re-)compiling the stdlib

2016-10-07 Thread Jordan Rose via swift-dev
We were seeing some issues recently where the stdlib wouldn't get copied 
(actually lipo'd) into its final destination. Doug Coleman reverted the problem 
commit yesterday in https://github.com/apple/swift/pull/5166 
. Can you update to the latest master 
and try again?

Jordan

> On Oct 6, 2016, at 11:40, Christian Hoffmann via swift-dev 
>  wrote:
> 
> Hi there,
> 
> quick question from someone who likes to get started on the stdlib and
> therefore sometimes likes to change an implementation, just to get a better
> understanding, what is going on.
> 
> So let's say, I changed something in Bool.swift, e.g. to let the
> implementation of `description` in the `CustomStringConvertible`
> extension return 'YES' or 'NO'.
> 
> Ok, so doing a
> `./swift/utils/build-script --debug-swift-stdlib --build-subdir=ds --`
> compiles fine -> Perfect!
> 
> Running the REPL via `./build/ds/swift-macosx-x86_64/bin/swift` gives:
> 
> ***  You are running Swift's integrated REPL,  ***
> ***  intended for compiler and stdlib  ***
> ***  development and testing purposes only.***
> ***  The full REPL is built as part of LLDB.   ***
> ***  Type ':help' for assistance.  ***
> (swift) let someBool = true
> // someBool : Bool = YES
> (swift) print (someBool.description)
> YES
> 
> Once again: Perfect and as expected!
> 
> So after seeing, that this was kind of a bad idea and resetting these changes,
> re-triggering the same build command
> `./swift/utils/build-script --debug-swift-stdlib --build-subdir=ds --`
> runs much faster (as expected), BUT:
> a newly started REPL gives the same results, as before and not as I
> would expect a `true` or `false`.
> 
> I also tried to add a new method:
> ```
> let someBool = true
> // someBool : Bool = YES
> let someBoolStr = someBool.anotherFunc()
> LLVM ERROR: Program used external function '__TFSb11anotherFuncfT_SS' which 
> could not be resolved!
> ```
> 
> Once again: After a clean build, everything seems to work perfect. 
> Any idea, what needs to be "retriggered", so that the REPL or `swiftc` 
> picks up the new stdlib?
> 
> Thank you and Regards,
> Christian Hoffmann
> 
> ___
> swift-dev mailing list
> swift-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-dev

___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] DispatchQueue function in Swift 3.0

2016-10-07 Thread Philippe Hausler via swift-dev
I believe it got renamed to qos:

DispatchQueue.global(qos: .userInteractive).async {

}

etc.


> On Oct 7, 2016, at 6:11 AM, Yue Cui via swift-dev  wrote:
> 
> Does anyone know the equivalent function of DispatchQueue in Swift 3.0?
> 
> Thanks in advance.
> 
> For the DispatchQueue, the swift 3 has changed it's properties.
> 
> The code for swift 2.xx looks like this:
> 
> let priority = DispatchQueue.GlobalQueuePriority.default
>DispatchQueue.global(priority: priority).async {
>// ALL the API processing..
>DispatchQueue.main.async {
>// ALL the UI reload..
>}
>}
> 
> the error messages shown in Swift 3.0 are:
> 'default' was deprecated in iOS 8.0: Use qos attributes instead.
> 'global(priority:)' was deprecated in iOS 8.0.
> ___
> swift-dev mailing list
> swift-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-dev

___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] swift (ABI) and Windows

2016-10-07 Thread Paul Menage via swift-dev
On Wed, May 11, 2016 at 9:23 AM, Saleem Abdulrasool via swift-dev
 wrote:
>
> Unfortunately, ATM, the runtime is compacted into the stdlib, which has the
> small problem of making the stdlib have references to the runtime functions
> as if it were being dynamically linked.  We *could* just assume that the any
> time that the LLVM module name is "Swift.*" we are building the stdlib and
> not mark the runtime functions for external (import) dll storage, but this
> seems rather fragile.  The problem is that at IRGen time, we no longer have
> access to  the SILModule (AFAIK), so we don't have a way to identify if we
> are the stdlib or not.  Suggestions on how to handle that would be
> appreciated.

Experimenting with building for Windows-arm with MSVC, this approach
does work pretty well. But it seems hacky. Can we use
llvm::Module::addModuleFlag() to add a "SwiftStdlib" flag to the
module that the IRGenCode can check for?

Paul
___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


[swift-dev] The Legend of the Toll-Free Swift -> ObjC Collection Bridge

2016-10-07 Thread Alexis via swift-dev
I’ve been looking a lot into how Swift and Objective C collections 
inter-convert because a bunch of necessary cleanup for ABI stability interacts 
with it. Unfortunately I’ve run into some conflicting information with respect 
to how stuff should work, and how it seems to actually work. Hoping y'all could 
help me clear this up.

Here’s the literal state of the Swift codebase, as I currently understand it:

* String, Array, Dictionary, and Set are all effectively tagged unions of 
"Native || Objc”. 
* The ObjC case is the result of lazy bridging, and is basically just storing 
an NSWhatever pointer.
* If any of these collections are in the ObjC state, then bridging to ObjC is 
obvious and trivial. (yay!)
* If any of these collections are in the Native state:



Array: If the storage is verbatim bridgeable to ObjC (~it’s a class or objc 
existential), just return the buffer (toll free). Otherwise, wrap the storage 
in a _SwiftDeferredNSArray (not toll free). The first time someone tries to 
access the contents of the _SwiftDeferredNSArray, a CAS-loop race occurs to 
create a new buffer containing all the bridged values. The only alternative to 
this would be bridging each element as it’s requested, but that’s ultimately 
just a trade-off (and has issues if people are relying on pointer equality). 
There has to be some toll here.

However the construction of the _SwiftDeferredNSArray is hypothetically 
unnecessary, as alluded to in the comments on _SDNSArray. The class and its CAS 
pointer could be embedded in the native array buffer. This would presumably 
incur some bloat on all native Arrays, but it might not be too bad (and 
platforms which don’t support _runtime(ObjC) presumably can omit it)? That 
said, I’m not 100% clear if we have the machinery to accomplish this yet or 
not. If anyone knows this, it would help a lot!

(there’s also some special case singleton for empty arrays, that all seems fine)

See: 
ContiguousArrayBuffer.swift: _asCocoaArray
ContiguousArrayBuffer.swift: _getNonVerbatimBridgedHeapBuffer
SwiftNativeNSArray: _SwiftDeferredNSArray (the class that wraps the 
storage)




Dictionary/Set: Looks to be pretty much the same thing as Array, except that 
the old indexing model led to a double-indirection being baked into the design, 
so a wrapper class doesn’t need to be constructed in the non-verbatim case.
(_NativeDictionaryStorageOwner contains the CAS-pointer). (toll free as can be!)

But this means that cleaning up all the gunk from the old indexing model and 
removing this indirection will lead to a regression in bridging performance 
*unless* Dictionary/Set gets the kind of optimizations discussed for Array. The 
class inlining optimization also seem more acceptable for Dictionary, since 
it’s necessarily a more bloated allocation than Array (less overhead by %).

See: 
HashedCollections.swift.gyb: _bridgeToObjectiveCImpl
HashedCollections.swift.gyb: _Native${Self}StorageOwner (the “outer” 
class)




String: Unconditionally construct a class that wraps the String’s storage. (not 
toll free)

This just seems bad, and as far as I can tell isn’t expected. It seems to be 
the result of _StringBuffer (the lowest-level type in the String abstraction 
stack that still actually knows it’s a string) being a struct, and not a class 
that inherits from _HeapBuffer due to some problems with deriving from generic 
classes. I’m not 100% sure what the “fix” for this is supposed to be.

I think any fix will necessarily lead to String becoming pointer-sized, which 
appears to be a desirable ABI feature anyway.
However this has tricky consequences for Strings which are actually sub-slices 
of other Strings. At the limit, this will definitely require some slices which 
don’t allocate (because they just create a new String pointing at the old 
buffer with different start/length values) to start requiring an allocation 
(because those fields will be in a class, and not a struct). Maybe stack 
promotion and careful pointer-tagging can eliminate most allocations in 
practice.

See: 
StringBridge.swift: _stdlib_binary_bridgeToObjectiveCImpl
StringBridge.swift: _NSContiguousString (the class that wraps the 
storage)
StringBuffer.swift: _StringBuffer (the type that wants to subclass 
_HeapBuffer)




So that’s the situation as I understand it. Did I get anything wrong? Are there 
any details I’m missing?





___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] Reporting/Debugging Slow Swift Compile Time

2016-10-07 Thread Ben Asher via swift-dev
Hello again! I wanted to follow up with some more numbers and feedback. I
wasn't able to easily compile a single file from our project from the CLI.
I started putting together a command with all of the necessary framework
includes, flags, etc., but I moved on because it was taking awhile,
becoming a mess, and figured the other suggestions might yield results
quicker.

Moving on, I took a second look at the -debug-time-function-bodies output
as Mark suggested, and I found that we have 2521 properties that are parsed
607 times each. If we got that down to the ideal case of parsing each one
of those properties once, that would save us ~1.5 million "parses". So, is
there a ticket already for this issue? I didn't see one when I searched,
but it does sound like it's known.

I do plan on at least taking a look at adding the suggested timers, but
that will likely take me into next week or longer depending on what else I
have going on.

Thanks!

Ben

On Wed, Oct 5, 2016 at 4:31 PM, Ben Asher  wrote:

> Ah this is all super helpful. I'll do some more profiling and try to get
> back with some data in the next several days.
>
> Thanks!
>
> Ben
>
> On Wed, Oct 5, 2016 at 4:28 PM, Mark Lacey  wrote:
>
>>
>> On Oct 5, 2016, at 3:37 PM, Ben Asher  wrote:
>>
>> I just tried with both Xcode 8.1 beta 2 and Xcode 8.0, and 8.1b2 seems
>> maybe 15s faster (to build our main huge target): 7m28s compared to 7m43s.
>> It's some improvement, but I'm not exactly sure what kind of improvement
>> was expected.
>>
>>
>> The kind of benefit you might expect really depends on the specific code
>> you’ve written. The changes I have in mind attempt to speed up the
>> expression type checker (the thing that does the work of inferring types
>> for a given expression, and the case where there is an explicit type the
>> expression needs to type-check to, ensuring that it does). These
>> expressions include things like array literals and dictionary literals,
>> where we sometimes take a long time to type check.
>>
>> Is there any profiling/tracing you all would recommend to help find
>> problem areas?
>>
>>
>> If you’re looking for problem areas in your particular build, I have a
>> couple suggestions:
>>
>> 1. Take a look at the output of -debug-time-function-bodies to see if the
>> same function is getting type checked multiple times, and determine what
>> the cumulative time for those functions is.
>>
>> For example below is the output I see for a simple test case. Note that
>> the getter/setter that are generated from a property on line 2 of two.swift
>> are type checked twice. Although in this case we type check the individual
>> functions very quickly, if you have enough of this kind of redundant type
>> checking happening, it can add up. This *particular* case is a known bug
>> that we hope to address - the synthesized getters/setters for properties
>> are type checked in each file they are referenced in.
>>
>> There may be other cases like this that we’re not already aware of, so
>> it’s always good to open a bug if you find something like this.
>>
>> swiftc -c main.swift two.swift -module-name test -Xfrontend
>> -debug-time-function-bodies
>> 0.2ms main.swift:2:7 get {}
>> 0.2ms main.swift:2:7 set {}
>> 0.0ms main.swift:1:7 @objc deinit
>> 0.3ms main.swift:1:13 override init()
>> 0.2ms two.swift:2:14 get {}
>> 0.2ms two.swift:2:14 set {}
>> 0.2ms two.swift:2:14 get {}
>> 0.2ms two.swift:2:14 set {}
>> 0.0ms two.swift:1:14 @objc deinit
>> 0.0ms two.swift:1:14 init()
>>
>> 2. Add a timer for expression type checking and see if that helps narrow
>> down whether there is time being spent type checking expressions that isn’t
>> accounted for in -debug-time-function-bodies. There are a few places that
>> might make sense for this, but I suspect ConstraintSystem::solve() might
>> be the best. This is ultimately called from a variety of places, and would
>> provide the most insight into where time is being spent in the expression
>> type checking. It’s possible something higher up the stack, like
>> TypeChecker::solveForExpression or TypeChecker::typeCheckExpression()
>> might make more sense as well. You can model this on how
>> -debug-time-function-bodies is currently implemented, e.g. look
>> at swift::performTypeChecking for some help on getting started. I’ll
>> probably try to add this timer myself in the next few weeks if you don’t
>> manage to beat me to it.
>>
>> Mark
>>
>>
>> I don't mind building from Swift master, using someone's preferred
>> profiling tools, etc. I'm not really sure where to start.
>>
>> Ben
>>
>> On Wed, Oct 5, 2016 at 1:05 PM, Ben Asher  wrote:
>>
>>> Apologies for not starting off with system info: macOS Sierra (10.12.0),
>>> Xcode 8.0 (from the App Store).
>>>
>>> I'll try with Xcode 8.1 beta this afternoon and report back. Ill also
>>> open a ticket for improving -debug-time-function-bodies if I can confirm
>>> anything.
>>>
>>> Thanks!
>>>
>>> Ben
>>>
>>> On Wed, Oct 5, 2016 at 1:00 PM, Mark Lacey  wrote:
>>>

Re: [swift-dev] [semantic-arc][proposal] High Level ARC Memory Operations

2016-10-07 Thread Michael Gottesman via swift-dev
Attached below is an updated version of the proposal. Again a rendered version 
is located at:

https://gottesmm.github.io/proposals/high-level-arc-memory-operations.html

Michael



# Summary

This document proposes:

1. adding the following ownership qualifiers to `load`: `[take]`, `[copy]`,
   `[borrow]`, `[trivial]`.
2. adding the following ownership qualifiers to `store`: `[init]`, `[assign]`,
   `[trivial]`.
3. requiring all `load` and `store` operations to have ownership qualifiers.
4. banning the use of `load [trivial]`, `store [trivial]` on memory locations of
   `non-trivial` type.

This will allow for:

1. eliminating optimizer miscompiles that occur due to releases being moved into
   the region in between a `load`/`retain`, `load`/`release`,
   `store`/`release`. (For a specific example, see the appendix).
2. explicitly modeling `load [trivial]`/`store [trivial]` as having `unsafe
   unowned` ownership semantics. This will be enforced via the verifier.
3. more aggressive ARC code motion.

# Definitions

## ownership qualified load

We propose four different ownership qualifiers for load. Define `load [trivial]`
as:

%x = load [trivial] %x_ptr : $*Int

  =>

%x = load %x_ptr : $*Int

A `load [trivial]` can not be used to load values of non-trivial type. Define
`load [copy]` as:

%x = load [copy] %x_ptr : $*C

  =>

%x = load %x_ptr : $*C
retain_value %x : $C

Then define `load [take]` as:

%x = load [take] %x_ptr : $*Builtin.NativeObject

  =>

%x = load %x_ptr : $*Builtin.NativeObject

**NOTE** `load [take]` implies that the loaded from memory location no longer
owns the result object (i.e. a take is a move). Loading from the memory location
again without reinitialization is illegal.

Next we provide `load [borrow]`:

%x = load [borrow] %x_ptr : $*Builtin.NativeObject
...
endBorrow(%x, %x_ptr)

  =>

%x = load %x_ptr : $*Builtin.NativeObject
...
endBorrow(%x, %x_ptr)

`load [borrow]` implies that in the region between the `load` and the
`endBorrow`, the loaded object must semantically remain alive. The `endBorrow`
communicates to the optimizer:

1. That the value in `%x_ptr` should not be destroyed before endBorrow.
2. Uses of `%x` should not be sunk past endBorrow since `%x` is only a shallow
   copy of the value in `%x_ptr` and past that point `%x_ptr` may not remain
   alive.

An example of where this construct is useful is when one has a let binding to a
class instance `c` that contains a let field `f`. In that case `c`'s lifetime
guarantees `f`'s lifetime meaning that returning `f` over the function call
boundary is safe.

## ownership qualified store

First define a `store [trivial]` as:

store %x to [trivial] %x_ptr : $*Int

  =>

store %x to %x_ptr : $*Int

The verifier will prevent this instruction from being used on types with
non-trivial ownership. Define a `store [assign]` as follows:

store %x to [assign] %x_ptr : $*C

   =>

%old_x = load %x_ptr : $*C
store %new_x to %x_ptr : $*C
release_value %old_x : $C

*NOTE* `store` is defined as a consuming operation. We also provide
`store [init]` in the case where we know statically that there is no
previous value in the memory location:

store %x to [init] %x_ptr : $*C

   =>

store %new_x to %x_ptr : $*C

# Implementation

## Goals

Our implementation strategy goals are:

1. zero impact on other compiler developers until the feature is fully
   developed. This implies all work will be done behind a flag.
2. separation of feature implementation from updating passes.

Goal 2 will be implemented via a pass that transforms ownership qualified
`load`/`store` instructions into unqualified `load`/`store` right after SILGen.

## Plan

We begin by adding initial infrastructure for our development. This means:

1. Adding to SILOptions a disabled by default flag called
 "EnableSILOwnershipModel". This flag will be set by a false by default frontend
 option called "-enable-sil-ownership-mode".

2. Bots will be brought up to test the compiler with
   "-enable-sil-ownership-model" set to true. The specific bots are:

   * RA-OSX+simulators
   * RA-Device
   * RA-Linux.

   The bots will run once a day until the feature is close to completion. Then a
   polling model will be followed.

Now that change isolation is borrow, we develop building blocks for the
optimization:

1. Two enums will be defined: `LoadInstOwnershipQualifier`,
   `StoreInstOwnershipQualifier`. The exact definition of these enums are as
   follows:

   enum class LoadOwnershipQualifier {
 Unqualified, Take, Copy, Borrow, Trivial
   };
   enum class StoreOwnershipQualifier {
 Unqualified, Init, Assign, Trivial
   };

*NOTE* `LoadOwnershipQualifier::Unqualified` and
`StoreOwnershipQualifier::Unqualified` are only needed for staging purposes.

2. Creating a `LoadInst`, `StoreInst` will be changed to require an ownership
qualifier. A

Re: [swift-dev] The Legend of the Toll-Free Swift -> ObjC Collection Bridge

2016-10-07 Thread Dave Abrahams via swift-dev

on Fri Oct 07 2016, Alexis  wrote:

> I’ve been looking a lot into how Swift and Objective C collections
> inter-convert because a bunch of necessary cleanup for ABI stability
> interacts with it. Unfortunately I’ve run into some conflicting
> information with respect to how stuff should work, and how it seems to
> actually work. Hoping y'all could help me clear this up.
>
> Here’s the literal state of the Swift codebase, as I currently understand it:
>
> * String, Array, Dictionary, and Set are all effectively tagged unions of 
> "Native || Objc”. 
> * The ObjC case is the result of lazy bridging, and is basically just storing 
> an NSWhatever pointer.
> * If any of these collections are in the ObjC state, then bridging to ObjC is 
> obvious and
> trivial. (yay!)
> * If any of these collections are in the Native state:
>
> Array: If the storage is verbatim bridgeable to ObjC (~it’s a class or
> objc existential), just return the buffer (toll free). Otherwise, wrap
> the storage in a _SwiftDeferredNSArray (not toll free). The first time
> someone tries to access the contents of the _SwiftDeferredNSArray, a
> CAS-loop race occurs to create a new buffer containing all the bridged
> values. 

Correct, except to be clear it's not a data race because of the atomics.

> The only alternative to this would be bridging each element as
> it’s requested, but that’s ultimately just a trade-off (and has issues
> if people are relying on pointer equality). There has to be some toll
> here.
>
> However the construction of the _SwiftDeferredNSArray is
> hypothetically unnecessary, as alluded to in the comments on
> _SDNSArray. The class and its CAS pointer could be embedded in the
> native array buffer. 

That doesn't make creating it unneccessary; it only makes the separate
allocation unnecessary.  Whether or not it's actually needed is a
separate question.  When we first tested Swift without it there were
some bugs reported due to object identity of things bridged from value
types not being preserved.  We could try again to discover who's relying
on it and see whether we've reached the point where that code can be
changed not to rely on it.

> This would presumably incur some bloat on all native Arrays, but it
> might not be too bad (and platforms which don’t support _runtime(ObjC)
> presumably can omit it)? That said, I’m not 100% clear if we have the
> machinery to accomplish this yet or not. If anyone knows this, it
> would help a lot!

We do.

> (there’s also some special case singleton for empty arrays, that all seems 
> fine)
>
> See: 
>   ContiguousArrayBuffer.swift: _asCocoaArray
>   ContiguousArrayBuffer.swift: _getNonVerbatimBridgedHeapBuffer
>   SwiftNativeNSArray: _SwiftDeferredNSArray (the class that wraps the 
> storage)
>
> Dictionary/Set: Looks to be pretty much the same thing as Array,
> except that the old indexing model led to a double-indirection being
> baked into the design, so a wrapper class doesn’t need to be
> constructed in the non-verbatim case.
> (_NativeDictionaryStorageOwner contains the CAS-pointer). (toll free
> as can be!)

I didn't know that, but it sounds plausible.

> But this means that cleaning up all the gunk from the old indexing
> model and removing this indirection will lead to a regression in
> bridging performance *unless* Dictionary/Set gets the kind of
> optimizations discussed for Array. 

I wouldn't worry about this particular cost.  Bridging values into
Objective-C is already very expensive unless none of the values are
actually used, which is rare to say the least.

> The class inlining optimization also seem more acceptable for
> Dictionary, since it’s necessarily a more bloated allocation than
> Array (less overhead by %).

Yes.  And given the scale of expense occurred the first time an element
is requested from ObjC, it probably doesn't make sense for Dictionary
either.  Embedding the NS class in the Swift data structure's buffer
can also keep some memory alive longer than necessary.  I don't think we
should do this optimization.

>
>
> See: 
>   HashedCollections.swift.gyb: _bridgeToObjectiveCImpl
>   HashedCollections.swift.gyb: _Native${Self}StorageOwner (the “outer” 
> class)
>
> String: Unconditionally construct a class that wraps the String’s storage. 
> (not toll free)
>
> This just seems bad, and as far as I can tell isn’t expected. 

As I told you, it isn't.

> It seems to be the result of _StringBuffer (the lowest-level type in
> the String abstraction stack that still actually knows it’s a string)
> being a struct, and not a class that inherits from _HeapBuffer 

? _HeapBuffer is a struct; you can't inherit from it.  You must mean
_HeapBufferStorage.  But there's an underlying _HeapBufferStorage in
_StringBuffer, and this class can be made a subclass of NSString.

> due to some problems with deriving from generic classes. I’m not 100%
> sure what the “fix” for this is supposed to be.
>
> I think any fix will necessarily lead to String 

Re: [swift-dev] swift (ABI) and Windows

2016-10-07 Thread Paul Menage via swift-dev
On Tue, Apr 26, 2016 at 8:49 AM, John McCall via swift-dev
 wrote:
>
> I think it's reasonable to assume that @_silgen_name is not being used for
> objects that are external to the declaring module.  That is, the
> implementation model is that those declarations really are declaring a Swift
> function; it just happens that the actual body (if not provided) is provided
> magically.  That should work for all the standard library use cases.

So what's the cleanest way to make this work in practice? I
experimented with the following hack, which worked for building the
stdlib and the SDK overlay but which is full of layer violations:

- Add a symbol tracking hook in SILGenNameAttr, such that when the
hook is active, whenever we encounter a _silgen_name() declaration we
record it in a set.

- Enable this symbol tracking just for the duration of parsing the
main module. Thus we end up with a set of all _silgen_name attributes
on functions declared in the current module, but not _silgen_name
attributes on functions imported from other modules.

- At various points in lib/IRGen/GenDecl.cc
(updateLinkageForDefinition, LinkInfo::createFunction,
LinkInfo::createVariable) check whether the symbol being used is in
the list of _silgen_name attributes from the current module, and if so
ignore the dll-import tag on the symbol when setting up the
llvm::GlobalValue.

It would be nicer to walk across the main module after parsing it to
find SILGenNameAttr instances, but I don't have a good idea how to
start with that. Then we could perhaps add the list of attributes to
the llvm::Module as some kind of llvm::Metadata object?

Paul
___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] [semantic-arc][proposal] High Level ARC Memory Operations

2016-10-07 Thread John McCall via swift-dev

> On Oct 7, 2016, at 2:38 PM, Michael Gottesman  wrote:
> 
> Attached below is an updated version of the proposal. Again a rendered 
> version is located at:
> 
> https://gottesmm.github.io/proposals/high-level-arc-memory-operations.html 
> 
> 
> Michael
> 
> 
> 
> # Summary
> 
> This document proposes:
> 
> 1. adding the following ownership qualifiers to `load`: `[take]`, `[copy]`,
>`[borrow]`, `[trivial]`.
> 2. adding the following ownership qualifiers to `store`: `[init]`, `[assign]`,
>`[trivial]`.
> 3. requiring all `load` and `store` operations to have ownership qualifiers.
> 4. banning the use of `load [trivial]`, `store [trivial]` on memory locations 
> of
>`non-trivial` type.
> 
> This will allow for:
> 
> 1. eliminating optimizer miscompiles that occur due to releases being moved 
> into
>the region in between a `load`/`retain`, `load`/`release`,
>`store`/`release`. (For a specific example, see the appendix).
> 2. explicitly modeling `load [trivial]`/`store [trivial]` as having `unsafe
>unowned` ownership semantics. This will be enforced via the verifier.
> 3. more aggressive ARC code motion.
> 
> # Definitions
> 
> ## ownership qualified load
> 
> We propose four different ownership qualifiers for load. Define `load 
> [trivial]`
> as:
> 
> %x = load [trivial] %x_ptr : $*Int
> 
>   =>
> 
> %x = load %x_ptr : $*Int
> 
> A `load [trivial]` can not be used to load values of non-trivial type.

Should we mandate the reverse as well, that e.g. load [copy] cannot be used to
load values of trivial type?  That's a little more work for substituting 
cloners, but it
keeps everything nice and canonical.

> Define
> `load [copy]` as:
> 
> %x = load [copy] %x_ptr : $*C
> 
>   =>
> 
> %x = load %x_ptr : $*C
> retain_value %x : $C
> 
> Then define `load [take]` as:
> 
> %x = load [take] %x_ptr : $*Builtin.NativeObject
> 
>   =>
> 
> %x = load %x_ptr : $*Builtin.NativeObject
> 
> **NOTE** `load [take]` implies that the loaded from memory location no longer
> owns the result object (i.e. a take is a move). Loading from the memory 
> location
> again without reinitialization is illegal.
> 
> Next we provide `load [borrow]`:
> 
> %x = load [borrow] %x_ptr : $*Builtin.NativeObject
> ...
> endBorrow(%x, %x_ptr)
> 
>   =>
> 
> %x = load %x_ptr : $*Builtin.NativeObject
> ...
> endBorrow(%x, %x_ptr)
> 
> `load [borrow]` implies that in the region between the `load` and the
> `endBorrow`, the loaded object must semantically remain alive.

For consistency with other multi-word SIL instructions, this should be 
end_borrow.

I wonder whether it might make more sense for load [borrow] to be a different 
instruction.
There's a couple reasons for that first.  The first is that it's the only load 
which introduces
a scope, which is a really big difference structurally.  The second is that 
it's the only load
which returns a non-owned value, which will be a typing difference when we 
record
ownership in the type system.

Anyway, I really like that load [borrow] is scoped..  Are you planning to 
include the formation
restrictions on scopes instructions immediately, or will you do that in a later 
proposal?

The requirements we need from scopes are:
  - there has to be a well-defined set of IPs that lie within the scope and
  - there can't be a non-explicit transition into or out of the scope.

One way to get the first condition is to say that there has to be a unique 
scope-ender that
post-dominates the scope-beginner, but that's a pretty hard restriction for 
SILGen to satisfy
(as well as the optimizer, I imagine), and it doesn't handle "unreachable" or 
infinite loops.
We need to allow multiple scope-enders, and we need to allow scope-enders to be 
missing
in some cases.  Here's the right formalism, I think:

For all walks W beginning from the entry point of the function:
  For each node B in the CFG which is a scope-beginner:
Let E be the set of scope-enders for B, and consider just the sub-sequence 
S of nodes
of W where the node is a member of {B} U E.  Then the elements of S at even
positions (starting from 0) must be B, and the elements at odd positions 
must be
members of E.  Furthermore, if the walk ends in a return or throw 
instruction, then
S must have even length.

Note that for this to be true, all the scope-enders must be dominated by the 
scope-beginner.

It is sufficient to just consider the set of "beeline" paths, i.e. acyclic 
paths ending in either a true
terminator (a return, throw, or unreachable) or an edge back to a node already 
in the path.
No such path may include multiple scope-enders for the same scope-beginner.  If 
the path ends
in a return or throw, it must include a matching scope-ender after every 
scope-beginner.  If
it ends in a loop back, then for every scope-beginner in the path, if the path 
contains a 

[swift-dev] @swift-ci now supports clean workspace for "smoke test" and "test and merge"

2016-10-07 Thread mishal_shah via swift-dev
@swift-ci now supports clean workspace for "smoke test" and "test and merge”, 
by using following trigger phrase. 

New:
@swift-ci Please clean smoke test
@swift-ci Please clean smoke test macOS
@swift-ci Please clean smoke test Linux
@swift-ci Please clean smoke test and merge
@swift-ci Please clean test and merge

Full list:
@swift-ci Please clean test
@swift-ci Please clean test macOS
@swift-ci Please clean test Linux
@swift-ci Please clean smoke test
@swift-ci Please clean smoke test macOS
@swift-ci Please clean smoke test Linux
@swift-ci Please clean smoke test and merge
@swift-ci Please clean test and merge

Currently this is only setup for https://github.com/apple/swift 
 repository.

Thanks, 
Mishal Shah___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] @swift-ci now supports clean workspace for "smoke test" and "test and merge"

2016-10-07 Thread Enrico Granata via swift-dev
On that subject of trigger phrases, I think a while ago you sent out a way to 
do cross-repository testing, e.g. "test pull request 123 on apple/swift 
*together with* pull request 136 on apple/swift-lldb"

If that is indeed possible, can I please ask for a refresher on how to achieve 
it? (and maybe, a suggestion to have all of these magic incantations listed 
somewhere for posterity?)

> On Oct 7, 2016, at 5:18 PM, mishal_shah via swift-dev  
> wrote:
> 
> @swift-ci now supports clean workspace for "smoke test" and "test and merge”, 
> by using following trigger phrase. 
> 
> New:
> @swift-ci Please clean smoke test
> @swift-ci Please clean smoke test macOS
> @swift-ci Please clean smoke test Linux
> @swift-ci Please clean smoke test and merge
> @swift-ci Please clean test and merge
> 
> Full list:
> @swift-ci Please clean test
> @swift-ci Please clean test macOS
> @swift-ci Please clean test Linux
> @swift-ci Please clean smoke test
> @swift-ci Please clean smoke test macOS
> @swift-ci Please clean smoke test Linux
> @swift-ci Please clean smoke test and merge
> @swift-ci Please clean test and merge
> 
> Currently this is only setup for https://github.com/apple/swift 
>  repository.
> 
> Thanks, 
> Mishal Shah
> ___
> swift-dev mailing list
> swift-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-dev


Thanks,
- Enrico
📩 egranata@.com ☎️ 27683

___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] @swift-ci now supports clean workspace for "smoke test" and "test and merge"

2016-10-07 Thread mishal_shah via swift-dev
Hi Enrico,

Here is the doc for CI: 
https://github.com/apple/swift/blob/master/docs/ContinuousIntegration.md

Thanks, 
Mishal Shah
> On Oct 7, 2016, at 5:20 PM, Enrico Granata  wrote:
> 
> On that subject of trigger phrases, I think a while ago you sent out a way to 
> do cross-repository testing, e.g. "test pull request 123 on apple/swift 
> *together with* pull request 136 on apple/swift-lldb"
> 
> If that is indeed possible, can I please ask for a refresher on how to 
> achieve it? (and maybe, a suggestion to have all of these magic incantations 
> listed somewhere for posterity?)
> 
>> On Oct 7, 2016, at 5:18 PM, mishal_shah via swift-dev > > wrote:
>> 
>> @swift-ci now supports clean workspace for "smoke test" and "test and 
>> merge”, by using following trigger phrase. 
>> 
>> New:
>> @swift-ci Please clean smoke test
>> @swift-ci Please clean smoke test macOS
>> @swift-ci Please clean smoke test Linux
>> @swift-ci Please clean smoke test and merge
>> @swift-ci Please clean test and merge
>> 
>> Full list:
>> @swift-ci Please clean test
>> @swift-ci Please clean test macOS
>> @swift-ci Please clean test Linux
>> @swift-ci Please clean smoke test
>> @swift-ci Please clean smoke test macOS
>> @swift-ci Please clean smoke test Linux
>> @swift-ci Please clean smoke test and merge
>> @swift-ci Please clean test and merge
>> 
>> Currently this is only setup for https://github.com/apple/swift 
>>  repository.
>> 
>> Thanks, 
>> Mishal Shah
>> ___
>> swift-dev mailing list
>> swift-dev@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-dev
> 
> 
> Thanks,
> - Enrico
> 📩 egranata@.com ☎️ 27683
> 

___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] [semantic-arc][proposal] High Level ARC Memory Operations

2016-10-07 Thread Michael Gottesman via swift-dev

> On Oct 7, 2016, at 5:09 PM, John McCall  wrote:
> 
>> 
>> On Oct 7, 2016, at 2:38 PM, Michael Gottesman > > wrote:
>> 
>> Attached below is an updated version of the proposal. Again a rendered 
>> version is located at:
>> 
>> https://gottesmm.github.io/proposals/high-level-arc-memory-operations.html 
>> 
>> 
>> Michael
>> 
>> 
>> 
>> # Summary
>> 
>> This document proposes:
>> 
>> 1. adding the following ownership qualifiers to `load`: `[take]`, `[copy]`,
>>`[borrow]`, `[trivial]`.
>> 2. adding the following ownership qualifiers to `store`: `[init]`, 
>> `[assign]`,
>>`[trivial]`.
>> 3. requiring all `load` and `store` operations to have ownership qualifiers.
>> 4. banning the use of `load [trivial]`, `store [trivial]` on memory 
>> locations of
>>`non-trivial` type.
>> 
>> This will allow for:
>> 
>> 1. eliminating optimizer miscompiles that occur due to releases being moved 
>> into
>>the region in between a `load`/`retain`, `load`/`release`,
>>`store`/`release`. (For a specific example, see the appendix).
>> 2. explicitly modeling `load [trivial]`/`store [trivial]` as having `unsafe
>>unowned` ownership semantics. This will be enforced via the verifier.
>> 3. more aggressive ARC code motion.
>> 
>> # Definitions
>> 
>> ## ownership qualified load
>> 
>> We propose four different ownership qualifiers for load. Define `load 
>> [trivial]`
>> as:
>> 
>> %x = load [trivial] %x_ptr : $*Int
>> 
>>   =>
>> 
>> %x = load %x_ptr : $*Int
>> 
>> A `load [trivial]` can not be used to load values of non-trivial type.
> 
> Should we mandate the reverse as well, that e.g. load [copy] cannot be used to
> load values of trivial type?  That's a little more work for substituting 
> cloners, but it
> keeps everything nice and canonical.

No. I think that in the trivial case, load [copy] optimizes to load [trivial] 
as a canonicalization. This is just like applying a retain_value to a trivial 
type.

> 
>> Define
>> `load [copy]` as:
>> 
>> %x = load [copy] %x_ptr : $*C
>> 
>>   =>
>> 
>> %x = load %x_ptr : $*C
>> retain_value %x : $C
>> 
>> Then define `load [take]` as:
>> 
>> %x = load [take] %x_ptr : $*Builtin.NativeObject
>> 
>>   =>
>> 
>> %x = load %x_ptr : $*Builtin.NativeObject
>> 
>> **NOTE** `load [take]` implies that the loaded from memory location no longer
>> owns the result object (i.e. a take is a move). Loading from the memory 
>> location
>> again without reinitialization is illegal.
>> 
>> Next we provide `load [borrow]`:
>> 
>> %x = load [borrow] %x_ptr : $*Builtin.NativeObject
>> ...
>> endBorrow(%x, %x_ptr)
>> 
>>   =>
>> 
>> %x = load %x_ptr : $*Builtin.NativeObject
>> ...
>> endBorrow(%x, %x_ptr)
>> 
>> `load [borrow]` implies that in the region between the `load` and the
>> `endBorrow`, the loaded object must semantically remain alive.
> 
> For consistency with other multi-word SIL instructions, this should be 
> end_borrow.

Sure.

> 
> I wonder whether it might make more sense for load [borrow] to be a different 
> instruction.
> There's a couple reasons for that first.  The first is that it's the only 
> load which introduces
> a scope, which is a really big difference structurally.  The second is that 
> it's the only load
> which returns a non-owned value, which will be a typing difference when we 
> record
> ownership in the type system.

I am fine with a load_borrow. If this is the only change left that you want can 
I just send out a proposal with that small change and start implementing. I am 
nervous about perfection being the enemy of the good (and I want to start 
implementing this weekend if possible *evil smile*).

> 
> Anyway, I really like that load [borrow] is scoped..  Are you planning to 
> include the formation
> restrictions on scopes instructions immediately, or will you do that in a 
> later proposal?

It will be done in a later proposal. We are just trying to set the stage for 
verification.

> 
> The requirements we need from scopes are:
>   - there has to be a well-defined set of IPs that lie within the scope and
>   - there can't be a non-explicit transition into or out of the scope.
> 
> One way to get the first condition is to say that there has to be a unique 
> scope-ender that
> post-dominates the scope-beginner, but that's a pretty hard restriction for 
> SILGen to satisfy
> (as well as the optimizer, I imagine), and it doesn't handle "unreachable" or 
> infinite loops.
> We need to allow multiple scope-enders, and we need to allow scope-enders to 
> be missing
> in some cases.

I agree with you here. We definitely want to be able to support multiple 
scope-enders.

>  Here's the right formalism, I think:
> 
> For all walks W beginning from the entry point of the function:
>   For each node B in the CFG which is a scope-beginner:
> Let E be the set of scope-ender

Re: [swift-dev] @swift-ci now supports clean workspace for "smoke test" and "test and merge"

2016-10-07 Thread Michael Gottesman via swift-dev
I added a section explaining what a smoke test is. Can you add a section 
describing what a clean smoke test is as well?
> On Oct 7, 2016, at 5:24 PM, mishal_shah via swift-dev  
> wrote:
> 
> Hi Enrico,
> 
> Here is the doc for CI: 
> https://github.com/apple/swift/blob/master/docs/ContinuousIntegration.md 
> 
> 
> Thanks, 
> Mishal Shah
>> On Oct 7, 2016, at 5:20 PM, Enrico Granata > > wrote:
>> 
>> On that subject of trigger phrases, I think a while ago you sent out a way 
>> to do cross-repository testing, e.g. "test pull request 123 on apple/swift 
>> *together with* pull request 136 on apple/swift-lldb"
>> 
>> If that is indeed possible, can I please ask for a refresher on how to 
>> achieve it? (and maybe, a suggestion to have all of these magic incantations 
>> listed somewhere for posterity?)
>> 
>>> On Oct 7, 2016, at 5:18 PM, mishal_shah via swift-dev >> > wrote:
>>> 
>>> @swift-ci now supports clean workspace for "smoke test" and "test and 
>>> merge”, by using following trigger phrase. 
>>> 
>>> New:
>>> @swift-ci Please clean smoke test
>>> @swift-ci Please clean smoke test macOS
>>> @swift-ci Please clean smoke test Linux
>>> @swift-ci Please clean smoke test and merge
>>> @swift-ci Please clean test and merge
>>> 
>>> Full list:
>>> @swift-ci Please clean test
>>> @swift-ci Please clean test macOS
>>> @swift-ci Please clean test Linux
>>> @swift-ci Please clean smoke test
>>> @swift-ci Please clean smoke test macOS
>>> @swift-ci Please clean smoke test Linux
>>> @swift-ci Please clean smoke test and merge
>>> @swift-ci Please clean test and merge
>>> 
>>> Currently this is only setup for https://github.com/apple/swift 
>>>  repository.
>>> 
>>> Thanks, 
>>> Mishal Shah
>>> ___
>>> swift-dev mailing list
>>> swift-dev@swift.org 
>>> https://lists.swift.org/mailman/listinfo/swift-dev 
>>> 
>> 
>> 
>> Thanks,
>> - Enrico
>> 📩 egranata@.com ☎️ 27683
>> 
> 
> ___
> swift-dev mailing list
> swift-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-dev

___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] [semantic-arc][proposal] High Level ARC Memory Operations

2016-10-07 Thread John McCall via swift-dev
> On Oct 7, 2016, at 6:04 PM, Michael Gottesman  wrote:
>> On Oct 7, 2016, at 5:09 PM, John McCall > > wrote:
>>> On Oct 7, 2016, at 2:38 PM, Michael Gottesman >> > wrote:
>>> 
>>> Attached below is an updated version of the proposal. Again a rendered 
>>> version is located at:
>>> 
>>> https://gottesmm.github.io/proposals/high-level-arc-memory-operations.html 
>>> 
>>> 
>>> Michael
>>> 
>>> 
>>> 
>>> # Summary
>>> 
>>> This document proposes:
>>> 
>>> 1. adding the following ownership qualifiers to `load`: `[take]`, `[copy]`,
>>>`[borrow]`, `[trivial]`.
>>> 2. adding the following ownership qualifiers to `store`: `[init]`, 
>>> `[assign]`,
>>>`[trivial]`.
>>> 3. requiring all `load` and `store` operations to have ownership qualifiers.
>>> 4. banning the use of `load [trivial]`, `store [trivial]` on memory 
>>> locations of
>>>`non-trivial` type.
>>> 
>>> This will allow for:
>>> 
>>> 1. eliminating optimizer miscompiles that occur due to releases being moved 
>>> into
>>>the region in between a `load`/`retain`, `load`/`release`,
>>>`store`/`release`. (For a specific example, see the appendix).
>>> 2. explicitly modeling `load [trivial]`/`store [trivial]` as having `unsafe
>>>unowned` ownership semantics. This will be enforced via the verifier.
>>> 3. more aggressive ARC code motion.
>>> 
>>> # Definitions
>>> 
>>> ## ownership qualified load
>>> 
>>> We propose four different ownership qualifiers for load. Define `load 
>>> [trivial]`
>>> as:
>>> 
>>> %x = load [trivial] %x_ptr : $*Int
>>> 
>>>   =>
>>> 
>>> %x = load %x_ptr : $*Int
>>> 
>>> A `load [trivial]` can not be used to load values of non-trivial type.
>> 
>> Should we mandate the reverse as well, that e.g. load [copy] cannot be used 
>> to
>> load values of trivial type?  That's a little more work for substituting 
>> cloners, but it
>> keeps everything nice and canonical.
> 
> No. I think that in the trivial case, load [copy] optimizes to load [trivial] 
> as a canonicalization. This is just like applying a retain_value to a trivial 
> type.

I guess I'm fine with that.

>>> Define
>>> `load [copy]` as:
>>> 
>>> %x = load [copy] %x_ptr : $*C
>>> 
>>>   =>
>>> 
>>> %x = load %x_ptr : $*C
>>> retain_value %x : $C
>>> 
>>> Then define `load [take]` as:
>>> 
>>> %x = load [take] %x_ptr : $*Builtin.NativeObject
>>> 
>>>   =>
>>> 
>>> %x = load %x_ptr : $*Builtin.NativeObject
>>> 
>>> **NOTE** `load [take]` implies that the loaded from memory location no 
>>> longer
>>> owns the result object (i.e. a take is a move). Loading from the memory 
>>> location
>>> again without reinitialization is illegal.
>>> 
>>> Next we provide `load [borrow]`:
>>> 
>>> %x = load [borrow] %x_ptr : $*Builtin.NativeObject
>>> ...
>>> endBorrow(%x, %x_ptr)
>>> 
>>>   =>
>>> 
>>> %x = load %x_ptr : $*Builtin.NativeObject
>>> ...
>>> endBorrow(%x, %x_ptr)
>>> 
>>> `load [borrow]` implies that in the region between the `load` and the
>>> `endBorrow`, the loaded object must semantically remain alive.
>> 
>> For consistency with other multi-word SIL instructions, this should be 
>> end_borrow.
> 
> Sure.
> 
>> 
>> I wonder whether it might make more sense for load [borrow] to be a 
>> different instruction.
>> There's a couple reasons for that first.  The first is that it's the only 
>> load which introduces
>> a scope, which is a really big difference structurally.  The second is that 
>> it's the only load
>> which returns a non-owned value, which will be a typing difference when we 
>> record
>> ownership in the type system.
> 
> I am fine with a load_borrow. If this is the only change left that you want 
> can I just send out a proposal with that small change and start implementing. 
> I am nervous about perfection being the enemy of the good (and I want to 
> start implementing this weekend if possible *evil smile*).

Yes, it's fine to introduce this incrementally.

We can discuss the formation rules on scopes concurrently.  I think the same 
theoretical
foundation is probably what we'll use for pseudo-linearity, 
memory-initialization soundness,
and so on.

John.

>> Anyway, I really like that load [borrow] is scoped..  Are you planning to 
>> include the formation
>> restrictions on scopes instructions immediately, or will you do that in a 
>> later proposal?
> 
> It will be done in a later proposal. We are just trying to set the stage for 
> verification.
> 
>> 
>> The requirements we need from scopes are:
>>   - there has to be a well-defined set of IPs that lie within the scope and
>>   - there can't be a non-explicit transition into or out of the scope.
>> 
>> One way to get the first condition is to say that there has to be a unique 
>> scope-ender that
>> post-dominates the scope-beginner, but that's a pretty hard restriction for 
>> SILGen

Re: [swift-dev] [semantic-arc][proposal] High Level ARC Memory Operations

2016-10-07 Thread Andrew Trick via swift-dev

> On Oct 7, 2016, at 6:04 PM, Michael Gottesman via swift-dev 
>  wrote:
> 
>> I wonder whether it might make more sense for load [borrow] to be a 
>> different instruction.
>> There's a couple reasons for that first.  The first is that it's the only 
>> load which introduces
>> a scope, which is a really big difference structurally.  The second is that 
>> it's the only load
>> which returns a non-owned value, which will be a typing difference when we 
>> record
>> ownership in the type system.
> 
> I am fine with a load_borrow. If this is the only change left that you want 
> can I just send out a proposal with that small change and start implementing. 
> I am nervous about perfection being the enemy of the good (and I want to 
> start implementing this weekend if possible *evil smile*).

There’s a lot in the proposal that makes sense to discuss for completeness but 
isn’t motivated by a particular need. Please separate functionality. We only 
need load [copy] at first right? When do those need to be promoted to 
load_borrow? load [trivial] is an optimization, so that should follow a 
functionally complete implementation.  load [take] should definitely not exist 
until there’s some motivation.

-Andy___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] [semantic-arc][proposal] High Level ARC Memory Operations

2016-10-07 Thread Michael Gottesman via swift-dev

> On Oct 7, 2016, at 9:25 PM, Andrew Trick  wrote:
> 
> 
>> On Oct 7, 2016, at 6:04 PM, Michael Gottesman via swift-dev 
>> mailto:swift-dev@swift.org>> wrote:
>> 
>>> I wonder whether it might make more sense for load [borrow] to be a 
>>> different instruction.
>>> There's a couple reasons for that first.  The first is that it's the only 
>>> load which introduces
>>> a scope, which is a really big difference structurally.  The second is that 
>>> it's the only load
>>> which returns a non-owned value, which will be a typing difference when we 
>>> record
>>> ownership in the type system.
>> 
>> I am fine with a load_borrow. If this is the only change left that you want 
>> can I just send out a proposal with that small change and start 
>> implementing. I am nervous about perfection being the enemy of the good (and 
>> I want to start implementing this weekend if possible *evil smile*).
> 
> There’s a lot in the proposal that makes sense to discuss for completeness 
> but isn’t motivated by a particular need. Please separate functionality. We 
> only need load [copy] at first right? When do those need to be promoted to 
> load_borrow?

These are needed for the ARC optimizer to eliminate retain, release operations, 
i.e. a:

%0 = load [copy] %x_ptr

destroy_value %1

=>

%0 = load [borrow] %x_ptr

borrow_end(%0, %x_ptr)

These constructs will be needed by engineers to update passes like ARC. By 
implementing such modifiers now, we can begin to implement support in the 
various passes for these new instructions via sil-opt/etc in parallel to other 
semantic ARC work.

> load [trivial] is an optimization, so that should follow a functionally 
> complete implementation.

Yes you are correct that given that we are exploding the load [copy] in the 
eliminator, the trivial load is not *strictly* needed. But as soon as we start 
upgrading passes, we are going to want this. Again assuming that parallel work 
can be done, it makes sense to set the stage for optimizer work that will occur 
in parallel to further semantic ARC work.

>  load [take] should definitely not exist until there’s some motivation.

If you look at the frontend, there are places where the frontend wants to emit 
a take. Unless we are willing to use unqualified loads for those cases (which 
we can not if we are trying to prove that no unqualified loads are emitted by 
the frontend), then we must have a load [take].

Did I provide the motivation that you requested?

Michael

> 
> -Andy

___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] [semantic-arc][proposal] High Level ARC Memory Operations

2016-10-07 Thread Andrew Trick via swift-dev

> On Oct 7, 2016, at 10:08 PM, Michael Gottesman  wrote:
> 
>> 
>> On Oct 7, 2016, at 9:25 PM, Andrew Trick > > wrote:
>> 
>> 
>>> On Oct 7, 2016, at 6:04 PM, Michael Gottesman via swift-dev 
>>> mailto:swift-dev@swift.org>> wrote:
>>> 
 I wonder whether it might make more sense for load [borrow] to be a 
 different instruction.
 There's a couple reasons for that first.  The first is that it's the only 
 load which introduces
 a scope, which is a really big difference structurally.  The second is 
 that it's the only load
 which returns a non-owned value, which will be a typing difference when we 
 record
 ownership in the type system.
>>> 
>>> I am fine with a load_borrow. If this is the only change left that you want 
>>> can I just send out a proposal with that small change and start 
>>> implementing. I am nervous about perfection being the enemy of the good 
>>> (and I want to start implementing this weekend if possible *evil smile*).
>> 
>> There’s a lot in the proposal that makes sense to discuss for completeness 
>> but isn’t motivated by a particular need. Please separate functionality. We 
>> only need load [copy] at first right? When do those need to be promoted to 
>> load_borrow?
> 
> These are needed for the ARC optimizer to eliminate retain, release 
> operations, i.e. a:
> 
> %0 = load [copy] %x_ptr
> 
> destroy_value %1
> 
> =>
> 
> %0 = load [borrow] %x_ptr
> 
> borrow_end(%0, %x_ptr)
> 
> These constructs will be needed by engineers to update passes like ARC. By 
> implementing such modifiers now, we can begin to implement support in the 
> various passes for these new instructions via sil-opt/etc in parallel to 
> other semantic ARC work.
> 
>> load [trivial] is an optimization, so that should follow a functionally 
>> complete implementation. 
> 
> Yes you are correct that given that we are exploding the load [copy] in the 
> eliminator, the trivial load is not *strictly* needed. But as soon as we 
> start upgrading passes, we are going to want this. Again assuming that 
> parallel work can be done, it makes sense to set the stage for optimizer work 
> that will occur in parallel to further semantic ARC work.
> 
>>  load [take] should definitely not exist until there’s some motivation.
> 
> If you look at the frontend, there are places where the frontend wants to 
> emit a take. Unless we are willing to use unqualified loads for those cases 
> (which we can not if we are trying to prove that no unqualified loads are 
> emitted by the frontend), then we must have a load [take].
> 
> Did I provide the motivation that you requested?

Yes. My general request is for each commit to be easy to review and the 
functionality obvious to test. I’m convinced we’ll eventually want the 
variants. Although I still want to understand better when we need to [take] 
values out of memory.

I also want to prove that my understanding of the model is accurate by seeing 
everything work with load [copy].

-Andy___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] [semantic-arc][proposal] High Level ARC Memory Operations

2016-10-07 Thread Michael Gottesman via swift-dev

> On Oct 7, 2016, at 10:26 PM, Andrew Trick  wrote:
> 
> 
>> On Oct 7, 2016, at 10:08 PM, Michael Gottesman > > wrote:
>> 
>>> 
>>> On Oct 7, 2016, at 9:25 PM, Andrew Trick >> > wrote:
>>> 
>>> 
 On Oct 7, 2016, at 6:04 PM, Michael Gottesman via swift-dev 
 mailto:swift-dev@swift.org>> wrote:
 
> I wonder whether it might make more sense for load [borrow] to be a 
> different instruction.
> There's a couple reasons for that first.  The first is that it's the only 
> load which introduces
> a scope, which is a really big difference structurally.  The second is 
> that it's the only load
> which returns a non-owned value, which will be a typing difference when 
> we record
> ownership in the type system.
 
 I am fine with a load_borrow. If this is the only change left that you 
 want can I just send out a proposal with that small change and start 
 implementing. I am nervous about perfection being the enemy of the good 
 (and I want to start implementing this weekend if possible *evil smile*).
>>> 
>>> There’s a lot in the proposal that makes sense to discuss for completeness 
>>> but isn’t motivated by a particular need. Please separate functionality. We 
>>> only need load [copy] at first right? When do those need to be promoted to 
>>> load_borrow?
>> 
>> These are needed for the ARC optimizer to eliminate retain, release 
>> operations, i.e. a:
>> 
>> %0 = load [copy] %x_ptr
>> 
>> destroy_value %1
>> 
>> =>
>> 
>> %0 = load [borrow] %x_ptr
>> 
>> borrow_end(%0, %x_ptr)
>> 
>> These constructs will be needed by engineers to update passes like ARC. By 
>> implementing such modifiers now, we can begin to implement support in the 
>> various passes for these new instructions via sil-opt/etc in parallel to 
>> other semantic ARC work.
>> 
>>> load [trivial] is an optimization, so that should follow a functionally 
>>> complete implementation. 
>> 
>> Yes you are correct that given that we are exploding the load [copy] in the 
>> eliminator, the trivial load is not *strictly* needed. But as soon as we 
>> start upgrading passes, we are going to want this. Again assuming that 
>> parallel work can be done, it makes sense to set the stage for optimizer 
>> work that will occur in parallel to further semantic ARC work.
>> 
>>>  load [take] should definitely not exist until there’s some motivation.
>> 
>> If you look at the frontend, there are places where the frontend wants to 
>> emit a take. Unless we are willing to use unqualified loads for those cases 
>> (which we can not if we are trying to prove that no unqualified loads are 
>> emitted by the frontend), then we must have a load [take].
>> 
>> Did I provide the motivation that you requested?
> 
> Yes. My general request is for each commit to be easy to review and the 
> functionality obvious to test. I’m convinced we’ll eventually want the 
> variants. Although I still want to understand better when we need to [take] 
> values out of memory.

Just as a quick example, the API for emitLoad in SILGenFunction:

  ManagedValue emitLoad(SILLocation loc, SILValue addr,
const TypeLowering &rvalueTL,
SGFContext C, IsTake_t isTake,
bool isGuaranteedValid = false);

Notice the IsTake_t parameter. I see that code path used in several locations 
in SILGenFunction.

> 
> I also want to prove that my understanding of the model is accurate by seeing 
> everything work with load [copy].

I am fine doing everything initially with load [copy] (and when SILGen requires 
load [take]). The other things can wait until we need them. I just don't want 
to have to do another proposal at that point ; ).

> 
> -Andy

___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] [semantic-arc][proposal] High Level ARC Memory Operations

2016-10-07 Thread John McCall via swift-dev
> On Oct 7, 2016, at 10:36 PM, Michael Gottesman  wrote:
>> On Oct 7, 2016, at 10:26 PM, Andrew Trick > > wrote:
>> 
>> 
>>> On Oct 7, 2016, at 10:08 PM, Michael Gottesman >> > wrote:
>>> 
 
 On Oct 7, 2016, at 9:25 PM, Andrew Trick >>> > wrote:
 
 
> On Oct 7, 2016, at 6:04 PM, Michael Gottesman via swift-dev 
> mailto:swift-dev@swift.org>> wrote:
> 
>> I wonder whether it might make more sense for load [borrow] to be a 
>> different instruction.
>> There's a couple reasons for that first.  The first is that it's the 
>> only load which introduces
>> a scope, which is a really big difference structurally.  The second is 
>> that it's the only load
>> which returns a non-owned value, which will be a typing difference when 
>> we record
>> ownership in the type system.
> 
> I am fine with a load_borrow. If this is the only change left that you 
> want can I just send out a proposal with that small change and start 
> implementing. I am nervous about perfection being the enemy of the good 
> (and I want to start implementing this weekend if possible *evil smile*).
 
 There’s a lot in the proposal that makes sense to discuss for completeness 
 but isn’t motivated by a particular need. Please separate functionality. 
 We only need load [copy] at first right? When do those need to be promoted 
 to load_borrow?
>>> 
>>> These are needed for the ARC optimizer to eliminate retain, release 
>>> operations, i.e. a:
>>> 
>>> %0 = load [copy] %x_ptr
>>> 
>>> destroy_value %1
>>> 
>>> =>
>>> 
>>> %0 = load [borrow] %x_ptr
>>> 
>>> borrow_end(%0, %x_ptr)
>>> 
>>> These constructs will be needed by engineers to update passes like ARC. By 
>>> implementing such modifiers now, we can begin to implement support in the 
>>> various passes for these new instructions via sil-opt/etc in parallel to 
>>> other semantic ARC work.
>>> 
 load [trivial] is an optimization, so that should follow a functionally 
 complete implementation. 
>>> 
>>> Yes you are correct that given that we are exploding the load [copy] in the 
>>> eliminator, the trivial load is not *strictly* needed. But as soon as we 
>>> start upgrading passes, we are going to want this. Again assuming that 
>>> parallel work can be done, it makes sense to set the stage for optimizer 
>>> work that will occur in parallel to further semantic ARC work.
>>> 
  load [take] should definitely not exist until there’s some motivation.
>>> 
>>> If you look at the frontend, there are places where the frontend wants to 
>>> emit a take. Unless we are willing to use unqualified loads for those cases 
>>> (which we can not if we are trying to prove that no unqualified loads are 
>>> emitted by the frontend), then we must have a load [take].
>>> 
>>> Did I provide the motivation that you requested?
>> 
>> Yes. My general request is for each commit to be easy to review and the 
>> functionality obvious to test. I’m convinced we’ll eventually want the 
>> variants. Although I still want to understand better when we need to [take] 
>> values out of memory.
> 
> Just as a quick example, the API for emitLoad in SILGenFunction:
> 
>   ManagedValue emitLoad(SILLocation loc, SILValue addr,
> const TypeLowering &rvalueTL,
> SGFContext C, IsTake_t isTake,
> bool isGuaranteedValid = false);
> 
> Notice the IsTake_t parameter. I see that code path used in several locations 
> in SILGenFunction.
> 
>> 
>> I also want to prove that my understanding of the model is accurate by 
>> seeing everything work with load [copy].
> 
> I am fine doing everything initially with load [copy] (and when SILGen 
> requires load [take]). The other things can wait until we need them. I just 
> don't want to have to do another proposal at that point ; ).

Well, you might as well *implement* load [trivial] now.  It's literally going 
to be, like, five lines in various switch statements plus an obvious case in 
the verifier.  You can incrementally move things over to actually start *using* 
load [trivial] whenever you like.

John.___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] [semantic-arc][proposal] High Level ARC Memory Operations

2016-10-07 Thread Andrew Trick via swift-dev

> On Oct 7, 2016, at 10:36 PM, Michael Gottesman  wrote:
> 
>> 
>> On Oct 7, 2016, at 10:26 PM, Andrew Trick > > wrote:
>> 
>> 
>>> On Oct 7, 2016, at 10:08 PM, Michael Gottesman >> > wrote:
>>> 
 
 On Oct 7, 2016, at 9:25 PM, Andrew Trick >>> > wrote:
 
 
> On Oct 7, 2016, at 6:04 PM, Michael Gottesman via swift-dev 
> mailto:swift-dev@swift.org>> wrote:
> 
>> I wonder whether it might make more sense for load [borrow] to be a 
>> different instruction.
>> There's a couple reasons for that first.  The first is that it's the 
>> only load which introduces
>> a scope, which is a really big difference structurally.  The second is 
>> that it's the only load
>> which returns a non-owned value, which will be a typing difference when 
>> we record
>> ownership in the type system.
> 
> I am fine with a load_borrow. If this is the only change left that you 
> want can I just send out a proposal with that small change and start 
> implementing. I am nervous about perfection being the enemy of the good 
> (and I want to start implementing this weekend if possible *evil smile*).
 
 There’s a lot in the proposal that makes sense to discuss for completeness 
 but isn’t motivated by a particular need. Please separate functionality. 
 We only need load [copy] at first right? When do those need to be promoted 
 to load_borrow?
>>> 
>>> These are needed for the ARC optimizer to eliminate retain, release 
>>> operations, i.e. a:
>>> 
>>> %0 = load [copy] %x_ptr
>>> 
>>> destroy_value %1
>>> 
>>> =>
>>> 
>>> %0 = load [borrow] %x_ptr
>>> 
>>> borrow_end(%0, %x_ptr)
>>> 
>>> These constructs will be needed by engineers to update passes like ARC. By 
>>> implementing such modifiers now, we can begin to implement support in the 
>>> various passes for these new instructions via sil-opt/etc in parallel to 
>>> other semantic ARC work.
>>> 
 load [trivial] is an optimization, so that should follow a functionally 
 complete implementation. 
>>> 
>>> Yes you are correct that given that we are exploding the load [copy] in the 
>>> eliminator, the trivial load is not *strictly* needed. But as soon as we 
>>> start upgrading passes, we are going to want this. Again assuming that 
>>> parallel work can be done, it makes sense to set the stage for optimizer 
>>> work that will occur in parallel to further semantic ARC work.
>>> 
  load [take] should definitely not exist until there’s some motivation.
>>> 
>>> If you look at the frontend, there are places where the frontend wants to 
>>> emit a take. Unless we are willing to use unqualified loads for those cases 
>>> (which we can not if we are trying to prove that no unqualified loads are 
>>> emitted by the frontend), then we must have a load [take].
>>> 
>>> Did I provide the motivation that you requested?
>> 
>> Yes. My general request is for each commit to be easy to review and the 
>> functionality obvious to test. I’m convinced we’ll eventually want the 
>> variants. Although I still want to understand better when we need to [take] 
>> values out of memory.
> 
> Just as a quick example, the API for emitLoad in SILGenFunction:
> 
>   ManagedValue emitLoad(SILLocation loc, SILValue addr,
> const TypeLowering &rvalueTL,
> SGFContext C, IsTake_t isTake,
> bool isGuaranteedValid = false);
> 
> Notice the IsTake_t parameter. I see that code path used in several locations 
> in SILGenFunction.

I guess it’s doing this to forward locals variables at their last use, avoiding 
a copy. Although probably not theoretically necessary, I guess it would be 
silly not to do this.
-Andy

>> 
>> I also want to prove that my understanding of the model is accurate by 
>> seeing everything work with load [copy].
> 
> I am fine doing everything initially with load [copy] (and when SILGen 
> requires load [take]). The other things can wait until we need them. I just 
> don't want to have to do another proposal at that point ; ).
> 
>> 
>> -Andy

___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] [semantic-arc][proposal] High Level ARC Memory Operations

2016-10-07 Thread John McCall via swift-dev
> On Oct 7, 2016, at 10:46 PM, Andrew Trick  wrote:
>> On Oct 7, 2016, at 10:36 PM, Michael Gottesman > > wrote:
>> 
>>> 
>>> On Oct 7, 2016, at 10:26 PM, Andrew Trick >> > wrote:
>>> 
>>> 
 On Oct 7, 2016, at 10:08 PM, Michael Gottesman >>> > wrote:
 
> 
> On Oct 7, 2016, at 9:25 PM, Andrew Trick  > wrote:
> 
> 
>> On Oct 7, 2016, at 6:04 PM, Michael Gottesman via swift-dev 
>> mailto:swift-dev@swift.org>> wrote:
>> 
>>> I wonder whether it might make more sense for load [borrow] to be a 
>>> different instruction.
>>> There's a couple reasons for that first.  The first is that it's the 
>>> only load which introduces
>>> a scope, which is a really big difference structurally.  The second is 
>>> that it's the only load
>>> which returns a non-owned value, which will be a typing difference when 
>>> we record
>>> ownership in the type system.
>> 
>> I am fine with a load_borrow. If this is the only change left that you 
>> want can I just send out a proposal with that small change and start 
>> implementing. I am nervous about perfection being the enemy of the good 
>> (and I want to start implementing this weekend if possible *evil smile*).
> 
> There’s a lot in the proposal that makes sense to discuss for 
> completeness but isn’t motivated by a particular need. Please separate 
> functionality. We only need load [copy] at first right? When do those 
> need to be promoted to load_borrow?
 
 These are needed for the ARC optimizer to eliminate retain, release 
 operations, i.e. a:
 
 %0 = load [copy] %x_ptr
 
 destroy_value %1
 
 =>
 
 %0 = load [borrow] %x_ptr
 
 borrow_end(%0, %x_ptr)
 
 These constructs will be needed by engineers to update passes like ARC. By 
 implementing such modifiers now, we can begin to implement support in the 
 various passes for these new instructions via sil-opt/etc in parallel to 
 other semantic ARC work.
 
> load [trivial] is an optimization, so that should follow a functionally 
> complete implementation. 
 
 Yes you are correct that given that we are exploding the load [copy] in 
 the eliminator, the trivial load is not *strictly* needed. But as soon as 
 we start upgrading passes, we are going to want this. Again assuming that 
 parallel work can be done, it makes sense to set the stage for optimizer 
 work that will occur in parallel to further semantic ARC work.
 
>  load [take] should definitely not exist until there’s some motivation.
 
 If you look at the frontend, there are places where the frontend wants to 
 emit a take. Unless we are willing to use unqualified loads for those 
 cases (which we can not if we are trying to prove that no unqualified 
 loads are emitted by the frontend), then we must have a load [take].
 
 Did I provide the motivation that you requested?
>>> 
>>> Yes. My general request is for each commit to be easy to review and the 
>>> functionality obvious to test. I’m convinced we’ll eventually want the 
>>> variants. Although I still want to understand better when we need to [take] 
>>> values out of memory.
>> 
>> Just as a quick example, the API for emitLoad in SILGenFunction:
>> 
>>   ManagedValue emitLoad(SILLocation loc, SILValue addr,
>> const TypeLowering &rvalueTL,
>> SGFContext C, IsTake_t isTake,
>> bool isGuaranteedValid = false);
>> 
>> Notice the IsTake_t parameter. I see that code path used in several 
>> locations in SILGenFunction.
> 
> I guess it’s doing this to forward locals variables at their last use, 
> avoiding a copy. Although probably not theoretically necessary, I guess it 
> would be silly not to do this.

Values, not variables.  SILGen can't do that kind of optimization on a local 
"let" or "var" because it's intentionally statement-by-statement.  It also 
can't do that kind of optimization on a "var" because, for all it knows, the 
variable might have escaped and thus not really have a statically-knowable last 
use; that's why SILGen emits them all as boxes and lets the mandatory optimizer 
promote them to the stack.  But there are several reasons why a local r-value 
might get emitted into memory and then need to get promoted to be a scalar, and 
of course we won't emit that as a copy.

John.___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


Re: [swift-dev] swift (ABI) and Windows

2016-10-07 Thread John McCall via swift-dev
> On Oct 7, 2016, at 4:08 PM, Paul Menage  wrote:
> On Tue, Apr 26, 2016 at 8:49 AM, John McCall via swift-dev
>  wrote:
>> 
>> I think it's reasonable to assume that @_silgen_name is not being used for
>> objects that are external to the declaring module.  That is, the
>> implementation model is that those declarations really are declaring a Swift
>> function; it just happens that the actual body (if not provided) is provided
>> magically.  That should work for all the standard library use cases.
> 
> So what's the cleanest way to make this work in practice? I
> experimented with the following hack, which worked for building the
> stdlib and the SDK overlay but which is full of layer violations:

Sorry, I could've been more clear.  For ordinary declarations, we know exactly
which module defines any symbols associated with them because we know
which module the declaration is in and ordinary declarations are always 
definitions.
A @_silgen_name declaration isn't itself a definition, but it's actually still
reasonable to assume that it's defined by the current module, which means
that as far as knowing where the symbol is defined goes, it really *is* a 
definition.
So there's no difference.

The right solution is for SILFunctions (well, at least the ones with public 
linkage)
to always carry a reference to their defining module.  IRGen can then just key 
off
of that + its knowledge of the current module when emitting the 
llvm::GlobalValue
for the thing.

John.

> 
> - Add a symbol tracking hook in SILGenNameAttr, such that when the
> hook is active, whenever we encounter a _silgen_name() declaration we
> record it in a set.
> 
> - Enable this symbol tracking just for the duration of parsing the
> main module. Thus we end up with a set of all _silgen_name attributes
> on functions declared in the current module, but not _silgen_name
> attributes on functions imported from other modules.
> 
> - At various points in lib/IRGen/GenDecl.cc
> (updateLinkageForDefinition, LinkInfo::createFunction,
> LinkInfo::createVariable) check whether the symbol being used is in
> the list of _silgen_name attributes from the current module, and if so
> ignore the dll-import tag on the symbol when setting up the
> llvm::GlobalValue.
> 
> It would be nicer to walk across the main module after parsing it to
> find SILGenNameAttr instances, but I don't have a good idea how to
> start with that. Then we could perhaps add the list of attributes to
> the llvm::Module as some kind of llvm::Metadata object?
> 
> Paul

___
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


[swift-dev] [discussion notes] SIL address types and borrowing

2016-10-07 Thread Andrew Trick via swift-dev
On swift-dev, John already sent out a great writeup on SIL SSA:
Representing "address-only" values in SIL.

While talking to John I also picked up a lot of insight into how
address types relate to SIL ownership and borrow checking. I finally
organized the information into these notes. This is not a
proposal. It's background information for those of us writing and
reviewing proposals. Just take it as a strawman for future
discussions. (There's also a good chance I'm getting something
wrong).

[My commentary in brackets.]

** Recap of address-only.

Divide address-only types into two categories:
1. By abstraction (compiler doesn't know the size).
2. The type is "memory-linked". i.e. the address is significant at runtime.
   - weak references (anything that registers its address).
   - C++ this.
   - Anything with interior pointers.
   - Any shared-borrowed value of a type with "nonmutating" properties.
 ["nonmutating" properties allow mutation of state attached to a value.
  Rust atomics are an example.]

Address-only will not be reflected in SIL types. SIL addresses should
only be used for formal memory (pointers, globals, class
properties, captures). We'll get to inout arguments later...

As with opaque types, when IRGen lowers a memory-linked borrowed type,
it needs to allocate storage.

Concern: SILGen has built-in tracking of managed values that automates
insertion of cleanups. Lowering address-only types after SILOpt would
require rediscovering that information based on CFG analysis. Is this
too heroic?

This was already described by John. Briefly recapping:

e.g. Constructung Optional

We want initialization should be in-place as such:

%0 = struct_element_addr .. #S.any
%1 = init_existential_addr %0, $*Any, $Optional
%2 = inject_enum_data_addr %1, $Optional.Some
apply @initX(%2)

SILValue initialization would look something like:

%0 = apply @initX()
%1 = enum #Optional.Some, %0 : $X
%2 = existential %1 : $Any

[I'm not sure we actually want to represent an existential container
this way, but enum, yes.]

Lowering now requires discovering the storage structure, bottom-up,
hoisting allocation, inserting cleanups as John explained.

Side note: Before lowering, something like alloc_box would directly
take its initial value.

** SILFunction calling convention.

For ownership analysis, there's effectively no difference between the
value/address forms of argument ownership:

@owned  / @in
@guaranteed / @in_guaranteed
return  / @out
@owned arg
+ @owned return / @inout

Regardless of the representation we choose for @inout, @in/@out will
now be scalar types. SILFunction will maintain the distinction between
@owned/@in etc. based on whether the type is address-only. We need
this for reabstraction, but it only affects the function type, not the
calling convention.

Rather than building a tuple, John prefers SIL support for anonymous
aggregate as "exploded values".

[I'm guessing because tuples are a distinct formal type with their own
convention and common ownership. This may need some discussion though.]

Example SIL function type:

$(@in P, @owned Q) -> (@owned R, @owned S, @out T, @out U)

%p = apply f: $() -> P
%q = apply g: $() -> Q
%exploded = apply h(%p, %q)
%r = project_exploded %exploded, #0 : $R
%s = project_exploded %exploded, #1 : $S
%t = project_exploded %exploded, #2 : $T
%u = project_exploded %exploded, #3 : $U

Exploded types requires all their elements to be projected with their
own independent ownership.

** Ownership terminology.

Swift "owned"= Rust values   = SIL @owned  = implicitly consumed
Swift "borrowed" = Rust immutable borrow = SIL @guaranteed = shared
Swift "inout"= Rust mutable borrow   = SIL @inout  = unique

Swift "inout" syntax is already (nearly) sufficient.

"borrowed" may not need syntax on the caller side, just a way to
qualify parameters. Swift still needs syntax for returning a borrowed
value.

** Representation of borrowed values.

Borrowed values represent some shared storage location.

We want some borrowed value references to be passed as SIL values, not SIL 
addresses:
- Borrowed class references should not be indirected.
- Optimize borrowing other small non-memory linked types.
- Support capture promotion, and other SSA optimizations.
- Borrow CoW values directly.

[Address-only borrowed types will still be passed as SIL addresses (why not?)]

Borrowed types with potentially mutating properties must be passed by
SIL address because they are not actually immutable and their storage
location is significant.

Borrowed references have a scope and need an end-of-borrow marker.

[The end-of-borrow marker semantically changes the memory state, and
statically enforces non-overlapping memory states. It does not
semantically write-back a value. Borrowed values with mutating fields
are semantically modified in-place.]

[Regardless of whether borrowed references are represented as SIL
values or addresses, they must be associat