Skip to content

Commit b175436

Browse files
committed
libswift: add instructions, support block predecessors/successors
Add many new instruction classes in libswift, including all terminator instructions. This allows to support BasicBlock predecessors and successors.
1 parent 46c3a17 commit b175436

File tree

16 files changed

+761
-109
lines changed

16 files changed

+761
-109
lines changed

include/swift/SIL/SILBridging.h

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ typedef struct {
2727

2828
typedef struct {
2929
const unsigned char * _Nonnull data;
30-
size_t numOperands;
31-
} BridgedOperandArray;
30+
size_t numElements;
31+
} BridgedArrayRef;
3232

3333
enum {
34-
BridgedOperandSize = 4 * sizeof(uintptr_t)
34+
BridgedOperandSize = 4 * sizeof(uintptr_t),
35+
BridgedSuccessorSize = 5 * sizeof(uintptr_t)
3536
};
3637

3738
typedef struct {
@@ -75,6 +76,14 @@ typedef struct {
7576
const void * _Nullable op;
7677
} OptionalBridgedOperand;
7778

79+
typedef struct {
80+
const void * _Nonnull succ;
81+
} BridgedSuccessor;
82+
83+
typedef struct {
84+
const void * _Nullable succ;
85+
} OptionalBridgedSuccessor;
86+
7887
typedef struct {
7988
SwiftObject obj;
8089
} BridgedFunction;
@@ -155,11 +164,16 @@ BridgedStringRef SILGlobalVariable_debugDescription(BridgedGlobalVar global);
155164

156165
OptionalBridgedBasicBlock SILBasicBlock_next(BridgedBasicBlock block);
157166
OptionalBridgedBasicBlock SILBasicBlock_previous(BridgedBasicBlock block);
167+
BridgedFunction SILBasicBlock_getFunction(BridgedBasicBlock block);
158168
BridgedStringRef SILBasicBlock_debugDescription(BridgedBasicBlock block);
159169
OptionalBridgedInstruction SILBasicBlock_firstInst(BridgedBasicBlock block);
160170
OptionalBridgedInstruction SILBasicBlock_lastInst(BridgedBasicBlock block);
161171
SwiftInt SILBasicBlock_getNumArguments(BridgedBasicBlock block);
162172
BridgedArgument SILBasicBlock_getArgument(BridgedBasicBlock block, SwiftInt index);
173+
OptionalBridgedSuccessor SILBasicBlock_getFirstPred(BridgedBasicBlock block);
174+
OptionalBridgedSuccessor SILSuccessor_getNext(BridgedSuccessor succ);
175+
BridgedBasicBlock SILSuccessor_getTargetBlock(BridgedSuccessor succ);
176+
BridgedInstruction SILSuccessor_getContainingInst(BridgedSuccessor succ);
163177

164178
BridgedValue Operand_getValue(BridgedOperand);
165179
OptionalBridgedOperand Operand_nextUse(BridgedOperand);
@@ -176,7 +190,7 @@ BridgedBasicBlock SILArgument_getParent(BridgedArgument argument);
176190
OptionalBridgedInstruction SILInstruction_next(BridgedInstruction inst);
177191
OptionalBridgedInstruction SILInstruction_previous(BridgedInstruction inst);
178192
BridgedBasicBlock SILInstruction_getParent(BridgedInstruction inst);
179-
BridgedOperandArray SILInstruction_getOperands(BridgedInstruction inst);
193+
BridgedArrayRef SILInstruction_getOperands(BridgedInstruction inst);
180194
BridgedLocation SILInstruction_getLocation(BridgedInstruction inst);
181195
BridgedMemoryBehavior SILInstruction_getMemBehavior(BridgedInstruction inst);
182196

@@ -185,8 +199,24 @@ SwiftInt MultipleValueInstruction_getNumResults(BridgedInstruction inst);
185199
BridgedMultiValueResult
186200
MultipleValueInstruction_getResult(BridgedInstruction inst, SwiftInt index);
187201

202+
BridgedArrayRef TermInst_getSuccessors(BridgedInstruction term);
203+
188204
BridgedStringRef CondFailInst_getMessage(BridgedInstruction cfi);
189205
BridgedGlobalVar GlobalAccessInst_getGlobal(BridgedInstruction globalInst);
206+
SwiftInt TupleExtractInst_fieldIndex(BridgedInstruction tei);
207+
SwiftInt TupleElementAddrInst_fieldIndex(BridgedInstruction teai);
208+
SwiftInt StructExtractInst_fieldIndex(BridgedInstruction sei);
209+
SwiftInt StructElementAddrInst_fieldIndex(BridgedInstruction seai);
210+
SwiftInt EnumInst_caseIndex(BridgedInstruction ei);
211+
SwiftInt UncheckedEnumDataInst_caseIndex(BridgedInstruction uedi);
212+
SwiftInt RefElementAddrInst_fieldIndex(BridgedInstruction reai);
213+
SwiftInt PartialApplyInst_numArguments(BridgedInstruction ai);
214+
SwiftInt ApplyInst_numArguments(BridgedInstruction ai);
215+
SwiftInt BeginApplyInst_numArguments(BridgedInstruction ai);
216+
SwiftInt TryApplyInst_numArguments(BridgedInstruction ai);
217+
BridgedBasicBlock BranchInst_getTargetBlock(BridgedInstruction bi);
218+
SwiftInt SwitchEnumInst_getNumCases(BridgedInstruction se);
219+
SwiftInt SwitchEnumInst_getCaseIndex(BridgedInstruction se, SwiftInt idx);
190220

191221
BridgedInstruction SILBuilder_createBuiltinBinaryFunction(
192222
BridgedInstruction insertionPoint,

include/swift/SIL/SILInstruction.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6267,6 +6267,8 @@ class TupleElementAddrInst
62676267
/// object, including properties declared in a superclass.
62686268
unsigned getFieldIndex(NominalTypeDecl *decl, VarDecl *property);
62696269

6270+
unsigned getCaseIndex(EnumElementDecl *enumElement);
6271+
62706272
/// Get the property for a struct or class by its unique index, or nullptr if
62716273
/// the index does not match a property declared in this struct or class or
62726274
/// one its superclasses.

include/swift/SIL/SILNodes.def

Lines changed: 55 additions & 65 deletions
Large diffs are not rendered by default.

include/swift/SIL/SILSuccessor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ class SILSuccessor {
7676

7777
operator SILBasicBlock*() const { return SuccessorBlock; }
7878
SILBasicBlock *getBB() const { return SuccessorBlock; }
79+
TermInst *getContainingInst() const { return ContainingInst; }
80+
SILSuccessor *getNext() const { return Next; }
7981

8082
ProfileCounter getCount() const { return Count; }
8183

lib/SIL/IR/SILInstructions.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,6 +1311,16 @@ unsigned swift::getFieldIndex(NominalTypeDecl *decl, VarDecl *field) {
13111311
"property of the operand type");
13121312
}
13131313

1314+
unsigned swift::getCaseIndex(EnumElementDecl *enumElement) {
1315+
unsigned idx = 0;
1316+
for (EnumElementDecl *e : enumElement->getParentEnum()->getAllElements()) {
1317+
if (e == enumElement)
1318+
return idx;
1319+
++idx;
1320+
}
1321+
llvm_unreachable("enum element not found in enum decl");
1322+
}
1323+
13141324
/// Get the property for a struct or class by its unique index.
13151325
VarDecl *swift::getIndexedField(NominalTypeDecl *decl, unsigned index) {
13161326
if (auto *structDecl = dyn_cast<StructDecl>(decl)) {

lib/SIL/Utils/SILBridging.cpp

Lines changed: 103 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ void registerBridgedClass(BridgedStringRef className, SwiftMetatype metatype) {
8686
return SILGlobalVariable::registerBridgedMetatype(metatype);
8787
if (clName == "BlockArgument") {
8888
nodeMetatypes[(unsigned)SILNodeKind::SILPhiArgument] = metatype;
89+
return;
90+
}
91+
if (clName == "FunctionArgument") {
8992
nodeMetatypes[(unsigned)SILNodeKind::SILFunctionArgument] = metatype;
9093
return;
9194
}
@@ -100,21 +103,21 @@ void registerBridgedClass(BridgedStringRef className, SwiftMetatype metatype) {
100103
return setUnimplementedRange(metatype, VALUE_RANGE(RefCountingInst));
101104
if (clName == "UnimplementedSingleValueInst")
102105
return setUnimplementedRange(metatype, VALUE_RANGE(SingleValueInstruction));
103-
if (clName == "UnimplementedMultiValueInst")
104-
return setUnimplementedRange(metatype, VALUE_RANGE(MultipleValueInstruction));
105106
if (clName == "UnimplementedInstruction")
106107
return setUnimplementedRange(metatype, VALUE_RANGE(SILInstruction));
107108
#undef VALUE_RANGE
108109

109110
if (valueNamesToKind.empty()) {
110-
#define BRIDGED_VALUE(ID, PARENT) \
111+
#define VALUE(ID, PARENT) \
111112
valueNamesToKind[#ID] = SILNodeKind::ID;
112113
#define BRIDGED_NON_VALUE_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) \
113-
BRIDGED_VALUE(ID, NAME)
114-
#define BRIDGED_ARGUMENT(ID, PARENT) \
115-
BRIDGED_VALUE(ID, NAME)
114+
VALUE(ID, NAME)
115+
#define ARGUMENT(ID, PARENT) \
116+
VALUE(ID, NAME)
116117
#define BRIDGED_SINGLE_VALUE_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) \
117-
BRIDGED_VALUE(ID, NAME)
118+
VALUE(ID, NAME)
119+
#define MULTIPLE_VALUE_INST(ID, NAME, PARENT, MEMBEHAVIOR, MAYRELEASE) \
120+
VALUE(ID, NAME)
118121
#include "swift/SIL/SILNodes.def"
119122
}
120123

@@ -123,14 +126,13 @@ void registerBridgedClass(BridgedStringRef className, SwiftMetatype metatype) {
123126
if (iter == valueNamesToKind.end()) {
124127
// Try again with a "SIL" prefix. For example Argument -> SILArgument.
125128
prefixedName = std::string("SIL") + std::string(clName);
129+
iter = valueNamesToKind.find(prefixedName);
130+
if (iter == valueNamesToKind.end()) {
131+
llvm::errs() << "Unknown bridged node class " << clName << '\n';
132+
abort();
133+
}
126134
clName = prefixedName;
127135
}
128-
129-
iter = valueNamesToKind.find(clName);
130-
if (iter == valueNamesToKind.end()) {
131-
llvm::errs() << "Unknonwn bridged node class " << clName << '\n';
132-
abort();
133-
}
134136
SILNodeKind kind = iter->second;
135137
SwiftMetatype existingTy = nodeMetatypes[(unsigned)kind];
136138
if (existingTy && !unimplementedTypes.count(existingTy)) {
@@ -182,6 +184,9 @@ OptionalBridgedBasicBlock SILFunction_lastBlock(BridgedFunction function) {
182184
// SILBasicBlock
183185
//===----------------------------------------------------------------------===//
184186

187+
static_assert(BridgedSuccessorSize == sizeof(SILSuccessor),
188+
"wrong bridged SILSuccessor size");
189+
185190
OptionalBridgedBasicBlock SILBasicBlock_next(BridgedBasicBlock block) {
186191
SILBasicBlock *b = castToBasicBlock(block);
187192
auto iter = std::next(b->getIterator());
@@ -198,6 +203,10 @@ OptionalBridgedBasicBlock SILBasicBlock_previous(BridgedBasicBlock block) {
198203
return {&*iter};
199204
}
200205

206+
BridgedFunction SILBasicBlock_getFunction(BridgedBasicBlock block) {
207+
return {castToBasicBlock(block)->getParent()};
208+
}
209+
201210
BridgedStringRef SILBasicBlock_debugDescription(BridgedBasicBlock block) {
202211
std::string str;
203212
llvm::raw_string_ostream os(str);
@@ -227,6 +236,25 @@ BridgedArgument SILBasicBlock_getArgument(BridgedBasicBlock block, SwiftInt inde
227236
return {castToBasicBlock(block)->getArgument(index)};
228237
}
229238

239+
OptionalBridgedSuccessor SILBasicBlock_getFirstPred(BridgedBasicBlock block) {
240+
return {castToBasicBlock(block)->pred_begin().getSuccessorRef()};
241+
}
242+
243+
static SILSuccessor *castToSuccessor(BridgedSuccessor succ) {
244+
return const_cast<SILSuccessor *>(static_cast<const SILSuccessor *>(succ.succ));
245+
}
246+
247+
OptionalBridgedSuccessor SILSuccessor_getNext(BridgedSuccessor succ) {
248+
return {castToSuccessor(succ)->getNext()};
249+
}
250+
251+
BridgedBasicBlock SILSuccessor_getTargetBlock(BridgedSuccessor succ) {
252+
return {castToSuccessor(succ)->getBB()};
253+
}
254+
255+
BridgedInstruction SILSuccessor_getContainingInst(BridgedSuccessor succ) {
256+
return {castToSuccessor(succ)->getContainingInst()};
257+
}
230258

231259
//===----------------------------------------------------------------------===//
232260
// SILArgument
@@ -324,7 +352,7 @@ BridgedBasicBlock SILInstruction_getParent(BridgedInstruction inst) {
324352
return {i->getParent()};
325353
}
326354

327-
BridgedOperandArray SILInstruction_getOperands(BridgedInstruction inst) {
355+
BridgedArrayRef SILInstruction_getOperands(BridgedInstruction inst) {
328356
auto operands = castToInst(inst)->getAllOperands();
329357
return {(const unsigned char *)operands.data(), operands.size()};
330358
}
@@ -350,6 +378,11 @@ MultipleValueInstruction_getResult(BridgedInstruction inst, SwiftInt index) {
350378
return {castToInst<MultipleValueInstruction>(inst)->getResult(index)};
351379
}
352380

381+
BridgedArrayRef TermInst_getSuccessors(BridgedInstruction term) {
382+
auto successors = castToInst<TermInst>(term)->getSuccessors();
383+
return {(const unsigned char *)successors.data(), successors.size()};
384+
}
385+
353386
//===----------------------------------------------------------------------===//
354387
// Instruction classes
355388
//===----------------------------------------------------------------------===//
@@ -362,6 +395,62 @@ BridgedGlobalVar GlobalAccessInst_getGlobal(BridgedInstruction globalInst) {
362395
return {castToInst<GlobalAccessInst>(globalInst)->getReferencedGlobal()};
363396
}
364397

398+
SwiftInt TupleExtractInst_fieldIndex(BridgedInstruction tei) {
399+
return castToInst<TupleExtractInst>(tei)->getFieldIndex();
400+
}
401+
402+
SwiftInt TupleElementAddrInst_fieldIndex(BridgedInstruction teai) {
403+
return castToInst<TupleElementAddrInst>(teai)->getFieldIndex();
404+
}
405+
406+
SwiftInt StructExtractInst_fieldIndex(BridgedInstruction sei) {
407+
return castToInst<StructExtractInst>(sei)->getFieldIndex();
408+
}
409+
410+
SwiftInt StructElementAddrInst_fieldIndex(BridgedInstruction seai) {
411+
return castToInst<StructElementAddrInst>(seai)->getFieldIndex();
412+
}
413+
414+
SwiftInt EnumInst_caseIndex(BridgedInstruction ei) {
415+
return getCaseIndex(castToInst<EnumInst>(ei)->getElement());
416+
}
417+
418+
SwiftInt UncheckedEnumDataInst_caseIndex(BridgedInstruction uedi) {
419+
return getCaseIndex(castToInst<UncheckedEnumDataInst>(uedi)->getElement());
420+
}
421+
422+
SwiftInt RefElementAddrInst_fieldIndex(BridgedInstruction reai) {
423+
return castToInst<RefElementAddrInst>(reai)->getFieldIndex();
424+
}
425+
426+
SwiftInt PartialApplyInst_numArguments(BridgedInstruction pai) {
427+
return castToInst<PartialApplyInst>(pai)->getNumArguments();
428+
}
429+
430+
SwiftInt ApplyInst_numArguments(BridgedInstruction ai) {
431+
return castToInst<ApplyInst>(ai)->getNumArguments();
432+
}
433+
434+
SwiftInt BeginApplyInst_numArguments(BridgedInstruction tai) {
435+
return castToInst<BeginApplyInst>(tai)->getNumArguments();
436+
}
437+
438+
SwiftInt TryApplyInst_numArguments(BridgedInstruction tai) {
439+
return castToInst<TryApplyInst>(tai)->getNumArguments();
440+
}
441+
442+
BridgedBasicBlock BranchInst_getTargetBlock(BridgedInstruction bi) {
443+
return {castToInst<BranchInst>(bi)->getDestBB()};
444+
}
445+
446+
SwiftInt SwitchEnumInst_getNumCases(BridgedInstruction se) {
447+
return castToInst<SwitchEnumInst>(se)->getNumCases();
448+
}
449+
450+
SwiftInt SwitchEnumInst_getCaseIndex(BridgedInstruction se, SwiftInt idx) {
451+
return getCaseIndex(castToInst<SwitchEnumInst>(se)->getCase(idx).first);
452+
}
453+
365454
//===----------------------------------------------------------------------===//
366455
// SILBuilder
367456
//===----------------------------------------------------------------------===//

libswift/Sources/Optimizer/FunctionPasses/SILPrinter.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ func runSILPrinter(function: Function, context: FunctionPassContext) {
2020
for (bbIdx, block) in function.blocks.enumerated() {
2121
print("bb\(bbIdx):")
2222

23+
print(" predecessors: " +
24+
block.predecessors.map { $0.label }.joined(separator: ", "))
25+
print(" successors: " +
26+
block.successors.map { $0.label }.joined(separator: ", "))
27+
2328
print(" arguments:")
2429
for arg in block.arguments {
2530
print(" arg: \(arg)")

libswift/Sources/SIL/ApplySite.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===--- ApplySite.swift - Defines the ApplySite protocols ----------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
public protocol ApplySite : AnyObject {
14+
var operands: OperandArray { get }
15+
var numArguments: Int { get }
16+
}
17+
18+
private let firstArgumentIndex = 1
19+
20+
extension ApplySite {
21+
public var callee: Value { operands[0].value }
22+
23+
public func argumentIndex(of operand: Operand) -> Int? {
24+
let opIdx = operand.index
25+
if opIdx >= firstArgumentIndex &&
26+
opIdx <= firstArgumentIndex + numArguments {
27+
return opIdx - firstArgumentIndex
28+
}
29+
return nil
30+
}
31+
}
32+
33+
public protocol FullApplySite : ApplySite {
34+
}

0 commit comments

Comments
 (0)