Skip to content

Commit b8a4b87

Browse files
authored
Merge pull request #63748 from eeckstein/fix-keypath-inst
SIL: add type-dependent operands to the `keypath` instruction
2 parents a3ac122 + 2c1d48b commit b8a4b87

File tree

8 files changed

+59
-16
lines changed

8 files changed

+59
-16
lines changed

include/swift/SIL/SILInstruction.h

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3870,7 +3870,8 @@ class KeyPathInst final
38703870
friend TrailingObjects;
38713871

38723872
KeyPathPattern *Pattern;
3873-
unsigned NumOperands;
3873+
unsigned numPatternOperands;
3874+
unsigned numTypeDependentOperands;
38743875
SubstitutionMap Substitutions;
38753876

38763877
static KeyPathInst *create(SILDebugLocation Loc,
@@ -3883,11 +3884,12 @@ class KeyPathInst final
38833884
KeyPathInst(SILDebugLocation Loc,
38843885
KeyPathPattern *Pattern,
38853886
SubstitutionMap Subs,
3886-
ArrayRef<SILValue> Args,
3887+
ArrayRef<SILValue> allOperands,
3888+
unsigned numPatternOperands,
38873889
SILType Ty);
38883890

38893891
size_t numTrailingObjects(OverloadToken<Operand>) const {
3890-
return NumOperands;
3892+
return numPatternOperands + numTypeDependentOperands;
38913893
}
38923894

38933895
public:
@@ -3899,6 +3901,23 @@ class KeyPathInst final
38993901
}
39003902
MutableArrayRef<Operand> getAllOperands();
39013903

3904+
ArrayRef<Operand> getPatternOperands() const {
3905+
return getAllOperands().slice(0, numPatternOperands);
3906+
}
3907+
3908+
MutableArrayRef<Operand> getPatternOperands() {
3909+
return getAllOperands().slice(0, numPatternOperands);
3910+
}
3911+
3912+
3913+
ArrayRef<Operand> getTypeDependentOperands() const {
3914+
return getAllOperands().slice(numPatternOperands);
3915+
}
3916+
3917+
MutableArrayRef<Operand> getTypeDependentOperands() {
3918+
return getAllOperands().slice(numPatternOperands);
3919+
}
3920+
39023921
SubstitutionMap getSubstitutions() const { return Substitutions; }
39033922

39043923
void dropReferencedPattern();

lib/SIL/IR/SILInstructions.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2899,24 +2899,30 @@ KeyPathInst::create(SILDebugLocation Loc,
28992899
assert(Args.size() == Pattern->getNumOperands()
29002900
&& "number of key path args doesn't match pattern");
29012901

2902-
auto totalSize = totalSizeToAlloc<Operand>(Args.size());
2902+
SmallVector<SILValue, 8> allOperands(Args.begin(), Args.end());
2903+
collectTypeDependentOperands(allOperands, F, Ty);
2904+
2905+
auto totalSize = totalSizeToAlloc<Operand>(allOperands.size());
29032906
void *mem = F.getModule().allocateInst(totalSize, alignof(KeyPathInst));
2904-
return ::new (mem) KeyPathInst(Loc, Pattern, Subs, Args, Ty);
2907+
return ::new (mem) KeyPathInst(Loc, Pattern, Subs, allOperands, Args.size(), Ty);
29052908
}
29062909

29072910
KeyPathInst::KeyPathInst(SILDebugLocation Loc,
29082911
KeyPathPattern *Pattern,
29092912
SubstitutionMap Subs,
2910-
ArrayRef<SILValue> Args,
2913+
ArrayRef<SILValue> allOperands,
2914+
unsigned numPatternOperands,
29112915
SILType Ty)
29122916
: InstructionBase(Loc, Ty),
29132917
Pattern(Pattern),
2914-
NumOperands(Pattern->getNumOperands()),
2918+
numPatternOperands(numPatternOperands),
2919+
numTypeDependentOperands(allOperands.size() - numPatternOperands),
29152920
Substitutions(Subs)
29162921
{
2922+
assert(allOperands.size() >= numPatternOperands);
29172923
auto *operandsBuf = getTrailingObjects<Operand>();
2918-
for (unsigned i = 0; i < Args.size(); ++i) {
2919-
::new ((void*)&operandsBuf[i]) Operand(this, Args[i]);
2924+
for (unsigned i = 0; i < allOperands.size(); ++i) {
2925+
::new ((void*)&operandsBuf[i]) Operand(this, allOperands[i]);
29202926
}
29212927

29222928
// Increment the use of any functions referenced from the keypath pattern.
@@ -2927,7 +2933,7 @@ KeyPathInst::KeyPathInst(SILDebugLocation Loc,
29272933

29282934
MutableArrayRef<Operand>
29292935
KeyPathInst::getAllOperands() {
2930-
return {getTrailingObjects<Operand>(), NumOperands};
2936+
return {getTrailingObjects<Operand>(), numPatternOperands + numTypeDependentOperands};
29312937
}
29322938

29332939
KeyPathInst::~KeyPathInst() {

lib/SIL/IR/SILPrinter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2673,10 +2673,10 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
26732673
*this << ' ';
26742674
printSubstitutions(KPI->getSubstitutions());
26752675
}
2676-
if (!KPI->getAllOperands().empty()) {
2676+
if (!KPI->getPatternOperands().empty()) {
26772677
*this << " (";
26782678

2679-
interleave(KPI->getAllOperands(),
2679+
interleave(KPI->getPatternOperands(),
26802680
[&](const Operand &operand) {
26812681
*this << Ctx.getID(operand.get());
26822682
}, [&]{

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5240,7 +5240,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
52405240
baseTy,
52415241
leafTy,
52425242
component,
5243-
KPI->getAllOperands(),
5243+
KPI->getPatternOperands(),
52445244
KPI->getPattern()->getGenericSignature(),
52455245
KPI->getSubstitutions(),
52465246
/*property descriptor*/false,

lib/SILOptimizer/IPO/CapturePropagation.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ static SILInstruction *getConstant(SILValue V) {
7373
// mangling scheme.
7474
// But currently it's not worth it because we do not optimize subscript
7575
// keypaths in SILCombine.
76-
if (kp->getNumOperands() != 0)
76+
if (kp->getPatternOperands().size() != 0)
7777
return nullptr;
7878
if (!kp->hasPattern())
7979
return nullptr;

lib/SILOptimizer/Transforms/DeadObjectElimination.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ bool DeadObjectElimination::processKeyPath(KeyPathInst *KPI) {
882882

883883
// For simplicity just bail if the keypath has a non-trivial operands.
884884
// TODO: don't bail but insert compensating destroys for such operands.
885-
for (const Operand &Op : KPI->getAllOperands()) {
885+
for (const Operand &Op : KPI->getPatternOperands()) {
886886
if (!Op.get()->getType().isTrivial(*KPI->getFunction()))
887887
return false;
888888
}

lib/Serialization/SerializeSIL.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2490,7 +2490,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
24902490
writeKeyPathPatternComponent(component, ListOfValues);
24912491
}
24922492

2493-
for (auto &operand : KPI->getAllOperands()) {
2493+
for (auto &operand : KPI->getPatternOperands()) {
24942494
auto value = operand.get();
24952495
ListOfValues.push_back(addValueRef(value));
24962496
ListOfValues.push_back(S.addTypeRef(value->getType().getASTType()));
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %target-swift-frontend -O -emit-sil %s | %FileCheck %s
2+
3+
public protocol P {}
4+
5+
// CHECK-LABEL: sil @$s14inline_keypath6testitySbAA1P_pXp_s14PartialKeyPathCyxGtSlRzlF
6+
// CHECK: [[T:%[0-9]+]] = open_existential_metatype %0
7+
// CHECK: = keypath {{.*}}@opened{{.*}} type-defs: [[T]]
8+
// CHECK: } // end sil function '$s14inline_keypath6testitySbAA1P_pXp_s14PartialKeyPathCyxGtSlRzlF'
9+
public func testit<C: Collection>(_ t: any P.Type, _ kp: PartialKeyPath<C>) -> Bool {
10+
return tyFunc(t, kp)
11+
}
12+
13+
@inline(__always)
14+
func tyFunc<C: Collection, H: P>(_ h: H.Type, _ kp: PartialKeyPath<C>) -> Bool {
15+
return kp == \Array<H>.count
16+
}
17+
18+

0 commit comments

Comments
 (0)