Hi everyone,

I’ve made good progress with the information in this thread but I can’t figure 
out how to create the proper set of substitutions for the method that I’m 
calling.

The error I’m getting, as expected, is "SIL verification failed: callee of 
apply without substitutions must not be polymorphic: !fnTy->isPolymorphic()"

I was hoping that there would be a way to delay specialization of the function 
that I’m replacing so that I can simply reuse those substitutions, but it 
doesn’t seem like that’s possible.

At a high level I assumed that I’d simply be able to substitute a type like 
`Int` for `τ_0_0`, but it looks like I have to use a ProtocolConformanceRef, 
which I don’t understand.

I looked into iterating through 
`getLoweredFunctionType()->getGenericSignature()->getGenericParams()`, but I 
don’t see how I can turn the information there into ProtocolConformanceRef.

Thanks for the help as always,

Ben

> On Nov 16, 2016, at 10:47 PM, Ben Ng <m...@benng.me> wrote:
> 
>> On Nov 16, 2016, at 7:11 PM, Arnold Schwaighofer <aschwaigho...@apple.com> 
>> wrote:
>> 
>> 
>>> On Nov 16, 2016, at 2:58 PM, Ben Ng <m...@benng.me> wrote:
>>> 
>>> Correct, that is what I am trying to do.
>>> 
>>>> On Nov 16, 2016, at 12:22 PM, Arnold Schwaighofer 
>>>> <aschwaigho...@apple.com> wrote:
>>>> 
>>>> // Really, by the time you look at this in array value prop
>>>> // this call should have been inline and you would see a call
>>>> // to:
>>>> // a.append(contentsOf: [1])
>>> 
>>> I do not understand this comment; I thought that inlining of stdlib 
>>> functions happened after high-level SIL optimizations are run. Is my 
>>> understanding incorrect?
>> 
>> 
>> Inlining of functions with @_semantics is delayed until after high-level SIL 
>> optimizations are run. Other functions are inlined.
>> 
>> https://github.com/apple/swift/blob/master/lib/SILOptimizer/PassManager/Passes.cpp#L221
>> https://github.com/apple/swift/blob/master/lib/SILOptimizer/Transforms/PerformanceInliner.cpp#L722
>> 
>> 
>> I recommend looking at the SIL function dump in ArrayElementValuePropagation 
>> of an example function after adding @semantics(“array.mutate_unknown”) to 
>> “append(contentsOf:)”.
>> 
>> 
>> $ git diff HEAD~
>> diff --git a/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp 
>> b/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp
>> index 76328a6..cb976f7 100644
>> --- a/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp
>> +++ b/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp
>> @@ -259,6 +259,8 @@ public:
>>  void run() override {
>>    auto &Fn = *getFunction();
>> 
>> +    Fn.dump();
>> +
>>    bool Changed = false;
>> 
>>    // Propagate the elements an of array value to its users.
>> diff --git a/stdlib/public/core/Arrays.swift.gyb 
>> b/stdlib/public/core/Arrays.swift.gyb
>> index f00cc23..2acfd06 100644
>> --- a/stdlib/public/core/Arrays.swift.gyb
>> +++ b/stdlib/public/core/Arrays.swift.gyb
>> @@ -1344,6 +1344,7 @@ extension ${Self} : RangeReplaceableCollection, 
>> _ArrayProtocol {
>>  /// - Parameter newElements: The elements to append to the array.
>>  ///
>>  /// - Complexity: O(*n*), where *n* is the length of the resulting array.
>> +  @_semantics("array.mutate_unknown")
>>  public mutating func append<C : Collection>(contentsOf newElements: C)
>>    where C.Iterator.Element == Element {
>> 
>> 
>> # Rebuild the compiler and stdlib (without stdlib assertions).
>> $ swift/utils/build-script -r  --assertions --no-swift-stdlib-assertions
>> 
>> 
>> $ cat TestArray.swift 
>> @inline(never)
>> public func test() {
>> var a = [1, 2, 3]
>> a += [1]
>> print(a)
>> }
>> 
>> $ bin/swiftc -O 2>&1 | less
>> ...
>> sil shared [_semantics "array.mutate_unknown"] 
>> @_TTSg5Si_GSaSi_GSaSi_s10Collections___TFSa6appenduRd__s10CollectionxzWd__8Iterator7Element_rfT10contentsOfqd___T_
>>  : $@convention(method) (@owned Array<I
>> nt>, @inout Array<Int>) -> () {
>> 
>> …
>> // testArray() -> ()
>> sil [noinline] @_TF9TestArray9testArrayFT_T_ : $@convention(thin) () -> () {
>> bb0:
>> %0 = alloc_stack $Array<Int>, var, name "a", loc "TestArray.swift":3:7, 
>> scope 2 // users: %54, %32, %60, %23, %43
>> %1 = integer_literal $Builtin.Word, 3, loc "TestArray.swift":3:12, scope 2 
>> // user: %4
>> %2 = integer_literal $Builtin.Int64, 3, scope 5 // user: %3
>> %3 = struct $Int (%2 : $Builtin.Int64), scope 5 // users: %22, %7
>> %4 = alloc_ref [tail_elems $Int * %1 : $Builtin.Word] 
>> $_ContiguousArrayStorage<Int>, scope 5 // user: %7
>> %5 = metatype $@thin Array<Int>.Type, scope 5   // users: %25, %7
>> // function_ref specialized static 
>> Array._adoptStorage(_ContiguousArrayStorage<A>, count : Int) -> ([A], 
>> UnsafeMutablePointer<A>)
>> %6 = function_ref 
>> @_TTSg5Si___TZFSa13_adoptStoragefTGCs23_ContiguousArrayStoragex_5countSi_TGSax_GSpx__
>>  : $@convention(method) (@owned _ContiguousArrayStorage<Int>, Int, @thin 
>> Array<Int>.Type) -> (@
>> owned Array<Int>, UnsafeMutablePointer<Int>), scope 5 // users: %25, %7
>> %7 = apply %6(%4, %3, %5) : $@convention(method) (@owned 
>> _ContiguousArrayStorage<Int>, Int, @thin Array<Int>.Type) -> (@owned 
>> Array<Int>, UnsafeMutablePointer<Int>), scope 5 // users: %9, %8
>> %8 = tuple_extract %7 : $(Array<Int>, UnsafeMutablePointer<Int>), 0, scope 5 
>> // user: %23
>> %9 = tuple_extract %7 : $(Array<Int>, UnsafeMutablePointer<Int>), 1, scope 5 
>> // user: %10
>> %10 = struct_extract %9 : $UnsafeMutablePointer<Int>, 
>> #UnsafeMutablePointer._rawValue, scope 5 // user: %11
>> %11 = pointer_to_address %10 : $Builtin.RawPointer to [strict] $*Int, loc 
>> "TestArray.swift":3:12, scope 2 // users: %14, %21, %16
>> %12 = integer_literal $Builtin.Int64, 1, loc "TestArray.swift":3:12, scope 2 
>> // user: %13
>> %13 = struct $Int (%12 : $Builtin.Int64), loc "TestArray.swift":3:12, scope 
>> 2 // users: %37, %30, %25, %14
>> store %13 to %11 : $*Int, loc "TestArray.swift":3:12, scope 2 // id: %14
>> %15 = integer_literal $Builtin.Word, 1, loc "TestArray.swift":3:15, scope 2 
>> // users: %34, %24, %16
>> %16 = index_addr %11 : $*Int, %15 : $Builtin.Word, loc 
>> "TestArray.swift":3:15, scope 2 // user: %19
>> %17 = integer_literal $Builtin.Int64, 2, loc "TestArray.swift":3:15, scope 2 
>> // user: %18
>> %18 = struct $Int (%17 : $Builtin.Int64), loc "TestArray.swift":3:15, scope 
>> 2 // user: %19
>> store %18 to %16 : $*Int, loc "TestArray.swift":3:15, scope 2 // id: %19
>> %20 = integer_literal $Builtin.Word, 2, loc "TestArray.swift":3:18, scope 2 
>> // user: %21
>> %21 = index_addr %11 : $*Int, %20 : $Builtin.Word, loc 
>> "TestArray.swift":3:18, scope 2 // user: %22
>> store %3 to %21 : $*Int, loc "TestArray.swift":3:18, scope 2 // id: %22
>> store %8 to %0 : $*Array<Int>, loc "TestArray.swift":3:18, scope 2 // id: %23
>> %24 = alloc_ref [tail_elems $Int * %15 : $Builtin.Word] 
>> $_ContiguousArrayStorage<Int>, scope 7 // user: %25
>> %25 = apply %6(%24, %13, %5) : $@convention(method) (@owned 
>> _ContiguousArrayStorage<Int>, Int, @thin Array<Int>.Type) -> (@owned 
>> Array<Int>, UnsafeMutablePointer<Int>), scope 7 // users: %27, %26
>> %26 = tuple_extract %25 : $(Array<Int>, UnsafeMutablePointer<Int>), 0, scope 
>> 7 // user: %32
>> %27 = tuple_extract %25 : $(Array<Int>, UnsafeMutablePointer<Int>), 1, scope 
>> 7 // user: %28
>> %28 = struct_extract %27 : $UnsafeMutablePointer<Int>, 
>> #UnsafeMutablePointer._rawValue, scope 7 // user: %29
>> %29 = pointer_to_address %28 : $Builtin.RawPointer to [strict] $*Int, loc 
>> "TestArray.swift":4:9, scope 2 // user: %30
>> store %13 to %29 : $*Int, loc "TestArray.swift":4:9, scope 2 // id: %30
>> // function_ref specialized Array.append<A where ...> (contentsOf : A1) -> ()
>> %31 = function_ref 
>> @_TTSg5Si_GSaSi_GSaSi_s10Collections___TFSa6appenduRd__s10CollectionxzWd__8Iterator7Element_rfT10contentsOfqd___T_
>>  : $@convention(method) (@owned Array<Int>, @inout Array<Int>) -> (), scope 
>> 10 // user: %32
>> %32 = apply %31(%26, %0) : $@convention(method) (@owned Array<Int>, @inout 
>> Array<Int>) -> (), scope 10
> 
> Ah, I do remember seeing something about how the semantic attribute stops 
> some functions from being inlined early. Thanks for saving me a bunch of 
> head-scratching!
> 
> 

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

Reply via email to