diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h index 42af7bdcbe299..f26057f81ecb1 100644 --- a/include/swift/SIL/SILBuilder.h +++ b/include/swift/SIL/SILBuilder.h @@ -153,7 +153,8 @@ class SILBuilder { if (InsertPt == BB->end()) return; // Set the opened archetype context from the instruction. - addOpenedArchetypeOperands(&*InsertPt); + this->getOpenedArchetypes().addOpenedArchetypeOperands( + InsertPt->getTypeDependentOperands()); } /// setInsertionPoint - Set the insertion point to insert before the specified @@ -199,7 +200,10 @@ class SILBuilder { //===--------------------------------------------------------------------===// // Opened archetypes handling //===--------------------------------------------------------------------===// - void addOpenedArchetypeOperands(SILInstruction *I); + void addOpenedArchetypeOperands(SILInstruction *I) { + getOpenedArchetypes().addOpenedArchetypeOperands( + I->getTypeDependentOperands()); + } //===--------------------------------------------------------------------===// // Type remapping diff --git a/include/swift/SIL/SILOpenedArchetypesTracker.h b/include/swift/SIL/SILOpenedArchetypesTracker.h index c8c1600d88d69..92987a7ef2e21 100644 --- a/include/swift/SIL/SILOpenedArchetypesTracker.h +++ b/include/swift/SIL/SILOpenedArchetypesTracker.h @@ -78,19 +78,16 @@ class SILOpenedArchetypesTracker : public DeleteNotificationHandler { // Can be used to incrementally populate the mapping, e.g. // if it is done when performing a scan of all instructions // inside a function. - // Returns true if any opened archetypes were registered. - bool registerOpenedArchetypes(const SILInstruction *I); + void registerOpenedArchetypes(const SILInstruction *I); // Register opened archetypes whose definitions are referenced by // the typedef operands of this instruction. - // Returns true if any opened archetypes were registered. - bool registerUsedOpenedArchetypes(const SILInstruction *I); + void registerUsedOpenedArchetypes(const SILInstruction *I); // Register opened archetypes referenced by this type, if they // are not registered yet. Create placeholders representing forward // definitions of these opened archetypes. - // Returns true if any opened archetypes were registered. - bool registerUsedOpenedArchetypes(CanType Ty); + void registerUsedOpenedArchetypes(CanType Ty); // Unregister archetypes opened by a given instruction. // Should be only called when this instruction is to be removed. diff --git a/lib/SIL/SILBuilder.cpp b/lib/SIL/SILBuilder.cpp index 38f4b3df2f5bc..ca36bf12f018c 100644 --- a/lib/SIL/SILBuilder.cpp +++ b/lib/SIL/SILBuilder.cpp @@ -344,34 +344,3 @@ SILValue SILBuilder::emitObjCToThickMetatype(SILLocation Loc, SILValue Op, // Just create the objc_to_thick_metatype instruction. return createObjCToThickMetatype(Loc, Op, Ty); } - -/// Add opned archetypes defined or used by the current instruction. -/// If there are no such opened archetypes in the current instruction -/// and it is an instruction with just one operand, try to perform -/// the same action for the instruction defining an operand, because -/// it may have some opened archetypes used or defined. -void SILBuilder::addOpenedArchetypeOperands(SILInstruction *I) { - while (I && I->getNumOperands() == 1 && - I->getNumTypeDependentOperands() == 0) { - I = dyn_cast(I->getOperand(0)); - if (!I) - return; - // If it is a definition of an opened archetype, - // register it and exit. - auto Archetype = getOpenedArchetypeOf(I); - if (!Archetype) - continue; - auto Def = OpenedArchetypes.getOpenedArchetypeDef(Archetype); - // Return if it is a known open archetype. - if (Def) - return; - // Otherwise register it and return. - if (OpenedArchetypesTracker) - OpenedArchetypesTracker->addOpenedArchetypeDef(Archetype, I); - return; - } - - if (I && I->getNumTypeDependentOperands() > 0) { - OpenedArchetypes.addOpenedArchetypeOperands(I->getTypeDependentOperands()); - } -} diff --git a/lib/SIL/SILOpenedArchetypesTracker.cpp b/lib/SIL/SILOpenedArchetypesTracker.cpp index d94795ba8820b..cd298c5d9bee6 100644 --- a/lib/SIL/SILOpenedArchetypesTracker.cpp +++ b/lib/SIL/SILOpenedArchetypesTracker.cpp @@ -39,11 +39,10 @@ bool SILOpenedArchetypesTracker::hasUnresolvedOpenedArchetypeDefinitions() { return false; } -bool SILOpenedArchetypesTracker::registerUsedOpenedArchetypes(CanType Ty) { - bool Registered = false; +void SILOpenedArchetypesTracker::registerUsedOpenedArchetypes(CanType Ty) { // Nothing else to be done if the type does not contain an opened archetype. if (!Ty || !Ty->hasOpenedExistential()) - return Registered; + return; // Find all opened existentials used by this type and check if their // definitions are known. @@ -65,39 +64,33 @@ bool SILOpenedArchetypesTracker::registerUsedOpenedArchetypes(CanType Ty) { // archetype can be constructed. addOpenedArchetypeDef(archetypeTy, Placeholder); }); - return Registered; } // Register archetypes opened by a given instruction. // Can be used to incrementally populate the mapping, e.g. // if it is done when performing a scan of all instructions // inside a function. -bool SILOpenedArchetypesTracker::registerOpenedArchetypes( +void SILOpenedArchetypesTracker::registerOpenedArchetypes( const SILInstruction *I) { assert((!I->getParent() || I->getFunction() == &F) && "Instruction does not belong to a proper SILFunction"); auto Archetype = getOpenedArchetypeOf(I); - if (!Archetype) - return false; - addOpenedArchetypeDef(Archetype, I); - return true; + if (Archetype) + addOpenedArchetypeDef(Archetype, I); } // Register opened archetypes whose definitions are referenced by // the typedef operands of this instruction. -bool SILOpenedArchetypesTracker::registerUsedOpenedArchetypes( +void SILOpenedArchetypesTracker::registerUsedOpenedArchetypes( const SILInstruction *I) { assert((!I->getParent() || I->getFunction() == &F) && "Instruction does not belong to a proper SILFunction"); - bool Registered = false; for (auto &Op : I->getTypeDependentOperands()) { auto OpenedArchetypeDef = Op.get(); if (auto *DefInst = dyn_cast(OpenedArchetypeDef)) { addOpenedArchetypeDef(getOpenedArchetypeOf(DefInst), OpenedArchetypeDef); - Registered = true; } } - return Registered; } // Unregister archetypes opened by a given instruction. diff --git a/lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp b/lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp index 47e413772b26b..8cf80e33944ae 100644 --- a/lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp +++ b/lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp @@ -39,13 +39,8 @@ namespace { struct OwnershipModelEliminatorVisitor : SILInstructionVisitor { SILBuilder &B; - SILOpenedArchetypesTracker OpenedArchetypesTracker; - - OwnershipModelEliminatorVisitor(SILBuilder &B) - : B(B), OpenedArchetypesTracker(B.getFunction()) { - B.setOpenedArchetypesTracker(&OpenedArchetypesTracker); - } + OwnershipModelEliminatorVisitor(SILBuilder &B) : B(B) {} void beforeVisit(ValueBase *V) { auto *I = cast(V); B.setInsertionPoint(I); diff --git a/test/SILOptimizer/opened_archetype_operands_tracking.sil b/test/SILOptimizer/opened_archetype_operands_tracking.sil index 6dc748b0a995d..e215014210b15 100644 --- a/test/SILOptimizer/opened_archetype_operands_tracking.sil +++ b/test/SILOptimizer/opened_archetype_operands_tracking.sil @@ -130,102 +130,3 @@ bb0(%0 : $*View, %1 : $@thin DynamicItem.Type): dealloc_stack %2 : $*DynamicItem return %9 : $DynamicItem } - -func use(_ t: T) - -final class Foo where T : P { - init(_ x: T) - @sil_stored final var x: T { get set } - @sil_stored final var y: T { get set } - deinit -} - -extension P { - @inline(__always) func foo() -} - -public func bar(_ p: P) - -// Foo.__allocating_init(_:) -sil @Foo_alloc_init : $@convention(method) (@in T, @thick Foo.Type) -> @owned Foo { -bb0(%0 : $*T, %1 : $@thick Foo.Type): - %2 = alloc_ref $Foo - // function_ref Foo.init(_:) - %3 = function_ref @Foo_init : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in τ_0_0, @owned Foo<τ_0_0>) -> @owned Foo<τ_0_0> - %4 = apply %3(%0, %2) : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in τ_0_0, @owned Foo<τ_0_0>) -> @owned Foo<τ_0_0> - return %4 : $Foo -} // end sil function 'Foo_alloc_init' - -// Foo.init(_:) -sil @Foo_init : $@convention(method) (@in T, @owned Foo) -> @owned Foo { -bb0(%0 : $*T, %1 : $Foo): - %4 = alloc_stack $T - copy_addr %0 to [initialization] %4 : $*T - %6 = ref_element_addr %1 : $Foo, #Foo.x - copy_addr [take] %4 to [initialization] %6 : $*T - dealloc_stack %4 : $*T - %9 = alloc_stack $T - copy_addr %0 to [initialization] %9 : $*T - %11 = ref_element_addr %1 : $Foo, #Foo.y - copy_addr [take] %9 to [initialization] %11 : $*T - dealloc_stack %9 : $*T - destroy_addr %0 : $*T - return %1 : $Foo -} // end sil function 'Foo_init' - -// P.foo() -sil [always_inline] @P_foo : $@convention(method) (@in_guaranteed Self) -> () { -bb0(%0 : $*Self): - // function_ref Foo.__allocating_init(_:) - %2 = function_ref @Foo_alloc_init : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in τ_0_0, @thick Foo<τ_0_0>.Type) -> @owned Foo<τ_0_0> - %3 = metatype $@thick Foo.Type - %4 = alloc_stack $Self - copy_addr %0 to [initialization] %4 : $*Self - %6 = apply %2(%4, %3) : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in τ_0_0, @thick Foo<τ_0_0>.Type) -> @owned Foo<τ_0_0> - dealloc_stack %4 : $*Self - // function_ref use - %9 = function_ref @use : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - %10 = ref_element_addr %6 : $Foo, #Foo.x - %11 = alloc_stack $Self - copy_addr %10 to [initialization] %11 : $*Self - %13 = apply %9(%11) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - dealloc_stack %11 : $*Self - // function_ref use - %15 = function_ref @use : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - %16 = ref_element_addr %6 : $Foo, #Foo.y - %17 = alloc_stack $Self - copy_addr %16 to [initialization] %17 : $*Self - %19 = apply %15(%17) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - dealloc_stack %17 : $*Self - strong_release %6 : $Foo - %22 = tuple () - return %22 : $() -} // end sil function 'P_foo' - -// use -sil hidden_external @use : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - -// Check that everything besides the external function use is inlined into bar. -// It should contain alloc_ref and alloc_stack instructions using opened archetypes. -// CHECK-LABEL: sil @bar -// CHECK: open_existential{{.*}}C08045E0-2779-11E7-970E-A45E60E99281 -// CHECK: alloc_ref{{.*}}C08045E0-2779-11E7-970E-A45E60E99281 -// CHECK: alloc_stack{{.*}}C08045E0-2779-11E7-970E-A45E60E99281 -// CHECK-NOT: function_ref @use -// CHECK: function_ref @use -// CHECK-NOT: function_ref -// CHECK: dealloc_stack{{.*}}C08045E0-2779-11E7-970E-A45E60E99281 -// CHECK: strong_release{{.*}}C08045E0-2779-11E7-970E-A45E60E99281 -// CHECK: dealloc_ref{{.*}}C08045E0-2779-11E7-970E-A45E60E99281 -// CHECK: end sil function 'bar' -sil @bar : $@convention(thin) (@in P) -> () { -bb0(%0 : $*P): - %2 = open_existential_addr immutable_access %0 : $*P to $*@opened("C08045E0-2779-11E7-970E-A45E60E99281") P - // function_ref P.foo() - %3 = function_ref @P_foo : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> () - %4 = apply %3<@opened("C08045E0-2779-11E7-970E-A45E60E99281") P>(%2) : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> () - destroy_addr %0 : $*P - %6 = tuple () - return %6 : $() -} // end sil function 'bar' -