Skip to content

Commit bfb284f

Browse files
committed
Swift SIL: add a few instructions and Instruction.visitReferencedFunctions
* add `DynamicFunctionRefInst` and `PreviousDynamicFunctionRefInst` * add a common base class to all function-referencing instructions: `FunctionRefBaseInst` * add `KeyPathInst` * add `IndexAddrInst.base` and `IndexAddrInst.index` getters * add `Instruction.visitReferencedFunctions` to visit all functions which are referenced by an instruction
1 parent 90c83be commit bfb284f

File tree

5 files changed

+73
-9
lines changed

5 files changed

+73
-9
lines changed

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ public class Instruction : ListNode, CustomStringConvertible, Hashable {
104104
return SILInstruction_mayRelease(bridged)
105105
}
106106

107+
public func visitReferencedFunctions(_ cl: (Function) -> ()) {
108+
}
109+
107110
public static func ==(lhs: Instruction, rhs: Instruction) -> Bool {
108111
lhs === rhs
109112
}
@@ -344,7 +347,10 @@ final public
344347
class PointerToAddressInst : SingleValueInstruction, UnaryInstruction {}
345348

346349
final public
347-
class IndexAddrInst : SingleValueInstruction {}
350+
class IndexAddrInst : SingleValueInstruction {
351+
public var base: Value { operands[0].value }
352+
public var index: Value { operands[1].value }
353+
}
348354

349355
final public
350356
class InitExistentialRefInst : SingleValueInstruction, UnaryInstruction {}
@@ -388,12 +394,25 @@ public class GlobalAccessInst : SingleValueInstruction {
388394
}
389395
}
390396

391-
final public class FunctionRefInst : GlobalAccessInst {
397+
public class FunctionRefBaseInst : SingleValueInstruction {
392398
public var referencedFunction: Function {
393-
FunctionRefInst_getReferencedFunction(bridged).function
399+
FunctionRefBaseInst_getReferencedFunction(bridged).function
400+
}
401+
402+
public override func visitReferencedFunctions(_ cl: (Function) -> ()) {
403+
cl(referencedFunction)
394404
}
395405
}
396406

407+
final public class FunctionRefInst : FunctionRefBaseInst {
408+
}
409+
410+
final public class DynamicFunctionRefInst : FunctionRefBaseInst {
411+
}
412+
413+
final public class PreviousDynamicFunctionRefInst : FunctionRefBaseInst {
414+
}
415+
397416
final public class GlobalAddrInst : GlobalAccessInst {}
398417

399418
final public class GlobalValueInst : GlobalAccessInst {}
@@ -458,6 +477,25 @@ final public class RefElementAddrInst : SingleValueInstruction, UnaryInstruction
458477

459478
final public class RefTailAddrInst : SingleValueInstruction, UnaryInstruction {}
460479

480+
final public class KeyPathInst : SingleValueInstruction {
481+
public override func visitReferencedFunctions(_ cl: (Function) -> ()) {
482+
var results = KeyPathFunctionResults()
483+
var componentIdx = 0
484+
repeat {
485+
componentIdx = KeyPathInst_getReferencedFunctions(bridged, componentIdx, &results)
486+
let numFuncs = results.numFunctions
487+
withUnsafePointer(to: &results) {
488+
$0.withMemoryRebound(to: BridgedFunction.self, capacity: numFuncs) {
489+
let functions = UnsafeBufferPointer(start: $0, count: numFuncs)
490+
for idx in 0..<numFuncs {
491+
cl(functions[idx].function)
492+
}
493+
}
494+
}
495+
} while componentIdx >= 0
496+
}
497+
}
498+
461499
final public
462500
class UnconditionalCheckedCastInst : SingleValueInstruction, UnaryInstruction {
463501
public override var mayTrap: Bool { true }

SwiftCompilerSources/Sources/SIL/Registration.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ public func registerSILClasses() {
8383
register(ValueMetatypeInst.self)
8484
register(ExistentialMetatypeInst.self)
8585
register(FunctionRefInst.self)
86+
register(DynamicFunctionRefInst.self)
87+
register(PreviousDynamicFunctionRefInst.self)
8688
register(GlobalAddrInst.self)
8789
register(GlobalValueInst.self)
8890
register(IntegerLiteralInst.self)
@@ -99,6 +101,7 @@ public func registerSILClasses() {
99101
register(UncheckedTakeEnumDataAddrInst.self)
100102
register(RefElementAddrInst.self)
101103
register(RefTailAddrInst.self)
104+
register(KeyPathInst.self)
102105
register(UnconditionalCheckedCastInst.self)
103106
register(ConvertFunctionInst.self)
104107
register(ThinToThickFunctionInst.self)

include/swift/SIL/SILBridging.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ BridgedArrayRef TermInst_getSuccessors(BridgedInstruction term);
357357
llvm::StringRef CondFailInst_getMessage(BridgedInstruction cfi);
358358
BridgedBuiltinID BuiltinInst_getID(BridgedInstruction bi);
359359
BridgedGlobalVar GlobalAccessInst_getGlobal(BridgedInstruction globalInst);
360-
BridgedFunction FunctionRefInst_getReferencedFunction(BridgedInstruction fri);
360+
BridgedFunction FunctionRefBaseInst_getReferencedFunction(BridgedInstruction fri);
361361
llvm::StringRef StringLiteralInst_getValue(BridgedInstruction sli);
362362
SwiftInt TupleExtractInst_fieldIndex(BridgedInstruction tei);
363363
SwiftInt TupleElementAddrInst_fieldIndex(BridgedInstruction teai);
@@ -391,6 +391,14 @@ void RefCountingInst_setIsAtomic(BridgedInstruction rc, bool isAtomic);
391391
bool RefCountingInst_getIsAtomic(BridgedInstruction rc);
392392
SwiftInt CondBranchInst_getNumTrueArgs(BridgedInstruction cbr);
393393

394+
struct KeyPathFunctionResults {
395+
enum { maxFunctions = 5 };
396+
BridgedFunction functions[maxFunctions];
397+
SwiftInt numFunctions;
398+
};
399+
SwiftInt KeyPathInst_getReferencedFunctions(BridgedInstruction kpi, SwiftInt componentIdx,
400+
KeyPathFunctionResults * _Nonnull results);
401+
394402
BridgedSubstitutionMap ApplySite_getSubstitutionMap(BridgedInstruction inst);
395403
BridgedArgumentConvention
396404
ApplySite_getArgumentConvention(BridgedInstruction inst, SwiftInt calleeArgIdx);

include/swift/SIL/SILNodes.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,9 +341,9 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
341341
ABSTRACT_SINGLE_VALUE_INST(LiteralInst, SingleValueInstruction)
342342
BRIDGED_SINGLE_VALUE_INST(FunctionRefInst, function_ref,
343343
LiteralInst, None, DoesNotRelease)
344-
SINGLE_VALUE_INST(DynamicFunctionRefInst, dynamic_function_ref,
344+
BRIDGED_SINGLE_VALUE_INST(DynamicFunctionRefInst, dynamic_function_ref,
345345
LiteralInst, None, DoesNotRelease)
346-
SINGLE_VALUE_INST(PreviousDynamicFunctionRefInst, prev_dynamic_function_ref,
346+
BRIDGED_SINGLE_VALUE_INST(PreviousDynamicFunctionRefInst, prev_dynamic_function_ref,
347347
LiteralInst, None, DoesNotRelease)
348348
BRIDGED_SINGLE_VALUE_INST(GlobalAddrInst, global_addr,
349349
LiteralInst, None, DoesNotRelease)
@@ -644,7 +644,7 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
644644
// Key paths
645645
// TODO: The only "side effect" is potentially retaining the returned key path
646646
// object; is there a more specific effect?
647-
SINGLE_VALUE_INST(KeyPathInst, keypath,
647+
BRIDGED_SINGLE_VALUE_INST(KeyPathInst, keypath,
648648
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
649649

650650
// BindMemory and RebindMemory have no physical side effect. Semantically they

lib/SIL/Utils/SILBridging.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -730,8 +730,8 @@ BridgedGlobalVar GlobalAccessInst_getGlobal(BridgedInstruction globalInst) {
730730
return {castToInst<GlobalAccessInst>(globalInst)->getReferencedGlobal()};
731731
}
732732

733-
BridgedFunction FunctionRefInst_getReferencedFunction(BridgedInstruction fri) {
734-
return {castToInst<FunctionRefInst>(fri)->getReferencedFunction()};
733+
BridgedFunction FunctionRefBaseInst_getReferencedFunction(BridgedInstruction fri) {
734+
return {castToInst<FunctionRefBaseInst>(fri)->getInitiallyReferencedFunction()};
735735
}
736736

737737
llvm::StringRef StringLiteralInst_getValue(BridgedInstruction sli) {
@@ -877,6 +877,21 @@ SwiftInt CondBranchInst_getNumTrueArgs(BridgedInstruction cbr) {
877877
return castToInst<CondBranchInst>(cbr)->getNumTrueArgs();
878878
}
879879

880+
SwiftInt KeyPathInst_getReferencedFunctions(BridgedInstruction kpi, SwiftInt componentIdx,
881+
KeyPathFunctionResults * _Nonnull results) {
882+
KeyPathPattern *pattern = castToInst<KeyPathInst>(kpi)->getPattern();
883+
const KeyPathPatternComponent &comp = pattern->getComponents()[componentIdx];
884+
results->numFunctions = 0;
885+
886+
comp.visitReferencedFunctionsAndMethods([results](SILFunction *func) {
887+
assert(results->numFunctions < KeyPathFunctionResults::maxFunctions);
888+
results->functions[results->numFunctions++] = {func};
889+
}, [](SILDeclRef) {});
890+
891+
++componentIdx;
892+
return componentIdx < (int)pattern->getComponents().size() ? componentIdx : -1;
893+
}
894+
880895
BridgedSubstitutionMap ApplySite_getSubstitutionMap(BridgedInstruction inst) {
881896
auto as = ApplySite(castToInst(inst));
882897
return {as.getSubstitutionMap().getOpaqueValue()};

0 commit comments

Comments
 (0)