Skip to content

[AddressLowering] Some small fixes. #61945

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions lib/SILOptimizer/Mandatory/AddressLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1159,7 +1159,7 @@ void OpaqueStorageAllocation::allocatePhi(PhiValue phi) {
coalescedPhi.coalesce(phi, pass.valueStorageMap);

SmallVector<SILValue, 4> coalescedValues;
coalescedValues.resize(coalescedPhi.getCoalescedOperands().size());
coalescedValues.reserve(coalescedPhi.getCoalescedOperands().size());
for (SILValue value : coalescedPhi.getCoalescedValues())
coalescedValues.push_back(value);

Expand Down Expand Up @@ -3362,8 +3362,21 @@ static void rewriteFunction(AddressLoweringState &pass) {
if (valueDef->getType().isAddress())
continue;

SmallPtrSet<Operand *, 8> originalUses;
SmallVector<Operand *, 8> uses(valueDef->getUses());
for (Operand *oper : uses) {
for (auto *oper : uses) {
originalUses.insert(oper);
UseRewriter::rewriteUse(oper, pass);
}
// Rewrite every new uses that was added.
uses.clear();
for (auto *use : valueDef->getUses()) {
if (originalUses.contains(use))
continue;
uses.push_back(use);
}
for (auto *oper : uses) {
assert(isa<DebugValueInst>(oper->getUser()));
UseRewriter::rewriteUse(oper, pass);
}
}
Expand Down Expand Up @@ -3396,7 +3409,7 @@ static void filterDeadArgs(OperandValueArrayRef origArgs,
SmallVectorImpl<SILValue> &newArgs) {
auto nextDeadArgI = deadArgIndices.begin();
for (unsigned i : indices(origArgs)) {
if (i == *nextDeadArgI) {
if (i == *nextDeadArgI && nextDeadArgI != deadArgIndices.end()) {
++nextDeadArgI;
continue;
}
Expand Down
5 changes: 3 additions & 2 deletions test/SILOptimizer/address_lowering.sil
Original file line number Diff line number Diff line change
Expand Up @@ -941,15 +941,16 @@ bb0(%0 : @owned $P):
// CHECK: bb0(%0 : $*any P):
// CHECK: [[ALLOCP:%.*]] = alloc_stack $any P, var, name "q"
// CHECK: copy_addr %0 to [init] [[ALLOCP]] : $*any P
// CHECK: debug_value %0 : $*any P, var, name "q"
// CHECK: [[OPEN:%.*]] = open_existential_addr immutable_access %0 : $*any P to $*@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541", any P) Self
// CHECK: [[OPTIONAL:%.*]] = alloc_stack $Optional<@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541", any P) Self>
// CHECK: witness_method $@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541", any P) Self, #P.foo : <Self where Self : P> (Self) -> () -> (), [[OPEN]] : $*@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541", any P) Self : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
// CHECK: [[INIT:%.*]] = init_enum_data_addr [[OPTIONAL]] : $*Optional<@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541", any P) Self>, #Optional.some!enumelt
// CHECK: copy_addr [[OPEN]] to [init] [[INIT]] : $*@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541", any P) Self
// CHECK: inject_enum_addr [[OPTIONAL]] : $*Optional<@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541", any P) Self>, #Optional.some!enumelt
// CHECK: [[DATA:%.*]] = unchecked_take_enum_data_addr [[OPTIONAL]] : $*Optional<@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541", any P) Self>, #Optional.some!enumelt
// CHECK: %10 = apply %{{.*}}<@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541", any P) Self>([[DATA]]) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
// CHECK: destroy_addr %9 : $*@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541", any P) Self
// CHECK: apply %{{.*}}<@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541", any P) Self>([[DATA]]) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
// CHECK: destroy_addr [[DATA:%[^,]+]] : $*@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541", any P) Self
// CHECK: destroy_addr [[ALLOCP]] : $*any P
// CHECK: destroy_addr %0 : $*any P
// CHECK: dealloc_stack [[OPTIONAL]] : $*Optional<@opened("EF755EF2-B636-11E7-B7B4-A45E60ECC541", any P) Self>
Expand Down
66 changes: 66 additions & 0 deletions test/SILOptimizer/address_lowering_phi.sil
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ enum Optional<T> {
case some(T)
}

struct S {}

struct SRef<T> {
@_hasStorage var object: AnyObject { get set }
@_hasStorage var element: T { get set }
Expand Down Expand Up @@ -470,3 +472,67 @@ bb2:
bb3(%phi : @owned $T):
return %phi : $T
}

// Check that the debug_value instruction that is created when deleting a load
// gets rewritten and doesn't obstruct the deletion of the phi.
// CHECK-LABEL: sil [ossa] @f100_store_phi : {{.*}} {
// CHECK: {{bb[0-9]+}}({{%[^,]+}} : $*Value):
// CHECK: [[TEMP:%[^,]+]] = alloc_stack $Value
// CHECK: [[VAR:%[^,]+]] = alloc_stack [lexical] $Value, var, name "value"
// CHECK: cond_br undef, bb2, bb1
// CHECK: bb3:
// CHECK: copy_addr [take] [[TEMP]] to [init] [[VAR]]
// CHECK: debug_value [[TEMP]] : $*Value, var, name "value"
// CHECK-LABEL: } // end sil function 'f100_store_phi'
sil [ossa] @f100_store_phi : $@convention(thin) <Value> (@in Value) -> () {
entry(%instance : @owned $Value):
%14 = alloc_stack [lexical] $Value, var, name "value"
cond_br undef, left, right

left:
br merge(%instance : $Value)

right:
br merge(%instance : $Value)

merge(%34 : @owned $Value):
store %34 to [init] %14 : $*Value
destroy_addr %14 : $*Value
dealloc_stack %14 : $*Value
%43 = tuple ()
return %43 : $()
}

// CHECK-LABEL: sil [ossa] @f105_phi_into_tuple : {{.*}} {
// CHECK: [[STORAGE:%[^,]+]] = alloc_stack $(Self, Builtin.Int1)
// CHECK: [[SELF_ADDR:%[^,]+]] = tuple_element_addr [[STORAGE]]
// CHECK: apply {{%[^,]+}}<Self>([[SELF_ADDR]])
// CHECK-LABEL: } // end sil function 'f105_phi_into_tuple'
sil [ossa] @f105_phi_into_tuple : $@convention(thin) <Self> () -> () {
%getOut = function_ref @getOut : $@convention(thin) <T> () -> @out T
%self = apply %getOut<Self>() : $@convention(thin) <τ_0_0> () -> @out τ_0_0
br exit(%self : $Self)

exit(%self_2 : @owned $Self):
%tuple = tuple (%self_2 : $Self, undef : $Bool)
destroy_value %tuple : $(Self, Bool)
%retval = tuple ()
return %retval : $()
}

// Check deleting the first of multiple block arguments.
// CHECK-LABEL: sil [ossa] @f110_nonfinal_argument : {{.*}} {
// CHECK: bb3({{%[^,]+}} : $S):
// CHECK-LABEL: } // end sil function 'f110_nonfinal_argument'
sil [ossa] @f110_nonfinal_argument : $@convention(thin) <T> (@in T, S) -> () {
entry(%instance : @owned $T, %s : $S):
cond_br undef, left, right
left:
br exit(%instance : $T, %s : $S)
right:
br exit(%instance : $T, %s : $S)
exit(%instance_2 : @owned $T, %s_2 : $S):
destroy_value %instance_2 : $T
%retval = tuple ()
return %retval : $()
}