Skip to content

Commit 8080465

Browse files
committed
libswift: basic SIL and SIL bridging
This is the initial version of a buildable SIL definition in libswift. It defines an initial set of SIL classes, like Function, BasicBlock, Instruction, Argument, and a few instruction classes. The interface between C++ and SIL is a bridging layer, implemented in C. It contains all the required bridging data structures used to access various SIL data structures.
1 parent 809ce72 commit 8080465

31 files changed

+1613
-26
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//===--- BridgedSwiftObject.h - C header which defines SwiftObject --------===//
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+
// This is a C header, which defines the SwiftObject header. For the C++ version
14+
// see SwiftObjectHeader.h.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef SWIFT_SIL_BRIDGEDSWIFTOBJECT_H
19+
#define SWIFT_SIL_BRIDGEDSWIFTOBJECT_H
20+
21+
#include <stdint.h>
22+
23+
#if !__has_feature(nullability)
24+
# define _Nullable
25+
# define _Nonnull
26+
# define _Null_unspecified
27+
#endif
28+
29+
typedef const void * _Nonnull SwiftMetatype;
30+
31+
/// The header of a Swift object.
32+
///
33+
/// This must be in sync with HeapObject, which is defined in the runtime lib.
34+
/// It must be layout compatible with the Swift object header.
35+
struct BridgedSwiftObject {
36+
SwiftMetatype metatype;
37+
int64_t refCounts;
38+
};
39+
40+
typedef struct BridgedSwiftObject * _Nonnull SwiftObject;
41+
typedef struct BridgedSwiftObject * _Nullable OptionalSwiftObject;
42+
43+
#endif

include/swift/SIL/SILArgument.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ class SILArgument : public ValueBase {
196196
}
197197
};
198198

199+
inline SILArgument *castToArgument(SwiftObject argument) {
200+
return static_cast<SILArgument *>(argument);
201+
}
202+
199203
class SILPhiArgument : public SILArgument {
200204
friend class SILBasicBlock;
201205

include/swift/SIL/SILBasicBlock.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/SIL/SILArgumentArrayRef.h"
2323
#include "swift/SIL/SILInstruction.h"
2424
#include "swift/SIL/SILArgument.h"
25+
#include "swift/SIL/SwiftObjectHeader.h"
2526
#include "llvm/ADT/TinyPtrVector.h"
2627

2728
namespace swift {
@@ -31,13 +32,16 @@ class SILArgument;
3132
class SILPrintContext;
3233

3334
class SILBasicBlock :
34-
public llvm::ilist_node<SILBasicBlock>, public SILAllocated<SILBasicBlock> {
35+
public llvm::ilist_node<SILBasicBlock>, public SILAllocated<SILBasicBlock>,
36+
public SwiftObjectHeader {
3537
friend class SILSuccessor;
3638
friend class SILFunction;
3739
friend class SILGlobalVariable;
3840
template <typename, unsigned> friend class BasicBlockData;
3941
friend class BasicBlockBitfield;
4042

43+
static SwiftMetatype registeredMetatype;
44+
4145
public:
4246
using InstListType = llvm::iplist<SILInstruction>;
4347
private:
@@ -47,7 +51,7 @@ public llvm::ilist_node<SILBasicBlock>, public SILAllocated<SILBasicBlock> {
4751
/// PrevList - This is a list of all of the terminator operands that are
4852
/// branching to this block, forming the predecessor list. This is
4953
/// automatically managed by the SILSuccessor class.
50-
SILSuccessor *PredList;
54+
SILSuccessor *PredList = nullptr;
5155

5256
/// This is the list of basic block arguments for this block.
5357
/// A TinyPtrVector is the right choice, because ~98% of blocks have 0 or 1
@@ -82,14 +86,18 @@ public llvm::ilist_node<SILBasicBlock>, public SILAllocated<SILBasicBlock> {
8286
uint64_t lastInitializedBitfieldID = 0;
8387

8488
friend struct llvm::ilist_traits<SILBasicBlock>;
85-
SILBasicBlock() : Parent(nullptr) {}
86-
void operator=(const SILBasicBlock &) = delete;
8789

88-
void operator delete(void *Ptr, size_t) = delete;
90+
SILBasicBlock();
91+
SILBasicBlock(SILFunction *parent);
8992

90-
SILBasicBlock(SILFunction *parent) : Parent(parent), PredList(nullptr) { }
93+
void operator=(const SILBasicBlock &) = delete;
94+
void operator delete(void *Ptr, size_t) = delete;
9195

9296
public:
97+
static void registerBridgedMetatype(SwiftMetatype metatype) {
98+
registeredMetatype = metatype;
99+
}
100+
93101
~SILBasicBlock();
94102

95103
/// Gets the ID (= index in the function's block list) of the block.

include/swift/SIL/SILBridging.h

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
//===--- SILBridging.h - header for the swift SILBridging module ----------===//
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+
#ifndef SWIFT_SIL_SILBRIDGING_H
14+
#define SWIFT_SIL_SILBRIDGING_H
15+
16+
#include "BridgedSwiftObject.h"
17+
#include <stddef.h>
18+
19+
#ifdef __cplusplus
20+
extern "C" {
21+
#endif
22+
23+
typedef struct {
24+
const unsigned char * _Nullable data;
25+
size_t length;
26+
} BridgedStringRef;
27+
28+
typedef struct {
29+
const unsigned char * _Nonnull data;
30+
size_t numOperands;
31+
} BridgedOperandArray;
32+
33+
enum {
34+
BridgedOperandSize = 4 * sizeof(uintptr_t)
35+
};
36+
37+
enum ChangeNotificationKind {
38+
instructionsChanged,
39+
callsChanged,
40+
branchesChanged
41+
};
42+
43+
typedef struct {
44+
void * _Null_unspecified word0;
45+
void * _Null_unspecified word1;
46+
void * _Null_unspecified word2;
47+
} BridgedLocation;
48+
49+
typedef struct {
50+
void * _Nullable typePtr;
51+
} BridgedType;
52+
53+
typedef struct {
54+
const void * _Nullable data;
55+
size_t count;
56+
} BridgedValueArray;
57+
58+
typedef struct {
59+
const void * _Nonnull op;
60+
} BridgedOperand;
61+
62+
typedef struct {
63+
const void * _Nullable op;
64+
} OptionalBridgedOperand;
65+
66+
typedef struct {
67+
SwiftObject obj;
68+
} BridgedFunction;
69+
70+
typedef struct {
71+
SwiftObject obj;
72+
} BridgedGlobalVar;
73+
74+
typedef struct {
75+
SwiftObject obj;
76+
} BridgedBasicBlock;
77+
78+
typedef struct {
79+
OptionalSwiftObject obj;
80+
} OptionalBridgedBasicBlock;
81+
82+
typedef struct {
83+
SwiftObject obj;
84+
} BridgedArgument;
85+
86+
typedef struct {
87+
OptionalSwiftObject obj;
88+
} OptionalBridgedArgument;
89+
90+
typedef struct {
91+
SwiftObject obj;
92+
} BridgedNode;
93+
94+
typedef struct {
95+
SwiftObject obj;
96+
} BridgedValue;
97+
98+
typedef struct {
99+
SwiftObject obj;
100+
} BridgedInstruction;
101+
102+
typedef struct {
103+
OptionalSwiftObject obj;
104+
} OptionalBridgedInstruction;
105+
106+
typedef struct {
107+
SwiftObject obj;
108+
} BridgedMultiValueResult;
109+
110+
typedef long SwiftInt;
111+
112+
void registerBridgedClass(BridgedStringRef className, SwiftMetatype metatype);
113+
114+
void freeBridgedStringRef(BridgedStringRef str);
115+
116+
BridgedStringRef SILFunction_getName(BridgedFunction function);
117+
BridgedStringRef SILFunction_debugDescription(BridgedFunction function);
118+
OptionalBridgedBasicBlock SILFunction_firstBlock(BridgedFunction function);
119+
OptionalBridgedBasicBlock SILFunction_lastBlock(BridgedFunction function);
120+
121+
BridgedStringRef SILGlobalVariable_getName(BridgedGlobalVar global);
122+
BridgedStringRef SILGlobalVariable_debugDescription(BridgedGlobalVar global);
123+
124+
OptionalBridgedBasicBlock SILBasicBlock_next(BridgedBasicBlock block);
125+
OptionalBridgedBasicBlock SILBasicBlock_previous(BridgedBasicBlock block);
126+
BridgedStringRef SILBasicBlock_debugDescription(BridgedBasicBlock block);
127+
OptionalBridgedInstruction SILBasicBlock_firstInst(BridgedBasicBlock block);
128+
OptionalBridgedInstruction SILBasicBlock_lastInst(BridgedBasicBlock block);
129+
SwiftInt SILBasicBlock_getNumArguments(BridgedBasicBlock block);
130+
BridgedArgument SILBasicBlock_getArgument(BridgedBasicBlock block, SwiftInt index);
131+
132+
BridgedValue Operand_getValue(BridgedOperand);
133+
OptionalBridgedOperand Operand_nextUse(BridgedOperand);
134+
BridgedInstruction Operand_getUser(BridgedOperand);
135+
136+
BridgedStringRef SILNode_debugDescription(BridgedNode node);
137+
OptionalBridgedOperand SILValue_firstUse(BridgedValue value);
138+
BridgedType SILValue_getType(BridgedValue value);
139+
140+
BridgedBasicBlock SILArgument_getParent(BridgedArgument argument);
141+
142+
OptionalBridgedInstruction SILInstruction_next(BridgedInstruction inst);
143+
OptionalBridgedInstruction SILInstruction_previous(BridgedInstruction inst);
144+
BridgedBasicBlock SILInstruction_getParent(BridgedInstruction inst);
145+
BridgedOperandArray SILInstruction_getOperands(BridgedInstruction inst);
146+
BridgedLocation SILInstruction_getLocation(BridgedInstruction inst);
147+
int SILInstruction_mayHaveSideEffects(BridgedInstruction inst);
148+
int SILInstruction_mayReadFromMemory(BridgedInstruction inst);
149+
int SILInstruction_mayWriteToMemory(BridgedInstruction inst);
150+
int SILInstruction_mayReadOrWriteMemory(BridgedInstruction inst);
151+
152+
BridgedInstruction MultiValueInstResult_getParent(BridgedMultiValueResult result);
153+
SwiftInt MultipleValueInstruction_getNumResults(BridgedInstruction inst);
154+
BridgedMultiValueResult
155+
MultipleValueInstruction_getResult(BridgedInstruction inst, SwiftInt index);
156+
157+
BridgedStringRef CondFailInst_getMessage(BridgedInstruction cfi);
158+
BridgedGlobalVar GlobalAccessInst_getGlobal(BridgedInstruction globalInst);
159+
160+
#ifdef __cplusplus
161+
} // extern "C"
162+
#endif
163+
164+
#endif

include/swift/SIL/SILBridgingUtils.h

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
//===--- SILBridgingUtils.h - utilities for swift bridging ----------------===//
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+
#ifndef SWIFT_SIL_SILBRIDGINGUTILS_H
14+
#define SWIFT_SIL_SILBRIDGINGUTILS_H
15+
16+
#include "swift/SIL/SILBridging.h"
17+
#include "swift/SIL/SILFunction.h"
18+
#include "swift/SIL/SILGlobalVariable.h"
19+
#include "llvm/ADT/StringRef.h"
20+
21+
#include <string>
22+
23+
namespace swift {
24+
25+
inline BridgedStringRef getBridgedStringRef(llvm::StringRef str) {
26+
return { (const unsigned char *)str.data(), str.size() };
27+
}
28+
29+
inline StringRef getStringRef(BridgedStringRef str) {
30+
return StringRef((const char *)str.data, str.length);
31+
}
32+
33+
/// Copies the string in an malloc'ed memory and the caller is responsible for
34+
/// freeing it.
35+
inline BridgedStringRef getCopiedBridgedStringRef(std::string str,
36+
bool removeTrailingNewline = false) {
37+
// A couple of mallocs are needed for passing a std::string to libswift. But
38+
// it's currently only used or debug descriptions. So, its' maybe not so bad -
39+
// for now.
40+
// TODO: find a better way to pass std::strings to libswift.
41+
StringRef strRef(str);
42+
if (removeTrailingNewline)
43+
strRef.consume_back("\n");
44+
llvm::MallocAllocator allocator;
45+
StringRef copy = strRef.copy(allocator);
46+
return getBridgedStringRef(copy);
47+
}
48+
49+
inline SILLocation getSILLocation(BridgedLocation loc) {
50+
return reinterpret_cast<SILDebugLocation *>(&loc)->getLocation();
51+
}
52+
53+
inline RegularLocation getRegularLocation(BridgedLocation loc) {
54+
return RegularLocation(getSILLocation(loc));
55+
}
56+
57+
inline const SILDebugScope *getSILDebugScope(BridgedLocation loc) {
58+
return reinterpret_cast<SILDebugLocation *>(&loc)->getScope();
59+
}
60+
61+
inline SILType getSILType(BridgedType ty) {
62+
return SILType::getFromOpaqueValue(ty.typePtr);
63+
}
64+
65+
inline SILNode *castToSILNode(BridgedNode node) {
66+
return static_cast<SILNode *>(node.obj);
67+
}
68+
69+
inline SILValue castToSILValue(BridgedValue value) {
70+
return static_cast<ValueBase *>(value.obj);
71+
}
72+
73+
template <class I = SILInstruction> I *castToInst(BridgedInstruction inst) {
74+
return cast<I>(static_cast<SILNode *>(inst.obj)->castToInstruction());
75+
}
76+
77+
inline SILBasicBlock *castToBasicBlock(BridgedBasicBlock block) {
78+
return static_cast<SILBasicBlock *>(block.obj);
79+
}
80+
81+
inline SILFunction *castToFunction(BridgedFunction function) {
82+
return static_cast<SILFunction *>(function.obj);
83+
}
84+
85+
inline SILGlobalVariable *castToGlobal(BridgedGlobalVar global) {
86+
return static_cast<SILGlobalVariable *>(global.obj);
87+
}
88+
89+
ArrayRef<SILValue> getSILValues(BridgedValueArray values,
90+
SmallVectorImpl<SILValue> &storage);
91+
92+
} // namespace swift
93+
94+
#endif
95+

0 commit comments

Comments
 (0)