mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[ownership] Update SROA to support OSSA.
Use destructure to chop up allocations. Other than that, just add correct load/store qualifiers.
This commit is contained in:
committed by
Michael Gottesman
parent
c6ea30c963
commit
12d652e39f
@@ -67,8 +67,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
SILValue createAgg(SILBuilder &B, SILLocation Loc, SILType Ty,
|
SILValue createAgg(SILBuilder &B, SILLocation Loc, SILType Ty,
|
||||||
ArrayRef<SILValue> Elements);
|
ArrayRef<SILValue> Elements);
|
||||||
SILValue createAggProjection(SILBuilder &B, SILLocation Loc,
|
|
||||||
SILValue Operand, unsigned EltNo);
|
|
||||||
unsigned getEltNoForProjection(SILInstruction *Inst);
|
unsigned getEltNoForProjection(SILInstruction *Inst);
|
||||||
void createAllocas(llvm::SmallVector<AllocStackInst *, 4> &NewAllocations);
|
void createAllocas(llvm::SmallVector<AllocStackInst *, 4> &NewAllocations);
|
||||||
};
|
};
|
||||||
@@ -87,24 +85,6 @@ SROAMemoryUseAnalyzer::createAgg(SILBuilder &B, SILLocation Loc,
|
|||||||
return B.createStruct(Loc, Ty, Elements);
|
return B.createStruct(Loc, Ty, Elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
SILValue
|
|
||||||
SROAMemoryUseAnalyzer::createAggProjection(SILBuilder &B, SILLocation Loc,
|
|
||||||
SILValue Operand,
|
|
||||||
unsigned EltNo) {
|
|
||||||
if (TT)
|
|
||||||
return B.createTupleExtract(Loc, Operand, EltNo);
|
|
||||||
|
|
||||||
assert(SD && "SD should not be null since either it or TT must be set at "
|
|
||||||
"this point.");
|
|
||||||
|
|
||||||
auto Properties = SD->getStoredProperties();
|
|
||||||
unsigned Counter = 0;
|
|
||||||
for (auto *D : Properties)
|
|
||||||
if (Counter++ == EltNo)
|
|
||||||
return B.createStructExtract(Loc, Operand, D);
|
|
||||||
llvm_unreachable("Unknown field.");
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned SROAMemoryUseAnalyzer::getEltNoForProjection(SILInstruction *Inst) {
|
unsigned SROAMemoryUseAnalyzer::getEltNoForProjection(SILInstruction *Inst) {
|
||||||
if (TT)
|
if (TT)
|
||||||
return cast<TupleElementAddrInst>(Inst)->getFieldNo();
|
return cast<TupleElementAddrInst>(Inst)->getFieldNo();
|
||||||
@@ -249,9 +229,10 @@ void SROAMemoryUseAnalyzer::chopUpAlloca(std::vector<AllocStackInst *> &Worklist
|
|||||||
for (auto *LI : Loads) {
|
for (auto *LI : Loads) {
|
||||||
SILBuilderWithScope B(LI);
|
SILBuilderWithScope B(LI);
|
||||||
llvm::SmallVector<SILValue, 4> Elements;
|
llvm::SmallVector<SILValue, 4> Elements;
|
||||||
for (auto *NewAI : NewAllocations)
|
for (auto *NewAI : NewAllocations) {
|
||||||
Elements.push_back(B.createLoad(LI->getLoc(), NewAI,
|
Elements.push_back(B.emitLoadValueOperation(LI->getLoc(), NewAI,
|
||||||
LoadOwnershipQualifier::Unqualified));
|
LI->getOwnershipQualifier()));
|
||||||
|
}
|
||||||
SILValue Agg = createAgg(B, LI->getLoc(), LI->getType().getObjectType(),
|
SILValue Agg = createAgg(B, LI->getLoc(), LI->getType().getObjectType(),
|
||||||
Elements);
|
Elements);
|
||||||
LI->replaceAllUsesWith(Agg);
|
LI->replaceAllUsesWith(Agg);
|
||||||
@@ -260,12 +241,15 @@ void SROAMemoryUseAnalyzer::chopUpAlloca(std::vector<AllocStackInst *> &Worklist
|
|||||||
|
|
||||||
// Change any aggregate stores into extracts + field stores.
|
// Change any aggregate stores into extracts + field stores.
|
||||||
for (auto *SI : Stores) {
|
for (auto *SI : Stores) {
|
||||||
SILBuilderWithScope B(SI);
|
SILBuilderWithScope builder(SI);
|
||||||
for (unsigned EltNo : indices(NewAllocations))
|
SmallVector<SILValue, 8> destructured;
|
||||||
B.createStore(SI->getLoc(),
|
builder.emitDestructureValueOperation(SI->getLoc(), SI->getSrc(),
|
||||||
createAggProjection(B, SI->getLoc(), SI->getSrc(), EltNo),
|
destructured);
|
||||||
NewAllocations[EltNo],
|
for (unsigned eltNo : indices(NewAllocations)) {
|
||||||
StoreOwnershipQualifier::Unqualified);
|
builder.emitStoreValueOperation(SI->getLoc(), destructured[eltNo],
|
||||||
|
NewAllocations[eltNo],
|
||||||
|
StoreOwnershipQualifier::Init);
|
||||||
|
}
|
||||||
SI->eraseFromParent();
|
SI->eraseFromParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,10 +340,6 @@ public:
|
|||||||
void run() override {
|
void run() override {
|
||||||
SILFunction *F = getFunction();
|
SILFunction *F = getFunction();
|
||||||
|
|
||||||
// FIXME: We should be able to handle ownership.
|
|
||||||
if (F->hasOwnership())
|
|
||||||
return;
|
|
||||||
|
|
||||||
LLVM_DEBUG(llvm::dbgs() << "***** SROA on function: " << F->getName()
|
LLVM_DEBUG(llvm::dbgs() << "***** SROA on function: " << F->getName()
|
||||||
<< " *****\n");
|
<< " *****\n");
|
||||||
|
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ sil @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
|||||||
// CHECK: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int32
|
// CHECK: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int32
|
||||||
// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int64
|
// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int64
|
||||||
// CHECK: [[VAR_4:%[0-9]+]] = struct_extract [[VAR_0]] : $S1, #S1.x
|
// CHECK: [[VAR_4:%[0-9]+]] = struct_extract [[VAR_0]] : $S1, #S1.x
|
||||||
// CHECK: store [[VAR_4]] to [[VAR_1]] : $*Builtin.Int1
|
|
||||||
// CHECK: [[VAR_6:%[0-9]+]] = struct_extract [[VAR_0]] : $S1, #S1.y
|
// CHECK: [[VAR_6:%[0-9]+]] = struct_extract [[VAR_0]] : $S1, #S1.y
|
||||||
// CHECK: store [[VAR_6]] to [[VAR_2]] : $*Builtin.Int32
|
|
||||||
// CHECK: [[VAR_8:%[0-9]+]] = struct_extract [[VAR_0]] : $S1, #S1.z
|
// CHECK: [[VAR_8:%[0-9]+]] = struct_extract [[VAR_0]] : $S1, #S1.z
|
||||||
|
// CHECK: store [[VAR_4]] to [[VAR_1]] : $*Builtin.Int1
|
||||||
|
// CHECK: store [[VAR_6]] to [[VAR_2]] : $*Builtin.Int32
|
||||||
// CHECK: store [[VAR_8]] to [[VAR_3]] : $*Builtin.Int64
|
// CHECK: store [[VAR_8]] to [[VAR_3]] : $*Builtin.Int64
|
||||||
// CHECK: [[VAR_10:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
// CHECK: [[VAR_10:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
// CHECK: [[VAR_11:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int32
|
// CHECK: [[VAR_11:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int32
|
||||||
@@ -91,13 +91,13 @@ struct S2 {
|
|||||||
// CHECK: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int32
|
// CHECK: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int32
|
||||||
// CHECK: [[VAR_5:%[0-9]+]] = alloc_stack $Builtin.Int64
|
// CHECK: [[VAR_5:%[0-9]+]] = alloc_stack $Builtin.Int64
|
||||||
// CHECK: [[VAR_6:%[0-9]+]] = struct_extract [[VAR_0]] : $S2, #S2.alpha
|
// CHECK: [[VAR_6:%[0-9]+]] = struct_extract [[VAR_0]] : $S2, #S2.alpha
|
||||||
// CHECK: store [[VAR_6]] to [[VAR_2]] : $*Builtin.FPIEEE32
|
|
||||||
// CHECK: [[VAR_8:%[0-9]+]] = struct_extract [[VAR_0]] : $S2, #S2.beta
|
// CHECK: [[VAR_8:%[0-9]+]] = struct_extract [[VAR_0]] : $S2, #S2.beta
|
||||||
|
// CHECK: store [[VAR_6]] to [[VAR_2]] : $*Builtin.FPIEEE32
|
||||||
// CHECK: [[VAR_9:%[0-9]+]] = struct_extract [[VAR_8]] : $S1, #S1.x
|
// CHECK: [[VAR_9:%[0-9]+]] = struct_extract [[VAR_8]] : $S1, #S1.x
|
||||||
// CHECK: store [[VAR_9]] to [[VAR_3]] : $*Builtin.Int1
|
|
||||||
// CHECK: [[VAR_11:%[0-9]+]] = struct_extract [[VAR_8]] : $S1, #S1.y
|
// CHECK: [[VAR_11:%[0-9]+]] = struct_extract [[VAR_8]] : $S1, #S1.y
|
||||||
// CHECK: store [[VAR_11]] to [[VAR_4]] : $*Builtin.Int32
|
|
||||||
// CHECK: [[VAR_13:%[0-9]+]] = struct_extract [[VAR_8]] : $S1, #S1.z
|
// CHECK: [[VAR_13:%[0-9]+]] = struct_extract [[VAR_8]] : $S1, #S1.z
|
||||||
|
// CHECK: store [[VAR_9]] to [[VAR_3]] : $*Builtin.Int1
|
||||||
|
// CHECK: store [[VAR_11]] to [[VAR_4]] : $*Builtin.Int32
|
||||||
// CHECK: store [[VAR_13]] to [[VAR_5]] : $*Builtin.Int64
|
// CHECK: store [[VAR_13]] to [[VAR_5]] : $*Builtin.Int64
|
||||||
// CHECK: [[VAR_15:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int1
|
// CHECK: [[VAR_15:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int1
|
||||||
// CHECK: [[VAR_16:%[0-9]+]] = load [[VAR_4]] : $*Builtin.Int32
|
// CHECK: [[VAR_16:%[0-9]+]] = load [[VAR_4]] : $*Builtin.Int32
|
||||||
@@ -159,13 +159,13 @@ struct S3 {
|
|||||||
// CHECK: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int16
|
// CHECK: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int16
|
||||||
// CHECK: [[VAR_5:%[0-9]+]] = alloc_stack $Builtin.FPIEEE32
|
// CHECK: [[VAR_5:%[0-9]+]] = alloc_stack $Builtin.FPIEEE32
|
||||||
// CHECK: [[VAR_6:%[0-9]+]] = struct_extract [[VAR_0]] : $S3, #S3.gamma
|
// CHECK: [[VAR_6:%[0-9]+]] = struct_extract [[VAR_0]] : $S3, #S3.gamma
|
||||||
// CHECK: [[VAR_7:%[0-9]+]] = tuple_extract [[VAR_6]] : $(Builtin.Int32, Builtin.Int64, Builtin.Int16), 0
|
|
||||||
// CHECK: store [[VAR_7]] to [[VAR_2]] : $*Builtin.Int32
|
|
||||||
// CHECK: [[VAR_9:%[0-9]+]] = tuple_extract [[VAR_6]] : $(Builtin.Int32, Builtin.Int64, Builtin.Int16), 1
|
|
||||||
// CHECK: store [[VAR_9]] to [[VAR_3]] : $*Builtin.Int64
|
|
||||||
// CHECK: [[VAR_11:%[0-9]+]] = tuple_extract [[VAR_6]] : $(Builtin.Int32, Builtin.Int64, Builtin.Int16), 2
|
|
||||||
// CHECK: store [[VAR_11]] to [[VAR_4]] : $*Builtin.Int16
|
|
||||||
// CHECK: [[VAR_13:%[0-9]+]] = struct_extract [[VAR_0]] : $S3, #S3.delta
|
// CHECK: [[VAR_13:%[0-9]+]] = struct_extract [[VAR_0]] : $S3, #S3.delta
|
||||||
|
// CHECK: [[VAR_7:%[0-9]+]] = tuple_extract [[VAR_6]] : $(Builtin.Int32, Builtin.Int64, Builtin.Int16), 0
|
||||||
|
// CHECK: [[VAR_9:%[0-9]+]] = tuple_extract [[VAR_6]] : $(Builtin.Int32, Builtin.Int64, Builtin.Int16), 1
|
||||||
|
// CHECK: [[VAR_11:%[0-9]+]] = tuple_extract [[VAR_6]] : $(Builtin.Int32, Builtin.Int64, Builtin.Int16), 2
|
||||||
|
// CHECK: store [[VAR_7]] to [[VAR_2]] : $*Builtin.Int32
|
||||||
|
// CHECK: store [[VAR_9]] to [[VAR_3]] : $*Builtin.Int64
|
||||||
|
// CHECK: store [[VAR_11]] to [[VAR_4]] : $*Builtin.Int16
|
||||||
// CHECK: store [[VAR_13]] to [[VAR_5]] : $*Builtin.FPIEEE32
|
// CHECK: store [[VAR_13]] to [[VAR_5]] : $*Builtin.FPIEEE32
|
||||||
// CHECK: [[VAR_15:%[0-9]+]] = function_ref @use_tup : $@convention(thin) ((Builtin.Int32, Builtin.Int64, Builtin.Int16)) -> ()
|
// CHECK: [[VAR_15:%[0-9]+]] = function_ref @use_tup : $@convention(thin) ((Builtin.Int32, Builtin.Int64, Builtin.Int16)) -> ()
|
||||||
// CHECK: [[VAR_16:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int32
|
// CHECK: [[VAR_16:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int32
|
||||||
@@ -219,10 +219,10 @@ bb0(%0 : $S3, %1 : $Builtin.Int64):
|
|||||||
// CHECK: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int32
|
// CHECK: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int32
|
||||||
// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int64
|
// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int64
|
||||||
// CHECK: [[VAR_4:%[0-9]+]] = tuple_extract [[VAR_0]] : $(Builtin.Int1, Builtin.Int32, Builtin.Int64), 0
|
// CHECK: [[VAR_4:%[0-9]+]] = tuple_extract [[VAR_0]] : $(Builtin.Int1, Builtin.Int32, Builtin.Int64), 0
|
||||||
// CHECK: store [[VAR_4]] to [[VAR_1]] : $*Builtin.Int1
|
|
||||||
// CHECK: [[VAR_6:%[0-9]+]] = tuple_extract [[VAR_0]] : $(Builtin.Int1, Builtin.Int32, Builtin.Int64), 1
|
// CHECK: [[VAR_6:%[0-9]+]] = tuple_extract [[VAR_0]] : $(Builtin.Int1, Builtin.Int32, Builtin.Int64), 1
|
||||||
// CHECK: store [[VAR_6]] to [[VAR_2]] : $*Builtin.Int32
|
|
||||||
// CHECK: [[VAR_8:%[0-9]+]] = tuple_extract [[VAR_0]] : $(Builtin.Int1, Builtin.Int32, Builtin.Int64), 2
|
// CHECK: [[VAR_8:%[0-9]+]] = tuple_extract [[VAR_0]] : $(Builtin.Int1, Builtin.Int32, Builtin.Int64), 2
|
||||||
|
// CHECK: store [[VAR_4]] to [[VAR_1]] : $*Builtin.Int1
|
||||||
|
// CHECK: store [[VAR_6]] to [[VAR_2]] : $*Builtin.Int32
|
||||||
// CHECK: store [[VAR_8]] to [[VAR_3]] : $*Builtin.Int64
|
// CHECK: store [[VAR_8]] to [[VAR_3]] : $*Builtin.Int64
|
||||||
// CHECK: [[VAR_10:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
// CHECK: [[VAR_10:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
// CHECK: [[VAR_11:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int32
|
// CHECK: [[VAR_11:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int32
|
||||||
@@ -267,11 +267,11 @@ sil @use_str4 : $@convention(thin) (S4) -> ()
|
|||||||
// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int32
|
// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int32
|
||||||
// CHECK: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int16
|
// CHECK: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int16
|
||||||
// CHECK: [[VAR_5:%[0-9]+]] = tuple_extract [[VAR_0]] : $(S4, Builtin.Int16), 0
|
// CHECK: [[VAR_5:%[0-9]+]] = tuple_extract [[VAR_0]] : $(S4, Builtin.Int16), 0
|
||||||
// CHECK: [[VAR_6:%[0-9]+]] = struct_extract [[VAR_5]] : $S4, #S4.aleph
|
|
||||||
// CHECK: store [[VAR_6]] to [[VAR_2]] : $*Builtin.Int64
|
|
||||||
// CHECK: [[VAR_8:%[0-9]+]] = struct_extract [[VAR_5]] : $S4, #S4.bet
|
|
||||||
// CHECK: store [[VAR_8]] to [[VAR_3]] : $*Builtin.Int32
|
|
||||||
// CHECK: [[VAR_10:%[0-9]+]] = tuple_extract [[VAR_0]] : $(S4, Builtin.Int16), 1
|
// CHECK: [[VAR_10:%[0-9]+]] = tuple_extract [[VAR_0]] : $(S4, Builtin.Int16), 1
|
||||||
|
// CHECK: [[VAR_6:%[0-9]+]] = struct_extract [[VAR_5]] : $S4, #S4.aleph
|
||||||
|
// CHECK: [[VAR_8:%[0-9]+]] = struct_extract [[VAR_5]] : $S4, #S4.bet
|
||||||
|
// CHECK: store [[VAR_6]] to [[VAR_2]] : $*Builtin.Int64
|
||||||
|
// CHECK: store [[VAR_8]] to [[VAR_3]] : $*Builtin.Int32
|
||||||
// CHECK: store [[VAR_10]] to [[VAR_4]] : $*Builtin.Int16
|
// CHECK: store [[VAR_10]] to [[VAR_4]] : $*Builtin.Int16
|
||||||
// CHECK: [[VAR_12:%[0-9]+]] = function_ref @use_str4 : $@convention(thin) (S4) -> ()
|
// CHECK: [[VAR_12:%[0-9]+]] = function_ref @use_str4 : $@convention(thin) (S4) -> ()
|
||||||
// CHECK: [[VAR_13:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int64
|
// CHECK: [[VAR_13:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int64
|
||||||
@@ -325,11 +325,11 @@ sil @use_int16 : $@convention(thin) (Builtin.Int16) -> ()
|
|||||||
// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int32
|
// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int32
|
||||||
// CHECK: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int16
|
// CHECK: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int16
|
||||||
// CHECK: [[VAR_5:%[0-9]+]] = tuple_extract [[VAR_0]] : $((Builtin.Int64, Builtin.Int32), Builtin.Int16), 0
|
// CHECK: [[VAR_5:%[0-9]+]] = tuple_extract [[VAR_0]] : $((Builtin.Int64, Builtin.Int32), Builtin.Int16), 0
|
||||||
// CHECK: [[VAR_6:%[0-9]+]] = tuple_extract [[VAR_5]] : $(Builtin.Int64, Builtin.Int32), 0
|
|
||||||
// CHECK: store [[VAR_6]] to [[VAR_2]] : $*Builtin.Int64
|
|
||||||
// CHECK: [[VAR_8:%[0-9]+]] = tuple_extract [[VAR_5]] : $(Builtin.Int64, Builtin.Int32), 1
|
|
||||||
// CHECK: store [[VAR_8]] to [[VAR_3]] : $*Builtin.Int32
|
|
||||||
// CHECK: [[VAR_10:%[0-9]+]] = tuple_extract [[VAR_0]] : $((Builtin.Int64, Builtin.Int32), Builtin.Int16), 1
|
// CHECK: [[VAR_10:%[0-9]+]] = tuple_extract [[VAR_0]] : $((Builtin.Int64, Builtin.Int32), Builtin.Int16), 1
|
||||||
|
// CHECK: [[VAR_6:%[0-9]+]] = tuple_extract [[VAR_5]] : $(Builtin.Int64, Builtin.Int32), 0
|
||||||
|
// CHECK: [[VAR_8:%[0-9]+]] = tuple_extract [[VAR_5]] : $(Builtin.Int64, Builtin.Int32), 1
|
||||||
|
// CHECK: store [[VAR_6]] to [[VAR_2]] : $*Builtin.Int64
|
||||||
|
// CHECK: store [[VAR_8]] to [[VAR_3]] : $*Builtin.Int32
|
||||||
// CHECK: store [[VAR_10]] to [[VAR_4]] : $*Builtin.Int16
|
// CHECK: store [[VAR_10]] to [[VAR_4]] : $*Builtin.Int16
|
||||||
// CHECK: [[VAR_12:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int64
|
// CHECK: [[VAR_12:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int64
|
||||||
// CHECK: [[VAR_13:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int32
|
// CHECK: [[VAR_13:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int32
|
||||||
|
|||||||
498
test/SILOptimizer/sroa_ossa.sil
Normal file
498
test/SILOptimizer/sroa_ossa.sil
Normal file
@@ -0,0 +1,498 @@
|
|||||||
|
// RUN: %target-sil-opt -enable-sil-verify-all -sroa %s | %FileCheck %s
|
||||||
|
|
||||||
|
sil_stage canonical
|
||||||
|
|
||||||
|
import Builtin
|
||||||
|
import Swift
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
// Struct with Scalar Fields //
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
|
struct S1 {
|
||||||
|
var x : Builtin.Int1
|
||||||
|
var y : Builtin.Int32
|
||||||
|
var z : Builtin.Int64
|
||||||
|
}
|
||||||
|
|
||||||
|
sil [ossa] @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
|
||||||
|
// CHECK-LABEL: sil [ossa] @struct_with_scalar_fields : $@convention(thin) (S1) -> ()
|
||||||
|
// CHECK: bb0([[VAR_0:%[0-9]+]] : $S1):
|
||||||
|
|
||||||
|
// CHECK-NEXT: [[VAR_1:%[0-9]+]] = alloc_stack $Builtin.Int1
|
||||||
|
// CHECK-NEXT: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int64
|
||||||
|
// CHECK-NEXT: ([[VAR_4:%[0-9]+]], [[VAR_6:%[0-9]+]], [[VAR_8:%[0-9]+]]) = destructure_struct [[VAR_0]]
|
||||||
|
// CHECK-NEXT: store [[VAR_4]] to [trivial] [[VAR_1]] : $*Builtin.Int1
|
||||||
|
// CHECK-NEXT: store [[VAR_6]] to [trivial] [[VAR_2]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: store [[VAR_8]] to [trivial] [[VAR_3]] : $*Builtin.Int64
|
||||||
|
|
||||||
|
// CHECK-NEXT: function_ref
|
||||||
|
// CHECK-NEXT: [[VAR_10:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_11:%[0-9]+]] = load [trivial] [[VAR_2]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_12:%[0-9]+]] = apply [[VAR_10]]([[VAR_11]]) : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_13:%[0-9]+]] = load [trivial] [[VAR_1]] : $*Builtin.Int1
|
||||||
|
// CHECK-NEXT: [[VAR_14:%[0-9]+]] = load [trivial] [[VAR_2]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_15:%[0-9]+]] = load [trivial] [[VAR_3]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: [[VAR_16:%[0-9]+]] = struct $S1 ([[VAR_13]] : $Builtin.Int1, [[VAR_14]] : $Builtin.Int32, [[VAR_15]] : $Builtin.Int64)
|
||||||
|
|
||||||
|
// CHECK: dealloc_stack [[VAR_3]] : $*Builtin.Int64
|
||||||
|
// CHECK: dealloc_stack [[VAR_2]] : $*Builtin.Int32
|
||||||
|
// CHECK: dealloc_stack [[VAR_1]] : $*Builtin.Int1
|
||||||
|
|
||||||
|
// CHECK: [[VAR_20:%[0-9]+]] = tuple ()
|
||||||
|
// CHECK: return [[VAR_20]] : $()
|
||||||
|
sil [ossa] @struct_with_scalar_fields : $@convention(thin) (S1) -> () {
|
||||||
|
bb0(%0 : $S1):
|
||||||
|
%1 = alloc_stack $S1
|
||||||
|
debug_value %1 : $*S1 // should not prevent the optimization
|
||||||
|
debug_value %1 : $*S1 // should not prevent the optimization
|
||||||
|
store %0 to [trivial] %1 : $*S1
|
||||||
|
%2 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
%3 = struct_element_addr %1 : $*S1, #S1.y
|
||||||
|
%4 = load [trivial] %3 : $*Builtin.Int32
|
||||||
|
apply %2(%4) : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
%5 = load [trivial] %1 : $*S1
|
||||||
|
dealloc_stack %1 : $*S1
|
||||||
|
%6 = tuple ()
|
||||||
|
return %6 : $()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: sil [ossa] @dont_sroa_without_benefit : $@convention(thin) (S1) -> S1
|
||||||
|
// CHECK: bb0
|
||||||
|
// CHECK-NEXT: alloc_stack $S1
|
||||||
|
// CHECK-NEXT: store %0 to [trivial] %1 : $*S1
|
||||||
|
// CHECK-NEXT: load [trivial] %1 : $*S1
|
||||||
|
// CHECK-NEXT: dealloc_stack %1 : $*S1
|
||||||
|
// CHECK-NEXT: return
|
||||||
|
sil [ossa] @dont_sroa_without_benefit : $@convention(thin) (S1) -> S1 {
|
||||||
|
bb0(%0 : $S1):
|
||||||
|
%1 = alloc_stack $S1
|
||||||
|
store %0 to [trivial] %1 : $*S1
|
||||||
|
%3 = load [trivial] %1 : $*S1
|
||||||
|
dealloc_stack %1 : $*S1
|
||||||
|
return %3 : $S1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
// Struct With Struct Fields //
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
|
sil [ossa] @use_s1 : $@convention(thin) (S1) -> ()
|
||||||
|
|
||||||
|
struct S2 {
|
||||||
|
var alpha : Builtin.FPIEEE32
|
||||||
|
var beta : S1
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: sil [ossa] @struct_with_struct_fields : $@convention(thin) (S2, Builtin.Int64) -> ()
|
||||||
|
// CHECK: bb0([[VAR_0:%[0-9]+]] : $S2, [[VAR_1:%[0-9]+]] : $Builtin.Int64):
|
||||||
|
|
||||||
|
// CHECK-NEXT: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.FPIEEE32
|
||||||
|
// CHECK-NEXT: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int1
|
||||||
|
// CHECK-NEXT: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_5:%[0-9]+]] = alloc_stack $Builtin.Int64
|
||||||
|
|
||||||
|
// CHECK-NEXT: ([[VAR_6:%[0-9]+]], [[VAR_8:%[0-9]+]]) = destructure_struct [[VAR_0]]
|
||||||
|
// CHECK-NEXT: store [[VAR_6]] to [trivial] [[VAR_2]] : $*Builtin.FPIEEE32
|
||||||
|
|
||||||
|
// CHECK-NEXT: ([[VAR_9:%[0-9]+]], [[VAR_11:%[0-9]+]], [[VAR_13:%[0-9]+]]) = destructure_struct [[VAR_8]]
|
||||||
|
// CHECK-NEXT: store [[VAR_9]] to [trivial] [[VAR_3]] : $*Builtin.Int1
|
||||||
|
// CHECK-NEXT: store [[VAR_11]] to [trivial] [[VAR_4]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: store [[VAR_13]] to [trivial] [[VAR_5]] : $*Builtin.Int64
|
||||||
|
|
||||||
|
// CHECK-NEXT: [[VAR_15:%[0-9]+]] = load [trivial] [[VAR_3]] : $*Builtin.Int1
|
||||||
|
// CHECK-NEXT: [[VAR_16:%[0-9]+]] = load [trivial] [[VAR_4]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_17:%[0-9]+]] = load [trivial] [[VAR_5]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: [[VAR_18:%[0-9]+]] = struct $S1 ([[VAR_15]] : $Builtin.Int1, [[VAR_16]] : $Builtin.Int32, [[VAR_17]] : $Builtin.Int64)
|
||||||
|
// CHECK-NEXT: function_ref
|
||||||
|
// CHECK-NEXT: [[VAR_19:%[0-9]+]] = function_ref @use_s1 : $@convention(thin) (S1) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_20:%[0-9]+]] = apply [[VAR_19]]([[VAR_18]]) : $@convention(thin) (S1) -> ()
|
||||||
|
// CHECK-NEXT: function_ref
|
||||||
|
// CHECK-NEXT: [[VAR_21:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_22:%[0-9]+]] = load [trivial] [[VAR_4]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_23:%[0-9]+]] = apply [[VAR_21]]([[VAR_22]]) : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_24:%[0-9]+]] = load [trivial] [[VAR_2]] : $*Builtin.FPIEEE32
|
||||||
|
// CHECK-NEXT: [[VAR_25:%[0-9]+]] = load [trivial] [[VAR_3]] : $*Builtin.Int1
|
||||||
|
// CHECK-NEXT: [[VAR_26:%[0-9]+]] = load [trivial] [[VAR_4]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_27:%[0-9]+]] = load [trivial] [[VAR_5]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: [[VAR_28:%[0-9]+]] = struct $S1 ([[VAR_25]] : $Builtin.Int1, [[VAR_26]] : $Builtin.Int32, [[VAR_27]] : $Builtin.Int64)
|
||||||
|
// CHECK-NEXT: [[VAR_29:%[0-9]+]] = struct $S2 ([[VAR_24]] : $Builtin.FPIEEE32, [[VAR_28]] : $S1)
|
||||||
|
// CHECK-NEXT: store [[VAR_1]] to [trivial] [[VAR_5]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_5]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_4]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_3]] : $*Builtin.Int1
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_2]] : $*Builtin.FPIEEE32
|
||||||
|
// CHECK-NEXT: [[VAR_35:%[0-9]+]] = tuple ()
|
||||||
|
// CHECK-NEXT: return [[VAR_35]] : $()
|
||||||
|
sil [ossa] @struct_with_struct_fields : $@convention(thin) (S2, Builtin.Int64) -> () {
|
||||||
|
bb0(%0 : $S2, %1 : $Builtin.Int64):
|
||||||
|
%2 = alloc_stack $S2
|
||||||
|
store %0 to [trivial] %2 : $*S2
|
||||||
|
%3 = struct_element_addr %2 : $*S2, #S2.beta
|
||||||
|
%4 = load [trivial] %3 : $*S1
|
||||||
|
%5 = function_ref @use_s1 : $@convention(thin) (S1) -> ()
|
||||||
|
apply %5(%4) : $@convention(thin) (S1) -> ()
|
||||||
|
%6 = struct_element_addr %3 : $*S1, #S1.y
|
||||||
|
%7 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
%8 = load [trivial] %6 : $*Builtin.Int32
|
||||||
|
apply %7(%8) : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
%9 = load [trivial] %2 : $*S2
|
||||||
|
%10 = struct_element_addr %3 : $*S1, #S1.z
|
||||||
|
store %1 to [trivial] %10 : $*Builtin.Int64
|
||||||
|
dealloc_stack %2 : $*S2
|
||||||
|
%11 = tuple()
|
||||||
|
return %11 : $()
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
// Struct with Tuple Fields //
|
||||||
|
//////////////////////////////
|
||||||
|
|
||||||
|
sil [ossa] @use_tup : $@convention(thin) ((Builtin.Int32, Builtin.Int64, Builtin.Int16)) -> ()
|
||||||
|
|
||||||
|
struct S3 {
|
||||||
|
var gamma : (Builtin.Int32, Builtin.Int64, Builtin.Int16)
|
||||||
|
var delta : Builtin.FPIEEE32
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: sil [ossa] @struct_with_tuple_fields : $@convention(thin) (S3, Builtin.Int64) -> ()
|
||||||
|
// CHECK: bb0([[VAR_0:%[0-9]+]] : $S3, [[VAR_1:%[0-9]+]] : $Builtin.Int64):
|
||||||
|
// CHECK-NEXT: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int64
|
||||||
|
// CHECK-NEXT: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int16
|
||||||
|
// CHECK-NEXT: [[VAR_5:%[0-9]+]] = alloc_stack $Builtin.FPIEEE32
|
||||||
|
// CHECK-NEXT: ([[VAR_6:%[0-9]+]], [[VAR_13:%[0-9]+]]) = destructure_struct [[VAR_0]]
|
||||||
|
// CHECK-NEXT: ([[VAR_7:%[0-9]+]], [[VAR_9:%[0-9]+]], [[VAR_11:%[0-9]+]]) = destructure_tuple [[VAR_6]]
|
||||||
|
// CHECK-NEXT: store [[VAR_7]] to [trivial] [[VAR_2]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: store [[VAR_9]] to [trivial] [[VAR_3]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: store [[VAR_11]] to [trivial] [[VAR_4]] : $*Builtin.Int16
|
||||||
|
// CHECK-NEXT: store [[VAR_13]] to [trivial] [[VAR_5]] : $*Builtin.FPIEEE32
|
||||||
|
// CHECK-NEXT: function_ref
|
||||||
|
// CHECK-NEXT: [[VAR_15:%[0-9]+]] = function_ref @use_tup : $@convention(thin) ((Builtin.Int32, Builtin.Int64, Builtin.Int16)) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_16:%[0-9]+]] = load [trivial] [[VAR_2]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_17:%[0-9]+]] = load [trivial] [[VAR_3]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: [[VAR_18:%[0-9]+]] = load [trivial] [[VAR_4]] : $*Builtin.Int16
|
||||||
|
// CHECK-NEXT: [[VAR_19:%[0-9]+]] = tuple ([[VAR_16]] : $Builtin.Int32, [[VAR_17]] : $Builtin.Int64, [[VAR_18]] : $Builtin.Int16)
|
||||||
|
// CHECK-NEXT: [[VAR_20:%[0-9]+]] = apply [[VAR_15]]([[VAR_19]]) : $@convention(thin) ((Builtin.Int32, Builtin.Int64, Builtin.Int16)) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_21:%[0-9]+]] = load [trivial] [[VAR_2]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: function_ref
|
||||||
|
// CHECK-NEXT: [[VAR_22:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_23:%[0-9]+]] = apply [[VAR_22]]([[VAR_21]]) : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_24:%[0-9]+]] = load [trivial] [[VAR_2]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_25:%[0-9]+]] = load [trivial] [[VAR_3]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: [[VAR_26:%[0-9]+]] = load [trivial] [[VAR_4]] : $*Builtin.Int16
|
||||||
|
// CHECK-NEXT: [[VAR_27:%[0-9]+]] = tuple ([[VAR_24]] : $Builtin.Int32, [[VAR_25]] : $Builtin.Int64, [[VAR_26]] : $Builtin.Int16)
|
||||||
|
// CHECK-NEXT: [[VAR_28:%[0-9]+]] = load [trivial] [[VAR_5]] : $*Builtin.FPIEEE32
|
||||||
|
// CHECK-NEXT: [[VAR_29:%[0-9]+]] = struct $S3 ([[VAR_27]] : $(Builtin.Int32, Builtin.Int64, Builtin.Int16), [[VAR_28]] : $Builtin.FPIEEE32)
|
||||||
|
// CHECK-NEXT: store [[VAR_1]] to [trivial] [[VAR_3]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_5]] : $*Builtin.FPIEEE32
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_4]] : $*Builtin.Int16
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_3]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_2]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_35:%[0-9]+]] = tuple ()
|
||||||
|
// CHECK-NEXT: return [[VAR_35]] : $()
|
||||||
|
sil [ossa] @struct_with_tuple_fields : $@convention(thin) (S3, Builtin.Int64) -> () {
|
||||||
|
bb0(%0 : $S3, %1 : $Builtin.Int64):
|
||||||
|
%2 = alloc_stack $S3
|
||||||
|
store %0 to [trivial] %2 : $*S3
|
||||||
|
%3 = function_ref @use_tup : $@convention(thin) ((Builtin.Int32, Builtin.Int64, Builtin.Int16)) -> ()
|
||||||
|
%4 = struct_element_addr %2 : $*S3, #S3.gamma
|
||||||
|
%5 = load [trivial] %4 : $*(Builtin.Int32, Builtin.Int64, Builtin.Int16)
|
||||||
|
apply %3(%5) : $@convention(thin) ((Builtin.Int32, Builtin.Int64, Builtin.Int16)) -> ()
|
||||||
|
%6 = tuple_element_addr %4 : $*(Builtin.Int32, Builtin.Int64, Builtin.Int16), 0
|
||||||
|
%7 = load [trivial] %6 : $*Builtin.Int32
|
||||||
|
%8 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
apply %8(%7) : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
%9 = load [trivial] %2 : $*S3
|
||||||
|
%10 = tuple_element_addr %4 : $*(Builtin.Int32, Builtin.Int64, Builtin.Int16), 1
|
||||||
|
store %1 to [trivial] %10 : $*Builtin.Int64
|
||||||
|
dealloc_stack %2 : $*S3
|
||||||
|
%11 = tuple ()
|
||||||
|
return %11 : $()
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
// Tuple with Scalar Fields //
|
||||||
|
//////////////////////////////
|
||||||
|
|
||||||
|
// CHECK-LABEL: sil [ossa] @tuple_with_scalar_fields : $@convention(thin) ((Builtin.Int1, Builtin.Int32, Builtin.Int64)) -> ()
|
||||||
|
// CHECK: bb0([[VAR_0:%[0-9]+]] : $(Builtin.Int1, Builtin.Int32, Builtin.Int64)):
|
||||||
|
// CHECK-NEXT: [[VAR_1:%[0-9]+]] = alloc_stack $Builtin.Int1
|
||||||
|
// CHECK-NEXT: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int64
|
||||||
|
// CHECK-NEXT: ([[VAR_4:%[0-9]+]], [[VAR_6:%[0-9]+]], [[VAR_8:%[0-9]+]]) = destructure_tuple [[VAR_0]]
|
||||||
|
// CHECK-NEXT: store [[VAR_4]] to [trivial] [[VAR_1]] : $*Builtin.Int1
|
||||||
|
// CHECK-NEXT: store [[VAR_6]] to [trivial] [[VAR_2]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: store [[VAR_8]] to [trivial] [[VAR_3]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: function_ref
|
||||||
|
// CHECK-NEXT: [[VAR_10:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_11:%[0-9]+]] = load [trivial] [[VAR_2]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_12:%[0-9]+]] = apply [[VAR_10]]([[VAR_11]]) : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_13:%[0-9]+]] = load [trivial] [[VAR_1]] : $*Builtin.Int1
|
||||||
|
// CHECK-NEXT: [[VAR_14:%[0-9]+]] = load [trivial] [[VAR_2]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_15:%[0-9]+]] = load [trivial] [[VAR_3]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: [[VAR_16:%[0-9]+]] = tuple ([[VAR_13]] : $Builtin.Int1, [[VAR_14]] : $Builtin.Int32, [[VAR_15]] : $Builtin.Int64)
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_3]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_2]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_1]] : $*Builtin.Int1
|
||||||
|
// CHECK-NEXT: [[VAR_20:%[0-9]+]] = tuple ()
|
||||||
|
// CHECK-NEXT: return [[VAR_20]] : $()
|
||||||
|
sil [ossa] @tuple_with_scalar_fields : $@convention(thin) ((Builtin.Int1, Builtin.Int32, Builtin.Int64)) -> () {
|
||||||
|
bb0(%0 : $(Builtin.Int1, Builtin.Int32, Builtin.Int64)):
|
||||||
|
%1 = alloc_stack $(Builtin.Int1, Builtin.Int32, Builtin.Int64)
|
||||||
|
store %0 to [trivial] %1 : $*(Builtin.Int1, Builtin.Int32, Builtin.Int64)
|
||||||
|
%2 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
%3 = tuple_element_addr %1 : $*(Builtin.Int1, Builtin.Int32, Builtin.Int64), 1
|
||||||
|
%4 = load [trivial] %3 : $*Builtin.Int32
|
||||||
|
apply %2(%4) : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
%5 = load [trivial] %1 : $*(Builtin.Int1, Builtin.Int32, Builtin.Int64)
|
||||||
|
dealloc_stack %1 : $*(Builtin.Int1, Builtin.Int32, Builtin.Int64)
|
||||||
|
%6 = tuple()
|
||||||
|
return %6 : $()
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
// Tuple With Struct Fields //
|
||||||
|
//////////////////////////////
|
||||||
|
|
||||||
|
struct S4 {
|
||||||
|
var aleph : Builtin.Int64
|
||||||
|
var bet : Builtin.Int32
|
||||||
|
}
|
||||||
|
|
||||||
|
sil [ossa] @use_str4 : $@convention(thin) (S4) -> ()
|
||||||
|
|
||||||
|
// CHECK-LABEL: sil [ossa] @tuple_with_struct_fields : $@convention(thin) ((S4, Builtin.Int16), Builtin.Int16) -> ()
|
||||||
|
// CHECK: bb0([[VAR_0:%[0-9]+]] : $(S4, Builtin.Int16), [[VAR_1:%[0-9]+]] : $Builtin.Int16):
|
||||||
|
// CHECK-NEXT: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int64
|
||||||
|
// CHECK-NEXT: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int16
|
||||||
|
// CHECK-NEXT: ([[VAR_5:%[0-9]+]], [[VAR_10:%[0-9]+]]) = destructure_tuple [[VAR_0]]
|
||||||
|
// CHECK-NEXT: ([[VAR_6:%[0-9]+]], [[VAR_8:%[0-9]+]]) = destructure_struct [[VAR_5]]
|
||||||
|
// CHECK-NEXT: store [[VAR_6]] to [trivial] [[VAR_2]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: store [[VAR_8]] to [trivial] [[VAR_3]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: store [[VAR_10]] to [trivial] [[VAR_4]] : $*Builtin.Int16
|
||||||
|
// CHECK-NEXT: function_ref
|
||||||
|
// CHECK-NEXT: [[VAR_12:%[0-9]+]] = function_ref @use_str4 : $@convention(thin) (S4) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_13:%[0-9]+]] = load [trivial] [[VAR_2]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: [[VAR_14:%[0-9]+]] = load [trivial] [[VAR_3]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_15:%[0-9]+]] = struct $S4 ([[VAR_13]] : $Builtin.Int64, [[VAR_14]] : $Builtin.Int32)
|
||||||
|
// CHECK-NEXT: [[VAR_16:%[0-9]+]] = apply [[VAR_12]]([[VAR_15]]) : $@convention(thin) (S4) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_17:%[0-9]+]] = load [trivial] [[VAR_3]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: function_ref
|
||||||
|
// CHECK-NEXT: [[VAR_18:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_19:%[0-9]+]] = apply [[VAR_18]]([[VAR_17]]) : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_20:%[0-9]+]] = load [trivial] [[VAR_2]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: [[VAR_21:%[0-9]+]] = load [trivial] [[VAR_3]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_22:%[0-9]+]] = struct $S4 ([[VAR_20]] : $Builtin.Int64, [[VAR_21]] : $Builtin.Int32)
|
||||||
|
// CHECK-NEXT: [[VAR_23:%[0-9]+]] = load [trivial] [[VAR_4]] : $*Builtin.Int16
|
||||||
|
// CHECK-NEXT: [[VAR_24:%[0-9]+]] = tuple ([[VAR_22]] : $S4, [[VAR_23]] : $Builtin.Int16)
|
||||||
|
// CHECK-NEXT: store [[VAR_1]] to [trivial] [[VAR_4]] : $*Builtin.Int16
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_4]] : $*Builtin.Int16
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_3]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_2]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: [[VAR_29:%[0-9]+]] = tuple ()
|
||||||
|
// CHECK-NEXT: return [[VAR_29]] : $()
|
||||||
|
sil [ossa] @tuple_with_struct_fields : $@convention(thin) ((S4, Builtin.Int16), Builtin.Int16) -> () {
|
||||||
|
bb0(%0 : $(S4, Builtin.Int16), %1 : $Builtin.Int16):
|
||||||
|
%2 = alloc_stack $(S4, Builtin.Int16)
|
||||||
|
store %0 to [trivial] %2 : $*(S4, Builtin.Int16)
|
||||||
|
%3 = function_ref @use_str4 : $@convention(thin) (S4) -> ()
|
||||||
|
%4 = tuple_element_addr %2 : $*(S4, Builtin.Int16), 0
|
||||||
|
%5 = load [trivial] %4 : $*S4
|
||||||
|
apply %3(%5) : $@convention(thin) (S4) -> ()
|
||||||
|
%6 = struct_element_addr %4 : $*S4, #S4.bet
|
||||||
|
%7 = load [trivial] %6 : $*Builtin.Int32
|
||||||
|
%8 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
apply %8(%7) : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
%9 = load [trivial] %2 : $*(S4, Builtin.Int16)
|
||||||
|
%10 = tuple_element_addr %2 : $*(S4, Builtin.Int16), 1
|
||||||
|
store %1 to [trivial] %10 : $*Builtin.Int16
|
||||||
|
dealloc_stack %2 : $*(S4, Builtin.Int16)
|
||||||
|
%11 = tuple()
|
||||||
|
return %11 : $()
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
// Tuple with Tuple Field Test //
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
sil [ossa] @use_tup2 : $@convention(thin) ((Builtin.Int64, Builtin.Int32)) -> ()
|
||||||
|
sil [ossa] @use_int16 : $@convention(thin) (Builtin.Int16) -> ()
|
||||||
|
|
||||||
|
// CHECK-LABEL: sil [ossa] @tuple_with_tuple_fields : $@convention(thin) (((Builtin.Int64, Builtin.Int32), Builtin.Int16), Builtin.Int16) -> ()
|
||||||
|
// CHECK: bb0([[VAR_0:%[0-9]+]] : $((Builtin.Int64, Builtin.Int32), Builtin.Int16), [[VAR_1:%[0-9]+]] : $Builtin.Int16):
|
||||||
|
// CHECK-NEXT: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int64
|
||||||
|
// CHECK-NEXT: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int16
|
||||||
|
// CHECK-NEXT: ([[VAR_5:%[0-9]+]], [[VAR_10:%[0-9]+]]) = destructure_tuple [[VAR_0]]
|
||||||
|
// CHECK-NEXT: ([[VAR_6:%[0-9]+]], [[VAR_8:%[0-9]+]]) = destructure_tuple [[VAR_5]]
|
||||||
|
// CHECK-NEXT: store [[VAR_6]] to [trivial] [[VAR_2]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: store [[VAR_8]] to [trivial] [[VAR_3]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: store [[VAR_10]] to [trivial] [[VAR_4]] : $*Builtin.Int16
|
||||||
|
// CHECK-NEXT: [[VAR_12:%[0-9]+]] = load [trivial] [[VAR_2]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: [[VAR_13:%[0-9]+]] = load [trivial] [[VAR_3]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_14:%[0-9]+]] = tuple ([[VAR_12]] : $Builtin.Int64, [[VAR_13]] : $Builtin.Int32)
|
||||||
|
// CHECK-NEXT: function_ref
|
||||||
|
// CHECK-NEXT: [[VAR_15:%[0-9]+]] = function_ref @use_tup2 : $@convention(thin) ((Builtin.Int64, Builtin.Int32)) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_16:%[0-9]+]] = apply [[VAR_15]]([[VAR_14]]) : $@convention(thin) ((Builtin.Int64, Builtin.Int32)) -> ()
|
||||||
|
// CHECK-NEXT: function_ref
|
||||||
|
// CHECK-NEXT: [[VAR_17:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_18:%[0-9]+]] = load [trivial] [[VAR_3]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_19:%[0-9]+]] = apply [[VAR_17]]([[VAR_18]]) : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_20:%[0-9]+]] = load [trivial] [[VAR_2]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: [[VAR_21:%[0-9]+]] = load [trivial] [[VAR_3]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: [[VAR_22:%[0-9]+]] = tuple ([[VAR_20]] : $Builtin.Int64, [[VAR_21]] : $Builtin.Int32)
|
||||||
|
// CHECK-NEXT: [[VAR_23:%[0-9]+]] = load [trivial] [[VAR_4]] : $*Builtin.Int16
|
||||||
|
// CHECK-NEXT: [[VAR_24:%[0-9]+]] = tuple ([[VAR_22]] : $(Builtin.Int64, Builtin.Int32), [[VAR_23]] : $Builtin.Int16)
|
||||||
|
// CHECK-NEXT: store [[VAR_1]] to [trivial] [[VAR_4]] : $*Builtin.Int16
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_4]] : $*Builtin.Int16
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_3]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_2]] : $*Builtin.Int64
|
||||||
|
// CHECK-NEXT: [[VAR_29:%[0-9]+]] = tuple ()
|
||||||
|
// CHECK-NEXT: return [[VAR_29]] : $()
|
||||||
|
sil [ossa] @tuple_with_tuple_fields : $@convention(thin) (((Builtin.Int64, Builtin.Int32), Builtin.Int16), Builtin.Int16) -> () {
|
||||||
|
bb0(%0 : $((Builtin.Int64, Builtin.Int32), Builtin.Int16), %1 : $Builtin.Int16):
|
||||||
|
%2 = alloc_stack $((Builtin.Int64, Builtin.Int32), Builtin.Int16)
|
||||||
|
store %0 to [trivial] %2 : $*((Builtin.Int64, Builtin.Int32), Builtin.Int16)
|
||||||
|
%3 = tuple_element_addr %2 : $*((Builtin.Int64, Builtin.Int32), Builtin.Int16), 0
|
||||||
|
%4 = load [trivial] %3 : $*(Builtin.Int64, Builtin.Int32)
|
||||||
|
%5 = function_ref @use_tup2 : $@convention(thin) ((Builtin.Int64, Builtin.Int32)) -> ()
|
||||||
|
apply %5(%4) : $@convention(thin) ((Builtin.Int64, Builtin.Int32)) -> ()
|
||||||
|
%6 = tuple_element_addr %3 : $*(Builtin.Int64, Builtin.Int32), 1
|
||||||
|
%7 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
%8 = load [trivial] %6 : $*Builtin.Int32
|
||||||
|
apply %7(%8) : $@convention(thin) (Builtin.Int32) -> ()
|
||||||
|
%9 = load [trivial] %2 : $*((Builtin.Int64, Builtin.Int32), Builtin.Int16)
|
||||||
|
%10 = tuple_element_addr %2 : $*((Builtin.Int64, Builtin.Int32), Builtin.Int16), 1
|
||||||
|
store %1 to [trivial] %10 : $*Builtin.Int16
|
||||||
|
dealloc_stack %2 : $*((Builtin.Int64, Builtin.Int32), Builtin.Int16)
|
||||||
|
%11 = tuple()
|
||||||
|
return %11 : $()
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////
|
||||||
|
// Capture Struct Test //
|
||||||
|
/////////////////////////
|
||||||
|
|
||||||
|
struct CapturedS {
|
||||||
|
var x : Builtin.Int32
|
||||||
|
}
|
||||||
|
|
||||||
|
sil [ossa] @use_capturedstruct : $@convention(thin) (@inout CapturedS) -> ()
|
||||||
|
|
||||||
|
// CHECK-LABEL: sil [ossa] @captured_struct : $@convention(thin) (CapturedS) -> ()
|
||||||
|
// CHECK: bb0([[VAR_0:%[0-9]+]] : $CapturedS):
|
||||||
|
// CHECK-NEXT: [[VAR_1:%[0-9]+]] = alloc_stack $CapturedS
|
||||||
|
// CHECK-NEXT: store [[VAR_0]] to [trivial] [[VAR_1]] : $*CapturedS
|
||||||
|
// CHECK-NEXT: [[VAR_3:%[0-9]+]] = struct_element_addr [[VAR_1]] : $*CapturedS, #CapturedS.x
|
||||||
|
// CHECK-NEXT: [[VAR_4:%[0-9]+]] = load [trivial] [[VAR_3]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: function_ref
|
||||||
|
// CHECK-NEXT: [[VAR_5:%[0-9]+]] = function_ref @use_capturedstruct : $@convention(thin) (@inout CapturedS) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_6:%[0-9]+]] = apply [[VAR_5]]([[VAR_1]]) : $@convention(thin) (@inout CapturedS) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_7:%[0-9]+]] = load [trivial] [[VAR_3]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_1]] : $*CapturedS
|
||||||
|
// CHECK-NEXT: [[VAR_9:%[0-9]+]] = tuple ()
|
||||||
|
// CHECK-NEXT: return [[VAR_9]] : $()
|
||||||
|
sil [ossa] @captured_struct : $@convention(thin) (CapturedS) -> () {
|
||||||
|
bb0(%0 : $CapturedS):
|
||||||
|
%1 = alloc_stack $CapturedS
|
||||||
|
store %0 to [trivial] %1 : $*CapturedS
|
||||||
|
%3 = struct_element_addr %1 : $*CapturedS, #CapturedS.x
|
||||||
|
%4 = load [trivial] %3 : $*Builtin.Int32
|
||||||
|
%5 = function_ref @use_capturedstruct : $@convention(thin) (@inout CapturedS) -> ()
|
||||||
|
%6 = apply %5(%1) : $@convention(thin) (@inout CapturedS) -> ()
|
||||||
|
%7 = load [trivial] %3 : $*Builtin.Int32
|
||||||
|
dealloc_stack %1 : $*CapturedS
|
||||||
|
%9 = tuple ()
|
||||||
|
return %9 : $()
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////
|
||||||
|
// Captured Tuple Test //
|
||||||
|
/////////////////////////
|
||||||
|
|
||||||
|
sil [ossa] @use_capturedtuple : $@convention(thin) (@inout (Builtin.Int32, Builtin.Int64)) -> ()
|
||||||
|
|
||||||
|
// CHECK-LABEL: sil [ossa] @captured_tuple : $@convention(thin) ((Builtin.Int32, Builtin.Int64)) -> ()
|
||||||
|
// CHECK: bb0([[VAR_0:%[0-9]+]] : $(Builtin.Int32, Builtin.Int64)):
|
||||||
|
// CHECK-NEXT: [[VAR_1:%[0-9]+]] = alloc_stack $(Builtin.Int32, Builtin.Int64)
|
||||||
|
// CHECK-NEXT: store [[VAR_0]] to [trivial] [[VAR_1]] : $*(Builtin.Int32, Builtin.Int64)
|
||||||
|
// CHECK-NEXT: [[VAR_3:%[0-9]+]] = tuple_element_addr [[VAR_1]] : $*(Builtin.Int32, Builtin.Int64), 0
|
||||||
|
// CHECK-NEXT: [[VAR_4:%[0-9]+]] = load [trivial] [[VAR_3]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: function_ref
|
||||||
|
// CHECK-NEXT: [[VAR_5:%[0-9]+]] = function_ref @use_capturedtuple : $@convention(thin) (@inout (Builtin.Int32, Builtin.Int64)) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_6:%[0-9]+]] = apply [[VAR_5]]([[VAR_1]]) : $@convention(thin) (@inout (Builtin.Int32, Builtin.Int64)) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_7:%[0-9]+]] = load [trivial] [[VAR_3]] : $*Builtin.Int32
|
||||||
|
// CHECK-NEXT: dealloc_stack [[VAR_1]] : $*(Builtin.Int32, Builtin.Int64)
|
||||||
|
// CHECK-NEXT: [[VAR_9:%[0-9]+]] = tuple ()
|
||||||
|
// CHECK-NEXT: return [[VAR_9]] : $()
|
||||||
|
sil [ossa] @captured_tuple : $@convention(thin) ((Builtin.Int32, Builtin.Int64)) -> () {
|
||||||
|
bb0(%0 : $(Builtin.Int32, Builtin.Int64)):
|
||||||
|
%1 = alloc_stack $(Builtin.Int32, Builtin.Int64)
|
||||||
|
store %0 to [trivial] %1 : $*(Builtin.Int32, Builtin.Int64)
|
||||||
|
%3 = tuple_element_addr %1 : $*(Builtin.Int32, Builtin.Int64), 0
|
||||||
|
%4 = load [trivial] %3 : $*Builtin.Int32
|
||||||
|
%5 = function_ref @use_capturedtuple : $@convention(thin) (@inout (Builtin.Int32, Builtin.Int64)) -> ()
|
||||||
|
%6 = apply %5(%1) : $@convention(thin) (@inout (Builtin.Int32, Builtin.Int64)) -> ()
|
||||||
|
%7 = load [trivial] %3 : $*Builtin.Int32
|
||||||
|
dealloc_stack %1 : $*(Builtin.Int32, Builtin.Int64)
|
||||||
|
%9 = tuple ()
|
||||||
|
return %9 : $()
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
// Non-trivial Tests //
|
||||||
|
///////////////////////
|
||||||
|
|
||||||
|
class Obj { }
|
||||||
|
|
||||||
|
struct NotTrivial {
|
||||||
|
var x : Obj
|
||||||
|
var y : Obj
|
||||||
|
}
|
||||||
|
|
||||||
|
sil [ossa] @use_obj : $@convention(thin) (@owned Obj) -> ()
|
||||||
|
|
||||||
|
// CHECK-LABEL: sil [ossa] @struct_with_obj_fields : $@convention(thin) (@owned NotTrivial) -> ()
|
||||||
|
// CHECK: bb0([[VAR_0:%[0-9]+]] : @owned $NotTrivial):
|
||||||
|
|
||||||
|
// CHECK-NEXT: [[VAR_1:%[0-9]+]] = alloc_stack $Obj
|
||||||
|
// CHECK-NEXT: [[VAR_2:%[0-9]+]] = alloc_stack $Obj
|
||||||
|
// CHECK-NEXT: ([[VAR_4:%[0-9]+]], [[VAR_6:%[0-9]+]]) = destructure_struct [[VAR_0]]
|
||||||
|
// CHECK-NEXT: store [[VAR_4]] to [init] [[VAR_1]] : $*Obj
|
||||||
|
// CHECK-NEXT: store [[VAR_6]] to [init] [[VAR_2]] : $*Obj
|
||||||
|
|
||||||
|
// CHECK-NEXT: function_ref
|
||||||
|
// CHECK-NEXT: [[VAR_10:%[0-9]+]] = function_ref @use_obj : $@convention(thin) (@owned Obj) -> ()
|
||||||
|
// Make sure we use [copy] here ▼▼▼▼▼▼
|
||||||
|
// CHECK-NEXT: [[VAR_11:%[0-9]+]] = load [copy] [[VAR_2]] : $*Obj
|
||||||
|
// CHECK-NEXT: [[VAR_12:%[0-9]+]] = apply [[VAR_10]]([[VAR_11]]) : $@convention(thin) (@owned Obj) -> ()
|
||||||
|
// CHECK-NEXT: [[VAR_13:%[0-9]+]] = load [take] [[VAR_1]] : $*Obj
|
||||||
|
// CHECK-NEXT: [[VAR_14:%[0-9]+]] = load [take] [[VAR_2]] : $*Obj
|
||||||
|
// CHECK-NEXT: [[VAR_16:%[0-9]+]] = struct $NotTrivial ([[VAR_13]] : $Obj, [[VAR_14]] : $Obj)
|
||||||
|
|
||||||
|
// CHECK: dealloc_stack [[VAR_2]] : $*Obj
|
||||||
|
// CHECK: dealloc_stack [[VAR_1]] : $*Obj
|
||||||
|
|
||||||
|
// CHECK: [[VAR_20:%[0-9]+]] = tuple ()
|
||||||
|
// CHECK: return [[VAR_20]] : $()
|
||||||
|
sil [ossa] @struct_with_obj_fields : $@convention(thin) (@owned NotTrivial) -> () {
|
||||||
|
bb0(%0 : @owned $NotTrivial):
|
||||||
|
%1 = alloc_stack $NotTrivial
|
||||||
|
debug_value %1 : $*NotTrivial // should not prevent the optimization
|
||||||
|
store %0 to [init] %1 : $*NotTrivial
|
||||||
|
%2 = function_ref @use_obj : $@convention(thin) (@owned Obj) -> ()
|
||||||
|
%3 = struct_element_addr %1 : $*NotTrivial, #NotTrivial.y
|
||||||
|
// Make sure that SROA respects the [copy] qual.
|
||||||
|
%4 = load [copy] %3 : $*Obj
|
||||||
|
apply %2(%4) : $@convention(thin) (@owned Obj) -> ()
|
||||||
|
%5 = load [take] %1 : $*NotTrivial
|
||||||
|
destroy_value %5 : $NotTrivial
|
||||||
|
dealloc_stack %1 : $*NotTrivial
|
||||||
|
%6 = tuple ()
|
||||||
|
return %6 : $()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user