Skip to content

Commit 3063e9d

Browse files
committed
[SIL] InitAccessors: Reference "self" in assign_or_init instruction
First step on the path to remove dependence on "setter".
1 parent 50d2f4d commit 3063e9d

File tree

11 files changed

+79
-77
lines changed

11 files changed

+79
-77
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -956,12 +956,14 @@ class SILBuilder {
956956
getSILDebugLocation(Loc), Src, Dest, Initializer, Setter, mode));
957957
}
958958

959-
AssignOrInitInst *createAssignOrInit(SILLocation Loc, SILValue Src,
959+
AssignOrInitInst *createAssignOrInit(SILLocation Loc,
960+
SILValue Self,
961+
SILValue Src,
960962
SILValue Initializer,
961963
SILValue Setter,
962964
AssignOrInitInst::Mode Mode) {
963965
return insert(new (getModule()) AssignOrInitInst(
964-
getSILDebugLocation(Loc), Src, Initializer, Setter, Mode));
966+
getSILDebugLocation(Loc), Self, Src, Initializer, Setter, Mode));
965967
}
966968

967969
StoreBorrowInst *createStoreBorrow(SILLocation Loc, SILValue Src,

include/swift/SIL/SILCloner.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,6 +1358,7 @@ void SILCloner<ImplClass>::visitAssignOrInitInst(AssignOrInitInst *Inst) {
13581358
recordClonedInstruction(
13591359
Inst, getBuilder().createAssignOrInit(
13601360
getOpLocation(Inst->getLoc()),
1361+
getOpValue(Inst->getSelf()),
13611362
getOpValue(Inst->getSrc()),
13621363
getOpValue(Inst->getInitializer()),
13631364
getOpValue(Inst->getSetter()), Inst->getMode()));

include/swift/SIL/SILInstruction.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4842,7 +4842,7 @@ class AssignOrInitInst
48424842
friend SILBuilder;
48434843
USE_SHARED_UINT8;
48444844

4845-
FixedOperandList<3> Operands;
4845+
FixedOperandList<4> Operands;
48464846

48474847
/// Marks all of the properties in `initializes(...)` list that
48484848
/// have been initialized before this intruction to help Raw SIL
@@ -4862,14 +4862,14 @@ class AssignOrInitInst
48624862
};
48634863

48644864
private:
4865-
AssignOrInitInst(SILDebugLocation DebugLoc,
4866-
SILValue Src, SILValue Initializer,
4867-
SILValue Setter, Mode mode);
4865+
AssignOrInitInst(SILDebugLocation DebugLoc, SILValue Self, SILValue Src,
4866+
SILValue Initializer, SILValue Setter, Mode mode);
48684867

48694868
public:
4870-
SILValue getSrc() const { return Operands[0].get(); }
4871-
SILValue getInitializer() const { return Operands[1].get(); }
4872-
SILValue getSetter() { return Operands[2].get(); }
4869+
SILValue getSelf() const { return Operands[0].get(); }
4870+
SILValue getSrc() const { return Operands[1].get(); }
4871+
SILValue getInitializer() const { return Operands[2].get(); }
4872+
SILValue getSetter() { return Operands[3].get(); }
48734873

48744874
Mode getMode() const {
48754875
return Mode(sharedUInt8().AssignOrInitInst.mode);

lib/SIL/IR/SILInstructions.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,11 +1256,12 @@ AssignByWrapperInst::AssignByWrapperInst(SILDebugLocation Loc,
12561256
sharedUInt8().AssignByWrapperInst.mode = uint8_t(mode);
12571257
}
12581258

1259-
AssignOrInitInst::AssignOrInitInst(SILDebugLocation Loc, SILValue Src,
1260-
SILValue Initializer, SILValue Setter,
1261-
AssignOrInitInst::Mode Mode)
1262-
: InstructionBase<SILInstructionKind::AssignOrInitInst, NonValueInstruction>(Loc),
1263-
Operands(this, Src, Initializer, Setter) {
1259+
AssignOrInitInst::AssignOrInitInst(SILDebugLocation Loc, SILValue Self,
1260+
SILValue Src, SILValue Initializer,
1261+
SILValue Setter, AssignOrInitInst::Mode Mode)
1262+
: InstructionBase<SILInstructionKind::AssignOrInitInst,
1263+
NonValueInstruction>(Loc),
1264+
Operands(this, Self, Src, Initializer, Setter) {
12641265
assert(Initializer->getType().is<SILFunctionType>());
12651266
sharedUInt8().AssignOrInitInst.mode = uint8_t(Mode);
12661267
Assignments.resize(getNumInitializedProperties());

lib/SIL/IR/SILPrinter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1802,7 +1802,8 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
18021802
}
18031803
}
18041804

1805-
*this << getIDAndType(AI->getSrc());
1805+
*this << "self " << getIDAndType(AI->getSelf());
1806+
*this << ", value " << getIDAndType(AI->getSrc());
18061807
*this << ", init " << getIDAndType(AI->getInitializer())
18071808
<< ", set " << getIDAndType(AI->getSetter());
18081809
}

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4742,21 +4742,23 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
47424742
}
47434743

47444744
case SILInstructionKind::AssignOrInitInst: {
4745-
SILValue Src, InitFn, SetFn;
4745+
SILValue Self, Src, InitFn, SetFn;
47464746
AssignOrInitInst::Mode Mode;
47474747
llvm::SmallVector<unsigned, 2> assignments;
47484748

47494749
if (parseAssignOrInitMode(Mode, *this) ||
47504750
parseAssignOrInitAssignments(assignments, *this) ||
4751-
parseTypedValueRef(Src, B) ||
4751+
parseVerbatim("self") || parseTypedValueRef(Self, B) ||
4752+
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
4753+
parseVerbatim("value") || parseTypedValueRef(Src, B) ||
47524754
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
47534755
parseVerbatim("init") || parseTypedValueRef(InitFn, B) ||
47544756
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
47554757
parseVerbatim("set") || parseTypedValueRef(SetFn, B) ||
47564758
parseSILDebugLocation(InstLoc, B))
47574759
return true;
47584760

4759-
auto *AI = B.createAssignOrInit(InstLoc, Src, InitFn, SetFn, Mode);
4761+
auto *AI = B.createAssignOrInit(InstLoc, Self, Src, InitFn, SetFn, Mode);
47604762

47614763
for (unsigned index : assignments)
47624764
AI->markAsInitialized(index);

lib/SILGen/SILGenLValue.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,8 +1731,8 @@ namespace {
17311731

17321732
// Create the assign_or_init with the initializer and setter.
17331733
auto value = emitValue(field, FieldType, setterTy, setterConv);
1734-
SGF.B.createAssignOrInit(loc, value.forward(SGF), initFRef,
1735-
setterFn.getValue(),
1734+
SGF.B.createAssignOrInit(loc, base.getValue(), value.forward(SGF),
1735+
initFRef, setterFn.getValue(),
17361736
AssignOrInitInst::Unknown);
17371737
return;
17381738
}

lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp

Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -655,8 +655,7 @@ class ElementUseCollector {
655655
private:
656656
void collectUses(SILValue Pointer, unsigned BaseEltNo);
657657
bool addClosureElementUses(PartialApplyInst *pai, Operand *argUse);
658-
void collectAssignOrInitUses(PartialApplyInst *pai, Operand *argUse,
659-
unsigned BaseEltNo = 0);
658+
void collectAssignOrInitUses(AssignOrInitInst *pai, unsigned BaseEltNo = 0);
660659

661660
void collectClassSelfUses(SILValue ClassPointer);
662661
void collectClassSelfUses(SILValue ClassPointer, SILType MemorySILType,
@@ -1088,14 +1087,17 @@ void ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) {
10881087
if (User->isDebugInstruction())
10891088
continue;
10901089

1090+
if (auto *AI = dyn_cast<AssignOrInitInst>(User)) {
1091+
collectAssignOrInitUses(AI, BaseEltNo);
1092+
continue;
1093+
}
1094+
10911095
if (auto *PAI = dyn_cast<PartialApplyInst>(User)) {
10921096
if (onlyUsedByAssignByWrapper(PAI))
10931097
continue;
10941098

1095-
if (onlyUsedByAssignOrInit(PAI)) {
1096-
collectAssignOrInitUses(PAI, Op, BaseEltNo);
1099+
if (onlyUsedByAssignOrInit(PAI))
10971100
continue;
1098-
}
10991101

11001102
if (BaseEltNo == 0 && addClosureElementUses(PAI, Op))
11011103
continue;
@@ -1188,47 +1190,38 @@ bool ElementUseCollector::addClosureElementUses(PartialApplyInst *pai,
11881190
}
11891191

11901192
void
1191-
ElementUseCollector::collectAssignOrInitUses(PartialApplyInst *pai,
1192-
Operand *argUse,
1193+
ElementUseCollector::collectAssignOrInitUses(AssignOrInitInst *Inst,
11931194
unsigned BaseEltNo) {
1194-
for (Operand *Op : pai->getUses()) {
1195-
SILInstruction *User = Op->getUser();
1196-
if (!isa<AssignOrInitInst>(User) || Op->getOperandNumber() != 2) {
1197-
continue;
1198-
}
1199-
1200-
/// AssignOrInit doesn't operate on `self` so we need to make sure
1201-
/// that the flag is dropped before calling \c addElementUses.
1202-
llvm::SaveAndRestore<bool> X(IsSelfOfNonDelegatingInitializer, false);
1203-
1204-
auto *inst = cast<AssignOrInitInst>(User);
1205-
auto *typeDC = inst->getReferencedInitAccessor()
1206-
->getDeclContext()
1207-
->getSelfNominalTypeDecl();
1208-
1209-
auto selfTy = pai->getOperand(1)->getType();
1210-
1211-
auto addUse = [&](VarDecl *property, DIUseKind useKind) {
1212-
auto expansionContext = TypeExpansionContext(*pai->getFunction());
1213-
auto type = selfTy.getFieldType(property, Module, expansionContext);
1214-
addElementUses(Module.getFieldIndex(typeDC, property), type, User,
1215-
useKind, property);
1216-
};
1217-
1218-
auto initializedElts = inst->getInitializedProperties();
1219-
if (initializedElts.empty()) {
1220-
// Add a placeholder use that doesn't touch elements to make sure that
1221-
// the `assign_or_init` instruction gets the kind set when `initializes`
1222-
// list is empty.
1223-
trackUse(DIMemoryUse(User, DIUseKind::InitOrAssign, BaseEltNo, 0));
1224-
} else {
1225-
for (auto *property : initializedElts)
1226-
addUse(property, DIUseKind::InitOrAssign);
1227-
}
1195+
/// AssignOrInit doesn't operate on `self` so we need to make sure
1196+
/// that the flag is dropped before calling \c addElementUses.
1197+
llvm::SaveAndRestore<bool> X(IsSelfOfNonDelegatingInitializer, false);
12281198

1229-
for (auto *property : inst->getAccessedProperties())
1230-
addUse(property, DIUseKind::Load);
1199+
auto *typeDC = Inst->getReferencedInitAccessor()
1200+
->getDeclContext()
1201+
->getSelfNominalTypeDecl();
1202+
1203+
auto selfTy = Inst->getSelf()->getType();
1204+
1205+
auto addUse = [&](VarDecl *property, DIUseKind useKind) {
1206+
auto expansionContext = TypeExpansionContext(*Inst->getFunction());
1207+
auto type = selfTy.getFieldType(property, Module, expansionContext);
1208+
addElementUses(Module.getFieldIndex(typeDC, property), type, Inst, useKind,
1209+
property);
1210+
};
1211+
1212+
auto initializedElts = Inst->getInitializedProperties();
1213+
if (initializedElts.empty()) {
1214+
// Add a placeholder use that doesn't touch elements to make sure that
1215+
// the `assign_or_init` instruction gets the kind set when `initializes`
1216+
// list is empty.
1217+
trackUse(DIMemoryUse(Inst, DIUseKind::InitOrAssign, BaseEltNo, 0));
1218+
} else {
1219+
for (auto *property : initializedElts)
1220+
addUse(property, DIUseKind::InitOrAssign);
12311221
}
1222+
1223+
for (auto *property : Inst->getAccessedProperties())
1224+
addUse(property, DIUseKind::Load);
12321225
}
12331226

12341227
/// collectClassSelfUses - Collect all the uses of a 'self' pointer in a class
@@ -1626,17 +1619,20 @@ void ElementUseCollector::collectClassSelfUses(
16261619

16271620
if (User->isDebugInstruction())
16281621
continue;
1629-
1622+
1623+
if (auto *AI = dyn_cast<AssignOrInitInst>(User)) {
1624+
collectAssignOrInitUses(AI);
1625+
continue;
1626+
}
1627+
16301628
// If this is a partial application of self, then this is an escape point
16311629
// for it.
16321630
if (auto *PAI = dyn_cast<PartialApplyInst>(User)) {
16331631
if (onlyUsedByAssignByWrapper(PAI))
16341632
continue;
16351633

1636-
if (onlyUsedByAssignOrInit(PAI)) {
1637-
collectAssignOrInitUses(PAI, Op);
1634+
if (onlyUsedByAssignOrInit(PAI))
16381635
continue;
1639-
}
16401636

16411637
if (addClosureElementUses(PAI, Op))
16421638
continue;

lib/SILOptimizer/Mandatory/RawSILInstLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ lowerAssignOrInitInstruction(SILBuilderWithScope &b,
287287
auto *setterPA = dyn_cast<PartialApplyInst>(inst->getSetter());
288288
assert(setterPA);
289289

290-
auto selfValue = setterPA->getOperand(1);
290+
auto selfValue = inst->getSelf();
291291
auto isRefSelf = selfValue->getType().getASTType()->mayHaveSuperclass();
292292

293293
SILValue selfRef;

test/SILOptimizer/init_accessor_raw_sil_lowering.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ struct Test1 {
2727

2828
// CHECK-LABEL: sil hidden [ossa] @$s23assign_or_init_lowering5Test1V1aACSi_tcfC : $@convention(method) (Int, @thin Test1.Type) -> @owned Test1
2929
init(a: Int) {
30-
// CHECK: assign_or_init [init] [[VALUE:%.*]] : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set {{.*}} : $@callee_guaranteed (Int) -> ()
30+
// CHECK: assign_or_init [init] self {{.*}}, value [[VALUE:%.*]] : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set {{.*}} : $@callee_guaranteed (Int) -> ()
3131
self.a = a
32-
// CHECK: assign_or_init [init] [assign=0] [[VALUE:%.*]] : $String, init {{.*}} : $@convention(thin) (@owned String) -> (@out Int, @out String), set {{.*}} : $@callee_guaranteed (@owned String) -> ()
32+
// CHECK: assign_or_init [init] [assign=0] self {{.*}}, value [[VALUE:%.*]] : $String, init {{.*}} : $@convention(thin) (@owned String) -> (@out Int, @out String), set {{.*}} : $@callee_guaranteed (@owned String) -> ()
3333
self.a = -1
3434
self.b = ""
35-
// CHECK: assign_or_init [set] [[VALUE:%.*]] : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set {{.*}} : $@callee_guaranteed (Int) -> ()
35+
// CHECK: assign_or_init [set] self {{.*}}, value [[VALUE:%.*]] : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set {{.*}} : $@callee_guaranteed (Int) -> ()
3636
self.a = a
3737
}
3838
}
@@ -54,12 +54,12 @@ struct Test2<T> {
5454

5555
// CHECK-LABEL: sil hidden [ossa] @$s23assign_or_init_lowering5Test2V1a1bACyxGSi_xtcfC : $@convention(method) <T> (Int, @in T, @thin Test2<T>.Type) -> @out Test2<T>
5656
init(a: Int, b: T) {
57-
// CHECK: assign_or_init [init] [[VALUE:%.*]] : $*(Int, T), init {{.*}} : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0), set {{.*}} : $@callee_guaranteed (Int, @in T) -> ()
57+
// CHECK: assign_or_init [init] self {{.*}}, value [[VALUE:%.*]] : $*(Int, T), init {{.*}} : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0), set {{.*}} : $@callee_guaranteed (Int, @in T) -> ()
5858
self.pair = (a, b)
59-
// CHECK: assign_or_init [init] [assign=0] [assign=1] [[VALUE:%.*]] : $*(Int, T), init {{.*}} : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0), set {{.*}} : $@callee_guaranteed (Int, @in T) -> ()
59+
// CHECK: assign_or_init [init] [assign=0] [assign=1] self {{.*}}, value [[VALUE:%.*]] : $*(Int, T), init {{.*}} : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0), set {{.*}} : $@callee_guaranteed (Int, @in T) -> ()
6060
self.pair = (0, b)
6161
self._c = ""
62-
// CHECK: assign_or_init [set] [[VALUE:%.*]] : $*(Int, T), init {{.*}} : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0), set {{.*}} : $@callee_guaranteed (Int, @in T) -> ()
62+
// CHECK: assign_or_init [set] self {{.*}}, value [[VALUE:%.*]] : $*(Int, T), init {{.*}} : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0), set {{.*}} : $@callee_guaranteed (Int, @in T) -> ()
6363
self.pair = (1, b)
6464
}
6565
}
@@ -75,7 +75,7 @@ struct Test {
7575

7676
// CHECK-LABEL: sil hidden [ossa] @$s23assign_or_init_lowering4TestV1vACSi_tcfC : $@convention(method) (Int, @thin Test.Type) -> Test
7777
init(v: Int) {
78-
// CHECK: assign_or_init [set] %0 : $Int, init {{.*}} : $@convention(thin) (Int) -> (), set {{.*}} : $@callee_guaranteed (Int) -> ()
78+
// CHECK: assign_or_init [set] self {{.*}}, value %0 : $Int, init {{.*}} : $@convention(thin) (Int) -> (), set {{.*}} : $@callee_guaranteed (Int) -> ()
7979
self.test = v
8080
}
8181
}

0 commit comments

Comments
 (0)