Skip to content

Commit 0f4aa3e

Browse files
committed
---
yaml --- r: 347881 b: refs/heads/master c: 364377b h: refs/heads/master i: 347879: da061a8
1 parent 26c63c9 commit 0f4aa3e

File tree

6 files changed

+105
-3
lines changed

6 files changed

+105
-3
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 6c192e2081d81e3b67cbd46e76a350c3e27ed054
2+
refs/heads/master: 364377b7d8f4a6ff7cfd8a08391b9b28900dbb0e
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/include/swift/SIL/SILInstruction.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1841,6 +1841,8 @@ class ApplyInstBase<Impl, Base, false> : public Base {
18411841
/// issues. It is at the bottom of the file.
18421842
SILFunction *getCalleeFunction() const;
18431843

1844+
bool isCalleeDynamicallyReplaceable() const;
1845+
18441846
/// Gets the referenced function if the callee is a function_ref instruction.
18451847
SILFunction *getReferencedFunction() const {
18461848
if (auto *FRI = dyn_cast<FunctionRefBaseInst>(getCallee()))
@@ -7773,6 +7775,27 @@ SILValue ApplyInstBase<Impl, Base, false>::getCalleeOrigin() const {
77737775
}
77747776
}
77757777

7778+
template <class Impl, class Base>
7779+
bool ApplyInstBase<Impl, Base, false>::isCalleeDynamicallyReplaceable() const {
7780+
SILValue Callee = getCalleeOrigin();
7781+
7782+
while (true) {
7783+
if (auto *FRI = dyn_cast<FunctionRefInst>(Callee))
7784+
return false;
7785+
7786+
if (auto *FRI = dyn_cast<DynamicFunctionRefInst>(Callee))
7787+
return true;
7788+
if (auto *FRI = dyn_cast<PreviousDynamicFunctionRefInst>(Callee))
7789+
return true;
7790+
7791+
if (auto *PAI = dyn_cast<PartialApplyInst>(Callee)) {
7792+
Callee = PAI->getCalleeOrigin();
7793+
continue;
7794+
}
7795+
return false;
7796+
}
7797+
}
7798+
77767799
template <class Impl, class Base>
77777800
SILFunction *ApplyInstBase<Impl, Base, false>::getCalleeFunction() const {
77787801
SILValue Callee = getCalleeOrigin();

trunk/lib/SILOptimizer/Analysis/ClosureScope.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,10 @@ class ClosureScopeData {
8282
void recordScope(PartialApplyInst *PAI) {
8383
// Only track scopes of non-escaping closures.
8484
auto closureTy = PAI->getCallee()->getType().castTo<SILFunctionType>();
85-
if (!isNonEscapingClosure(closureTy))
85+
// FIXME: isCalleeDynamicallyReplaceable should not be true but can today
86+
// because local functions can be marked dynamic.
87+
if (!isNonEscapingClosure(closureTy) ||
88+
PAI->isCalleeDynamicallyReplaceable())
8689
return;
8790

8891
auto closureFunc = PAI->getCalleeFunction();

trunk/lib/SILOptimizer/IPO/CapturePromotion.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,10 @@ bool isPartialApplyNonEscapingUser(Operand *CurrentOp, PartialApplyInst *PAI,
977977
unsigned Index = OpNo - 1 + closureConv.getNumSILArguments();
978978

979979
auto *Fn = PAI->getReferencedFunction();
980-
if (!Fn || !Fn->isDefinition()) {
980+
981+
// It is not safe to look at the content of dynamically replaceable functions
982+
// since this pass looks at the content of Fn.
983+
if (!Fn || !Fn->isDefinition() || Fn->isDynamicallyReplaceable()) {
981984
LLVM_DEBUG(llvm::dbgs() << " FAIL! Not a direct function definition "
982985
"reference.\n");
983986
return false;

trunk/test/SILOptimizer/access_enforcement_selection.sil

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,24 @@ bb0:
9999
return %9 : $()
100100
}
101101

102+
sil [dynamically_replacable] [ossa] @closureCapturingByStorageAddress2 : $@convention(thin) (@inout_aliasable Builtin.Int64) -> ()
102103

104+
// Make sure that we handle dynamic_function_ref.
105+
sil hidden [ossa] @escapeAsArgumentToPartialApplyDynamic : $@convention(thin) () -> () {
106+
bb0:
107+
%2 = alloc_box ${ var Builtin.Int64 }, var, name "x"
108+
%3 = project_box %2 : ${ var Builtin.Int64 }, 0
109+
%4 = function_ref @takesInoutAndClosure : $@convention(thin) (@inout Builtin.Int64, @guaranteed @callee_guaranteed () -> ()) -> ()
110+
%5 = dynamic_function_ref @closureCapturingByStorageAddress2 : $@convention(thin) (@inout_aliasable Builtin.Int64) -> ()
111+
%6 = partial_apply [callee_guaranteed] %5(%3) : $@convention(thin) (@inout_aliasable Builtin.Int64) -> ()
112+
%7 = begin_access [modify] [unknown] %3 : $*Builtin.Int64
113+
%8 = apply %4(%7, %6) : $@convention(thin) (@inout Builtin.Int64, @guaranteed @callee_guaranteed () -> ()) -> ()
114+
end_access %7 : $*Builtin.Int64
115+
destroy_value %6 : $@callee_guaranteed () -> ()
116+
destroy_value %2 : ${ var Builtin.Int64 }
117+
%9 = tuple ()
118+
return %9 : $()
119+
}
103120
// Test static enforcement of copied boxes.
104121
// FIXME: Oops... We make this dynamic.
105122
//

trunk/test/SILOptimizer/capture_promotion.sil

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,3 +474,59 @@ bb0:
474474
%tuple = tuple()
475475
return %tuple : $()
476476
}
477+
478+
sil private [dynamically_replacable] @closure0_guaranteed2 : $@convention(thin) (@guaranteed <τ_0_0> { var τ_0_0 } <Foo>, @guaranteed <τ_0_0> { var τ_0_0 } <Baz>, @guaranteed <τ_0_0> { var τ_0_0 } <Int>) -> Int {
479+
bb0(%0 : $<τ_0_0> { var τ_0_0 } <Foo>, %2 : $<τ_0_0> { var τ_0_0 } <Baz>, %4 : $<τ_0_0> { var τ_0_0 } <Int>):
480+
%1 = project_box %0 : $<τ_0_0> { var τ_0_0 } <Foo>, 0
481+
%3 = project_box %2 : $<τ_0_0> { var τ_0_0 } <Baz>, 0
482+
%5 = project_box %4 : $<τ_0_0> { var τ_0_0 } <Int>, 0
483+
%6 = tuple ()
484+
%7 = function_ref @dummy_func : $@convention(thin) (Int, Int, Int) -> Int
485+
%8 = load %1 : $*Foo
486+
strong_retain %8 : $Foo
487+
%10 = class_method %8 : $Foo, #Foo.foo!1 : (Foo) -> () -> Int, $@convention(method) (@guaranteed Foo) -> Int
488+
%11 = apply %10(%8) : $@convention(method) (@guaranteed Foo) -> Int
489+
%12 = struct_element_addr %3 : $*Baz, #Baz.x
490+
%13 = load %12 : $*Int
491+
%14 = load %5 : $*Int
492+
%15 = apply %7(%11, %13, %14) : $@convention(thin) (Int, Int, Int) -> Int
493+
return %15 : $Int
494+
}
495+
496+
// This should not crash.
497+
sil @test_capture_promotion_dynamic_function_ref : $@convention(thin) () -> () {
498+
bb0:
499+
%0 = tuple ()
500+
%1 = alloc_box $<τ_0_0> { var τ_0_0 } <Foo>
501+
%1a = project_box %1 : $<τ_0_0> { var τ_0_0 } <Foo>, 0
502+
%2 = function_ref @foo_allocating_init : $@convention(thin) (@thick Foo.Type) -> @owned Foo
503+
%3 = metatype $@thick Foo.Type
504+
%4 = apply %2(%3) : $@convention(thin) (@thick Foo.Type) -> @owned Foo
505+
store %4 to %1a : $*Foo
506+
%6 = alloc_box $<τ_0_0> { var τ_0_0 } <Baz>
507+
%6a = project_box %6 : $<τ_0_0> { var τ_0_0 } <Baz>, 0
508+
%7 = function_ref @baz_init : $@convention(thin) (@thin Baz.Type) -> @owned Baz
509+
%8 = metatype $@thin Baz.Type
510+
%9 = apply %7(%8) : $@convention(thin) (@thin Baz.Type) -> @owned Baz
511+
store %9 to %6a : $*Baz
512+
%11 = alloc_box $<τ_0_0> { var τ_0_0 } <Int>
513+
%11a = project_box %11 : $<τ_0_0> { var τ_0_0 } <Int>, 0
514+
%12 = function_ref @convert_from_integer_literal : $@convention(thin) (Builtin.Word, @thin Int.Type) -> Int
515+
%13 = metatype $@thin Int.Type
516+
%14 = integer_literal $Builtin.Word, 3
517+
%15 = apply %12(%14, %13) : $@convention(thin) (Builtin.Word, @thin Int.Type) -> Int
518+
store %15 to %11a : $*Int
519+
520+
%17 = dynamic_function_ref @closure0_guaranteed2 : $@convention(thin) (@guaranteed <τ_0_0> { var τ_0_0 } <Foo>, @guaranteed <τ_0_0> { var τ_0_0 } <Baz>, @guaranteed <τ_0_0> { var τ_0_0 } <Int>) -> Int
521+
%21 = partial_apply [callee_guaranteed] [on_stack] %17(%1, %6, %11) : $@convention(thin) (@guaranteed <τ_0_0> { var τ_0_0 } <Foo>, @guaranteed <τ_0_0> { var τ_0_0 } <Baz>, @guaranteed <τ_0_0> { var τ_0_0 } <Int>) -> Int
522+
%md = mark_dependence %21 :$@noescape @callee_guaranteed () -> Int on %1 : $<τ_0_0> { var τ_0_0 } <Foo>
523+
%md2 = mark_dependence %md :$@noescape @callee_guaranteed () -> Int on %6 : $<τ_0_0> { var τ_0_0 } <Baz>
524+
%md3 = mark_dependence %md2 :$@noescape @callee_guaranteed () -> Int on %11 : $<τ_0_0> { var τ_0_0 } <Int>
525+
apply %md3() : $@noescape @callee_guaranteed () -> Int
526+
dealloc_stack %21 : $@noescape @callee_guaranteed () -> Int
527+
strong_release %11 : $<τ_0_0> { var τ_0_0 } <Int>
528+
strong_release %6 : $<τ_0_0> { var τ_0_0 } <Baz>
529+
strong_release %1 : $<τ_0_0> { var τ_0_0 } <Foo>
530+
%tuple = tuple()
531+
return %tuple : $()
532+
}

0 commit comments

Comments
 (0)