+1!

> On Jul 26, 2017, at 8:29 AM, Erik Eckstein via swift-dev 
> <swift-dev@swift.org> wrote:
> 
> As John said, this is out of scope for swift 4.
> I think it’s find to just have it in master.
> 
> Thanks again for your work!
> 
>> On Jul 25, 2017, at 10:00 AM, John McCall via swift-dev 
>> <swift-dev@swift.org> wrote:
>> 
>> 
>>> On Jul 25, 2017, at 12:55 PM, Johannes Weiß via swift-dev 
>>> <swift-dev@swift.org> wrote:
>>> 
>>> Thanks very much Eric & Michael for your help! And thanks for merging it. 
>>> Will this automatically be part of Swift 4 or do I need to make another PR 
>>> against a swift 4  branch?
>> 
>> It's very hard to imagine we would take any optimizer work this late for 
>> Swift 4.
>> 
>> John.
>> 
>>> 
>>> Thanks,
>>> Johannes
>>> 
>>>> On 18 Jul 2017, at 9:21 pm, Johannes Weiß via swift-dev 
>>>> <swift-dev@swift.org> wrote:
>>>> 
>>>> great, thank you. I think I have worked all the suggestions in, let's do 
>>>> the rest in this PR: https://github.com/apple/swift/pull/11040
>>>> 
>>>> It's getting late here so I'll probably to the test tomorrow (but marked 
>>>> the patch as 'do not merge' & added that a test is still missing).
>>>> 
>>>>> On 18 Jul 2017, at 7:29 pm, Erik Eckstein <eeckst...@apple.com> wrote:
>>>>> 
>>>>>> 
>>>>>> On Jul 18, 2017, at 10:40 AM, Johannes Weiß <johanneswe...@apple.com> 
>>>>>> wrote:
>>>>>> 
>>>>>> Thanks, both suggestions look great. Will work them in tomorrow and will 
>>>>>> also try to add a test for the whole thing.
>>>>>> 
>>>>>>> On 18 Jul 2017, at 5:53 pm, Michael Gottesman <mgottes...@apple.com> 
>>>>>>> wrote:
>>>>>>> 
>>>>>>>> 
>>>>>>>> On Jul 18, 2017, at 8:39 AM, Johannes Weiß <johanneswe...@apple.com> 
>>>>>>>> wrote:
>>>>>>>> 
>>>>>>>> Hi Erik,
>>>>>>>> 
>>>>>>>>> On 17 Jul 2017, at 10:26 pm, Erik Eckstein <eeckst...@apple.com> 
>>>>>>>>> wrote:
>>>>>>>>> 
>>>>>>>>> Hi Johannes,
>>>>>>>>> 
>>>>>>>>> great that you want to work on this!
>>>>>>>> 
>>>>>>>> Thanks for your help, without Michael's and your help I wouldn't have 
>>>>>>>> been able to do anything here really!
>>>>>>>> 
>>>>>>>> 
>>>>>>>>> Some ideas:
>>>>>>>>> SideEffectAnalysis currently does not have a notion of “this argument 
>>>>>>>>> is not modified by the callee” if the callee is unknown or does 
>>>>>>>>> anything non-trivial.
>>>>>>>>> Therefore I think it’s best to put the in_guarantee check directly 
>>>>>>>>> into MemoryBehaviorVisitor::visitApplyInst():
>>>>>>>>> If the parameter convention is in_guaranteed and the parameter is V, 
>>>>>>>>> then the behavior can be MemBehavior::MayRead
>>>>>>>> 
>>>>>>>> 
>>>>>>>> Thanks, that actually makes a lot of sense. Here's my diff right now
>>>>>>>> 
>>>>>>>> diff --git a/lib/SILOptimizer/Analysis/MemoryBehavior.cpp 
>>>>>>>> b/lib/SILOptimizer/Analysis/MemoryBehavior.cpp
>>>>>>>> index b1fe7fa665..c44cc64f94 100644
>>>>>>>> --- a/lib/SILOptimizer/Analysis/MemoryBehavior.cpp
>>>>>>>> +++ b/lib/SILOptimizer/Analysis/MemoryBehavior.cpp
>>>>>>>> @@ -245,6 +245,23 @@ MemBehavior 
>>>>>>>> MemoryBehaviorVisitor::visitApplyInst(ApplyInst *AI) {
>>>>>>>> (InspectionMode == RetainObserveKind::ObserveRetains &&
>>>>>>>>  ApplyEffects.mayAllocObjects())) {
>>>>>>>> Behavior = MemBehavior::MayHaveSideEffects;
>>>>> 
>>>>> You should move your new code out of the if (ApplyEffects.mayReadRC() ...
>>>>> Otherwise it will not be executed if the called function does not read a 
>>>>> reference count.
>>>>> 
>>>>> Beside that it looks good to me.
>>>>> 
>>>>>>>> +
>>>>>>>> +    unsigned Idx = 0;
>>>>>>>> +    bool AllReadOnly = false;
>>>>>>>> +    for (Operand &operand : AI->getArgumentOperands()) {
>>>>>>>> +        if (operand.get() == V && 
>>>>>>>> AI->getOrigCalleeType()->getParameters()[Idx].isIndirectInGuaranteed())
>>>>>>>>  {
>>>>>>>> +            AllReadOnly = true;
>>>>>>>> +        } else {
>>>>>>>> +            AllReadOnly = false;
>>>>>>>> +            break;
>>>>>>>> +        }
>>>>>>>> +
>>>>>>>> +        Idx++;
>>>>>>>> +    }
>>>>>>>> +
>>>>>>>> +    if (AllReadOnly) {
>>>>>>>> +        Behavior = MemBehavior::MayRead;
>>>>>>>> +    }
>>>>>>> 
>>>>>>> Suggestion:
>>>>>>> 
>>>>>>> if (all_of(enumerate(AI->getArgumentOperands()),
>>>>>>>         [&](std::pair<unsigned, SILValue> pair) -> bool {
>>>>>>>            return pair.second.get() == V && 
>>>>>>> AI->getOrigCalleeType()->getParameters()[Idx].isIndirectInGuaranteed()
>>>>>>>         })) {
>>>>>>> Behavior = MemBehavior::MayRead;
>>>>>>> }
>>>>>>> 
>>>>>>> I may have gotten the order of the pair templates wrong. But something 
>>>>>>> like this is a little cleaner.
>>>>>>> 
>>>>>>> Michael
>>>>>>> 
>>>>>>>> } else {
>>>>>>>> auto &GlobalEffects = ApplyEffects.getGlobalEffects();
>>>>>>>> Behavior = GlobalEffects.getMemBehavior(InspectionMode);
>>>>>>>> 
>>>>>>>> which indeed turns
>>>>>>>> 
>>>>>>>> --- SNIP ---
>>>>>>>> sil @bar : $@convention(thin) (@in Int) -> () {
>>>>>>>> bb0(%0 : $*Int):
>>>>>>>> %value_raw = integer_literal $Builtin.Int64, 42
>>>>>>>> %value = struct $Int (%value_raw : $Builtin.Int64)
>>>>>>>> store %value to %0 : $*Int
>>>>>>>> 
>>>>>>>> %f_buz = function_ref @buz : $@convention(thin) (@in_guaranteed Int) 
>>>>>>>> -> ()
>>>>>>>> %r1 = apply %f_buz(%0) : $@convention(thin) (@in_guaranteed Int) -> ()
>>>>>>>> 
>>>>>>>> %value_again = load %0 : $*Int
>>>>>>>> %f_test = function_ref @test : $@convention(thin) (Int) -> ()
>>>>>>>> %r2 = apply %f_test(%value_again) : $@convention(thin) (Int) -> ()
>>>>>>>> 
>>>>>>>> /*
>>>>>>>> %f_bad = function_ref @bad : $@convention(thin) (@in_guaranteed Int) 
>>>>>>>> -> ()
>>>>>>>> %r3 = apply %f_bad(%0) : $@convention(thin) (@in_guaranteed Int) -> ()
>>>>>>>> 
>>>>>>>> %value_again2 = load %0 : $*Int
>>>>>>>> %r4 = apply %f_test(%value_again2) : $@convention(thin) (Int) -> ()
>>>>>>>> */
>>>>>>>> 
>>>>>>>> %9999 = tuple()
>>>>>>>> return %9999 : $()
>>>>>>>> }
>>>>>>>> --- SNAP ---
>>>>>>>> 
>>>>>>>> into
>>>>>>>> 
>>>>>>>> --- SNIP ---
>>>>>>>> bb0(%0 : $*Int):
>>>>>>>> %1 = integer_literal $Builtin.Int64, 42         // user: %2
>>>>>>>> %2 = struct $Int (%1 : $Builtin.Int64)          // users: %7, %3
>>>>>>>> store %2 to %0 : $*Int                          // id: %3
>>>>>>>> // function_ref buz
>>>>>>>> %4 = function_ref @buz : $@convention(thin) (@in_guaranteed Int) -> () 
>>>>>>>> // user: %5
>>>>>>>> %5 = apply %4(%0) : $@convention(thin) (@in_guaranteed Int) -> ()
>>>>>>>> // function_ref test
>>>>>>>> %6 = function_ref @test : $@convention(thin) (Int) -> () // user: %7
>>>>>>>> %7 = apply %6(%2) : $@convention(thin) (Int) -> ()
>>>>>>>> %8 = tuple ()                                   // user: %9
>>>>>>>> return %8 : $()                                 // id: %9
>>>>>>>> } // end sil function 'bar'
>>>>>>>> --- SNAP ---
>>>>>>>> 
>>>>>>>> so the load has successfully been eliminated. Also taking my initial 
>>>>>>>> repro [1], the retain, the load, and the release are now gone 😃.
>>>>>>>> 
>>>>>>>> Is that roughly what you were thinking of?
>>>>>>>> 
>>>>>>>> Many thanks,
>>>>>>>> Johannes
>>>>>>>> 
>>>>>>>> [1]: https://bugs.swift.org/secure/attachment/12378/test.swift
>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> Erik
>>>>>>>>> 
>>>>>>>>>> On Jul 17, 2017, at 9:23 AM, Johannes Weiß <johanneswe...@apple.com> 
>>>>>>>>>> wrote:
>>>>>>>>>> 
>>>>>>>>>> Thanks Michael!
>>>>>>>>>> 
>>>>>>>>>> Erik, I hope what I wrote makes some sense. Any questions or 
>>>>>>>>>> suggestions, please let me know.
>>>>>>>>>> 
>>>>>>>>>>> On 14 Jul 2017, at 7:30 pm, Michael Gottesman 
>>>>>>>>>>> <mgottes...@apple.com> wrote:
>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>> On Jul 12, 2017, at 9:53 AM, Johannes Weiß 
>>>>>>>>>>>> <johanneswe...@apple.com> wrote:
>>>>>>>>>>>> 
>>>>>>>>>>>> Hi Michael,
>>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>>> [...]
>>>>>>>>>>>>>> Long story short, I think the RLE actually works for the test 
>>>>>>>>>>>>>> case I created. It's even clever enough to see through my 
>>>>>>>>>>>>>> invalid function bad() which modified the storage despite its 
>>>>>>>>>>>>>> claim that it doesn't. I might also be misunderstanding 
>>>>>>>>>>>>>> something.
>>>>>>>>>>>>> 
>>>>>>>>>>>>> When something is marked as in_guaranteed, it should be 
>>>>>>>>>>>>> immutable. If the callee violates that, then the SIL is 
>>>>>>>>>>>>> malformed. Perhaps, we can add some sort of verification check.
>>>>>>>>>>>> 
>>>>>>>>>>>> Right, yes I was aware that that'd be illegal but I added it as a 
>>>>>>>>>>>> way to check whether this optimisation is 'looking into' the 
>>>>>>>>>>>> called function.
>>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>>> That being said, I have a good feeling that there is some sort of 
>>>>>>>>>>>>> analysis occuring here since you provided enough information to 
>>>>>>>>>>>>> the optimizer. The optimization here is regardless of whether or 
>>>>>>>>>>>>> not we can see the body of a function, we know that it is safe to 
>>>>>>>>>>>>> optimize this just based off the @in_guaranteed. This implies 
>>>>>>>>>>>>> using a declaration, not a definition of the bad function.
>>>>>>>>>>>> 
>>>>>>>>>>>> makes sense, didn't think about just only declaring it...
>>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>>> When I said write the SIL by hand, what I meant was writing the 
>>>>>>>>>>>>> whole program by hand. In general, we prefer SIL programs that do 
>>>>>>>>>>>>> not have extraneous stuff that is added by the compiler (for 
>>>>>>>>>>>>> instance debug_value). Additionally, it is important for SIL 
>>>>>>>>>>>>> files to not have dependencies on the stdlib unless absolutely 
>>>>>>>>>>>>> necessary (i.e. your usage of Int). This prevents the stdlib 
>>>>>>>>>>>>> maintainers from having to update these tests given chances to 
>>>>>>>>>>>>> the stdlib. Below is a cleaned up version that shows the problem. 
>>>>>>>>>>>>> Look at how small it is and how it tests /exactly/ what we are 
>>>>>>>>>>>>> trying to test and via the use of declarations and the like we 
>>>>>>>>>>>>> are able to exclude other optimizations:
>>>>>>>>>>>> 
>>>>>>>>>>>> That makes a lot of sense, thank you. I wasn't yet that familiar 
>>>>>>>>>>>> with SIL so I thought I start from a program generated by the 
>>>>>>>>>>>> compiler and then replace the guts with handwritten SIL. But your 
>>>>>>>>>>>> version is clearly a lot easier to understand and shows what 
>>>>>>>>>>>> precisely we want to see!
>>>>>>>>>>>> 
>>>>>>>>>>>> Today, I looked into why this is happening more precisely.
>>>>>>>>>>>> 
>>>>>>>>>>>> So we don't get the RLE because in this code
>>>>>>>>>>>> 
>>>>>>>>>>>> if (isComputeAvailValue(Kind) || isPerformingRLE(Kind)) {
>>>>>>>>>>>> for (unsigned i = 0; i < Locs.size(); ++i) {
>>>>>>>>>>>> if (isTrackingLocation(ForwardSetIn, Ctx.getLocationBit(Locs[i])))
>>>>>>>>>>>> continue;
>>>>>>>>>>>> updateForwardSetAndValForRead(Ctx, Ctx.getLocationBit(Locs[i]),
>>>>>>>>>>>>                           Ctx.getValueBit(Vals[i]));
>>>>>>>>>>>> // We can not perform the forwarding as we are at least missing
>>>>>>>>>>>> // some pieces of the read location.
>>>>>>>>>>>> CanForward = false;
>>>>>>>>>>>> 
>>>>>>>>>>>> (https://github.com/apple/swift/blob/86620aaa7ebd32d33f4cdf61add5c63a72d3f02a/lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp#L917)
>>>>>>>>>>>> 
>>>>>>>>>>>> we're not taking the `continue` for the call to `buz()`. The 
>>>>>>>>>>>> reason why is that here
>>>>>>>>>>>> 
>>>>>>>>>>>> if (!AA->mayWriteToMemory(I, R.getBase()))
>>>>>>>>>>>> continue;
>>>>>>>>>>>> // MayAlias.
>>>>>>>>>>>> stopTrackingLocation(ForwardSetIn, i);
>>>>>>>>>>>> stopTrackingValue(ForwardValIn, i);
>>>>>>>>>>>> 
>>>>>>>>>>>> (https://github.com/apple/swift/blob/86620aaa7ebd32d33f4cdf61add5c63a72d3f02a/lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp#L972)
>>>>>>>>>>>> 
>>>>>>>>>>>> we're not taking the `continue`, ie. `AA->mayWriteToMemory(I, 
>>>>>>>>>>>> R.getBase())` is true. The reason for that is that the 
>>>>>>>>>>>> `SILFunction` for `buz` has
>>>>>>>>>>>> 
>>>>>>>>>>>> EffectsKindAttr = Unspecified
>>>>>>>>>>>> 
>>>>>>>>>>>> which equates to `MayHaveSideEffects`, that's also what 
>>>>>>>>>>>> `-debug-only=sil-redundant-load-elim,sil-membehavior` outputs:
>>>>>>>>>>>> 
>>>>>>>>>>>> GET MEMORY BEHAVIOR FOR:
>>>>>>>>>>>> %5 = apply %4(%0) : $@convention(thin) (@in_guaranteed Int) -> ()
>>>>>>>>>>>> %0 = argument of bb0 : $*Int                    // users: %6, %5, 
>>>>>>>>>>>> %3
>>>>>>>>>>>> Found apply, returning MayHaveSideEffects
>>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>> So where I'm stuck today is that I'm not sure how 
>>>>>>>>>>>> `EffectsKindAttr` is actually defined. Sure, `$@convention(thin) 
>>>>>>>>>>>> (@in_guaranteed Int) -> ()` doesn't actually write to the 
>>>>>>>>>>>> `@in_guaranteed Int` (as that'd be illegal) but it may have other 
>>>>>>>>>>>> side effects. So I'm not sure if we can just create the function 
>>>>>>>>>>>> differently if we find only "read-only" kind of parameters. That'd 
>>>>>>>>>>>> be I think in
>>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>> auto *fn = SILMod.createFunction(SILLinkage::Private, Name.str(), 
>>>>>>>>>>>> Ty,
>>>>>>>>>>>>                          nullptr, loc, IsNotBare,
>>>>>>>>>>>>                          IsNotTransparent, IsNotSerialized);
>>>>>>>>>>>> 
>>>>>>>>>>>> (https://github.com/apple/swift/blob/ec6fc4d54db95f78ae72dab29734533f709ea2d7/lib/Parse/ParseSIL.cpp#L508
>>>>>>>>>>>>  -> 
>>>>>>>>>>>> https://github.com/apple/swift/blob/157db57506b813837481b574a9d38e806bf954b6/lib/SIL/SILModule.cpp#L249)
>>>>>>>>>>>> 
>>>>>>>>>>>> which doesn't specify any EffectsAttrKind and therefore it 
>>>>>>>>>>>> defaults to `Unspecified`.
>>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>> Just as a test, I did put a `[readonly]` in `sil @buz : 
>>>>>>>>>>>> $@convention(thin) (@in_guaranteed Int) -> ()` and as expected 
>>>>>>>>>>>> everything propagates through correctly and we get a successful 
>>>>>>>>>>>> RLE.
>>>>>>>>>>>> 
>>>>>>>>>>>> So yes, maybe you have some pointers on where to best educate the 
>>>>>>>>>>>> compiler that the `buz` function won't write to that bit of memory.
>>>>>>>>>>> 
>>>>>>>>>>> I have a few ideas of where to put it, but really the person to 
>>>>>>>>>>> bring in here is Erik. He is the one who wrote the side-effect part 
>>>>>>>>>>> of the optimizer. Keep in mind he is on vacation right now until 
>>>>>>>>>>> next week. So I wouldn't expect a response until then.
>>>>>>>>>>> 
>>>>>>>>>>> Michael
>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>> Many thanks,
>>>>>>>>>>>> Johannes
>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>>>> ----
>>>>>>>>>>>>> sil_stage canonical
>>>>>>>>>>>>> 
>>>>>>>>>>>>> import Builtin
>>>>>>>>>>>>> 
>>>>>>>>>>>>> struct Int {
>>>>>>>>>>>>> var _value : Builtin.Int64
>>>>>>>>>>>>> }
>>>>>>>>>>>>> 
>>>>>>>>>>>>> sil @test : $@convention(thin) (Int) -> ()
>>>>>>>>>>>>> sil @buz : $@convention(thin) (@in_guaranteed Int) -> ()
>>>>>>>>>>>>> sil @bad : $@convention(thin) (@in_guaranteed Int) -> ()
>>>>>>>>>>>>> 
>>>>>>>>>>>>> sil @bar : $@convention(thin) (@in Int) -> () {
>>>>>>>>>>>>> bb0(%0 : $*Int):
>>>>>>>>>>>>> %value_raw = integer_literal $Builtin.Int64, 42
>>>>>>>>>>>>> %value = struct $Int (%value_raw : $Builtin.Int64)
>>>>>>>>>>>>> store %value to %0 : $*Int
>>>>>>>>>>>>> 
>>>>>>>>>>>>> %f_buz = function_ref @buz : $@convention(thin) (@in_guaranteed 
>>>>>>>>>>>>> Int) -> ()
>>>>>>>>>>>>> %r1 = apply %f_buz(%0) : $@convention(thin) (@in_guaranteed Int) 
>>>>>>>>>>>>> -> ()
>>>>>>>>>>>>> 
>>>>>>>>>>>>> %value_again = load %0 : $*Int
>>>>>>>>>>>>> %f_test = function_ref @test : $@convention(thin) (Int) -> ()
>>>>>>>>>>>>> %r2 = apply %f_test(%value_again) : $@convention(thin) (Int) -> ()
>>>>>>>>>>>>> 
>>>>>>>>>>>>> %f_bad = function_ref @bad : $@convention(thin) (@in_guaranteed 
>>>>>>>>>>>>> Int) -> ()
>>>>>>>>>>>>> %r3 = apply %f_bad(%0) : $@convention(thin) (@in_guaranteed Int) 
>>>>>>>>>>>>> -> ()
>>>>>>>>>>>>> 
>>>>>>>>>>>>> %value_again2 = load %0 : $*Int
>>>>>>>>>>>>> %r4 = apply %f_test(%value_again2) : $@convention(thin) (Int) -> 
>>>>>>>>>>>>> ()
>>>>>>>>>>>>> 
>>>>>>>>>>>>> %9999 = tuple()
>>>>>>>>>>>>> return %9999 : $()
>>>>>>>>>>>>> }
>>>>>>>>>>>>> ----
>>>>>>>>>>>>> 
>>>>>>>>>>>>> When I run this test file through rle, I get:
>>>>>>>>>>>>> 
>>>>>>>>>>>>> ----
>>>>>>>>>>>>> sil_stage canonical
>>>>>>>>>>>>> 
>>>>>>>>>>>>> import Builtin
>>>>>>>>>>>>> import Swift
>>>>>>>>>>>>> import SwiftShims
>>>>>>>>>>>>> 
>>>>>>>>>>>>> struct Int {
>>>>>>>>>>>>> @sil_stored var _value: Builtin.Int64
>>>>>>>>>>>>> init(_value: Builtin.Int64)
>>>>>>>>>>>>> }
>>>>>>>>>>>>> 
>>>>>>>>>>>>> // test
>>>>>>>>>>>>> sil @test : $@convention(thin) (Int) -> ()
>>>>>>>>>>>>> 
>>>>>>>>>>>>> // buz
>>>>>>>>>>>>> sil @buz : $@convention(thin) (@in_guaranteed Int) -> ()
>>>>>>>>>>>>> 
>>>>>>>>>>>>> // bad
>>>>>>>>>>>>> sil @bad : $@convention(thin) (@in_guaranteed Int) -> ()
>>>>>>>>>>>>> 
>>>>>>>>>>>>> // bar
>>>>>>>>>>>>> sil @bar : $@convention(thin) (@in Int) -> () {
>>>>>>>>>>>>> // %0                                             // users: %11, 
>>>>>>>>>>>>> %10, %6, %5, %3
>>>>>>>>>>>>> bb0(%0 : $*Int):
>>>>>>>>>>>>> %1 = integer_literal $Builtin.Int64, 42         // user: %2
>>>>>>>>>>>>> %2 = struct $Int (%1 : $Builtin.Int64)          // user: %3
>>>>>>>>>>>>> store %2 to %0 : $*Int                          // id: %3
>>>>>>>>>>>>> // function_ref buz
>>>>>>>>>>>>> %4 = function_ref @buz : $@convention(thin) (@in_guaranteed Int) 
>>>>>>>>>>>>> -> () // user: %5
>>>>>>>>>>>>> %5 = apply %4(%0) : $@convention(thin) (@in_guaranteed Int) -> ()
>>>>>>>>>>>>> %6 = load %0 : $*Int                            // user: %8
>>>>>>>>>>>>> // function_ref test
>>>>>>>>>>>>> %7 = function_ref @test : $@convention(thin) (Int) -> () // 
>>>>>>>>>>>>> users: %12, %8
>>>>>>>>>>>>> %8 = apply %7(%6) : $@convention(thin) (Int) -> ()
>>>>>>>>>>>>> // function_ref bad
>>>>>>>>>>>>> %9 = function_ref @bad : $@convention(thin) (@in_guaranteed Int) 
>>>>>>>>>>>>> -> () // user: %10
>>>>>>>>>>>>> %10 = apply %9(%0) : $@convention(thin) (@in_guaranteed Int) -> ()
>>>>>>>>>>>>> %11 = load %0 : $*Int                           // user: %12
>>>>>>>>>>>>> %12 = apply %7(%11) : $@convention(thin) (Int) -> ()
>>>>>>>>>>>>> %13 = tuple ()                                  // user: %14
>>>>>>>>>>>>> return %13 : $()                                // id: %14
>>>>>>>>>>>>> } // end sil function 'bar'
>>>>>>>>>>>>> ----
>>>>>>>>>>>>> 
>>>>>>>>>>>>> Michael
>>>>>>>>>>>>> 
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> Does that all make sense?
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>> Johannes
>>>>>>>>>>>>>> <test-load-forwarding.sil><test-load-forwarding.sil-opt>
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>> Johannes
>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>> [1]: https://bugs.swift.org/browse/SR-5403
>>>> 
>>>> _______________________________________________
>>>> 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 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 mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to