Skip to content

Commit 3261e2e

Browse files
Merge pull request #34589 from nate-chandler/concurrency/irgen/function-constants
[Async CC] Add constant "pointer" for async func.
2 parents 2e6c120 + 6962874 commit 3261e2e

File tree

59 files changed

+586
-177
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+586
-177
lines changed

include/swift/IRGen/Linking.h

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,11 @@ class LinkEntity {
293293
/// the metadata cache once.
294294
CanonicalPrespecializedGenericTypeCachingOnceToken,
295295

296+
/// The same as AsyncFunctionPointer but with a different stored value, for
297+
/// use by TBDGen.
298+
/// The pointer is a AbstractStorageDecl*.
299+
AsyncFunctionPointerAST,
300+
296301
/// The pointer is a SILFunction*.
297302
DynamicallyReplaceableFunctionKey,
298303

@@ -410,6 +415,13 @@ class LinkEntity {
410415
/// passed to swift_getCanonicalSpecializedMetadata.
411416
/// The pointer is a canonical TypeBase*.
412417
NoncanonicalSpecializedGenericTypeMetadataCacheVariable,
418+
419+
/// Provides the data required to invoke an async function using the async
420+
/// calling convention in the form of the size of the context to allocate
421+
/// and the relative address of the function to call with that allocated
422+
/// context.
423+
/// The pointer is a SILFunction*.
424+
AsyncFunctionPointer,
413425
};
414426
friend struct llvm::DenseMapInfo<LinkEntity>;
415427

@@ -418,7 +430,7 @@ class LinkEntity {
418430
}
419431

420432
static bool isDeclKind(Kind k) {
421-
return k <= Kind::CanonicalPrespecializedGenericTypeCachingOnceToken;
433+
return k <= Kind::AsyncFunctionPointerAST;
422434
}
423435
static bool isTypeKind(Kind k) {
424436
return k >= Kind::ProtocolWitnessTableLazyAccessFunction;
@@ -1088,6 +1100,21 @@ class LinkEntity {
10881100
return entity;
10891101
}
10901102

1103+
static LinkEntity forAsyncFunctionPointer(SILFunction *silFunction) {
1104+
LinkEntity entity;
1105+
entity.Pointer = silFunction;
1106+
entity.SecondaryPointer = nullptr;
1107+
entity.Data = LINKENTITY_SET_FIELD(
1108+
Kind, unsigned(LinkEntity::Kind::AsyncFunctionPointer));
1109+
return entity;
1110+
}
1111+
1112+
static LinkEntity forAsyncFunctionPointer(AbstractFunctionDecl *decl) {
1113+
LinkEntity entity;
1114+
entity.setForDecl(Kind::AsyncFunctionPointerAST, decl);
1115+
return entity;
1116+
}
1117+
10911118
void mangle(llvm::raw_ostream &out) const;
10921119
void mangle(SmallVectorImpl<char> &buffer) const;
10931120
std::string mangleAsString() const;
@@ -1110,14 +1137,15 @@ class LinkEntity {
11101137
}
11111138

11121139
bool hasSILFunction() const {
1113-
return getKind() == Kind::SILFunction ||
1140+
return getKind() == Kind::AsyncFunctionPointer ||
11141141
getKind() == Kind::DynamicallyReplaceableFunctionVariable ||
1115-
getKind() == Kind::DynamicallyReplaceableFunctionKey;
1142+
getKind() == Kind::DynamicallyReplaceableFunctionKey ||
1143+
getKind() == Kind::SILFunction;
11161144
}
11171145

11181146
SILFunction *getSILFunction() const {
11191147
assert(hasSILFunction());
1120-
return reinterpret_cast<SILFunction*>(Pointer);
1148+
return reinterpret_cast<SILFunction *>(Pointer);
11211149
}
11221150

11231151
SILGlobalVariable *getSILGlobalVariable() const {

lib/IRGen/CallEmission.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class CallEmission {
6767
void emitToUnmappedExplosion(Explosion &out);
6868
virtual void emitCallToUnmappedExplosion(llvm::CallInst *call, Explosion &out) = 0;
6969
void emitYieldsToExplosion(Explosion &out);
70+
virtual FunctionPointer getCalleeFunctionPointer() = 0;
7071
llvm::CallInst *emitCallSite();
7172

7273
CallEmission(IRGenFunction &IGF, llvm::Value *selfValue, Callee &&callee)

lib/IRGen/Callee.h

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,31 @@ namespace irgen {
124124

125125
/// A function pointer value.
126126
class FunctionPointer {
127-
/// The actual function pointer.
127+
public:
128+
struct KindTy {
129+
enum class Value {
130+
Function,
131+
AsyncFunctionPointer,
132+
};
133+
static const Value Function = Value::Function;
134+
static const Value AsyncFunctionPointer = Value::AsyncFunctionPointer;
135+
Value value;
136+
KindTy(Value value) : value(value) {}
137+
KindTy(CanSILFunctionType fnType)
138+
: value(fnType->isAsync() ? Value::AsyncFunctionPointer
139+
: Value::Function) {}
140+
friend bool operator==(const KindTy &lhs, const KindTy &rhs) {
141+
return lhs.value == rhs.value;
142+
}
143+
friend bool operator!=(const KindTy &lhs, const KindTy &rhs) {
144+
return !(lhs == rhs);
145+
}
146+
};
147+
148+
private:
149+
KindTy Kind;
150+
151+
/// The actual pointer, either to the function or to its descriptor.
128152
llvm::Value *Value;
129153

130154
PointerAuthInfo AuthInfo;
@@ -135,25 +159,27 @@ namespace irgen {
135159
/// Construct a FunctionPointer for an arbitrary pointer value.
136160
/// We may add more arguments to this; try to use the other
137161
/// constructors/factories if possible.
138-
explicit FunctionPointer(llvm::Value *value, PointerAuthInfo authInfo,
162+
explicit FunctionPointer(KindTy kind, llvm::Value *value,
163+
PointerAuthInfo authInfo,
139164
const Signature &signature)
140-
: Value(value), AuthInfo(authInfo), Sig(signature) {
165+
: Kind(kind), Value(value), AuthInfo(authInfo), Sig(signature) {
141166
// The function pointer should have function type.
142167
assert(value->getType()->getPointerElementType()->isFunctionTy());
143168
// TODO: maybe assert similarity to signature.getType()?
144169
}
145170

146171
// Temporary only!
147-
explicit FunctionPointer(llvm::Value *value, const Signature &signature)
148-
: FunctionPointer(value, PointerAuthInfo(), signature) {}
172+
explicit FunctionPointer(KindTy kind, llvm::Value *value,
173+
const Signature &signature)
174+
: FunctionPointer(kind, value, PointerAuthInfo(), signature) {}
149175

150176
static FunctionPointer forDirect(IRGenModule &IGM,
151177
llvm::Constant *value,
152178
CanSILFunctionType fnType);
153179

154-
static FunctionPointer forDirect(llvm::Constant *value,
180+
static FunctionPointer forDirect(KindTy kind, llvm::Constant *value,
155181
const Signature &signature) {
156-
return FunctionPointer(value, PointerAuthInfo(), signature);
182+
return FunctionPointer(kind, value, PointerAuthInfo(), signature);
157183
}
158184

159185
static FunctionPointer forExplosionValue(IRGenFunction &IGF,
@@ -166,8 +192,17 @@ namespace irgen {
166192
return (isa<llvm::Constant>(Value) && AuthInfo.isConstant());
167193
}
168194

195+
KindTy getKind() const { return Kind; }
196+
197+
/// Given that this value is known to have been constructed from a direct
198+
/// function, Return the name of that function.
199+
StringRef getName(IRGenModule &IGM) const;
200+
169201
/// Return the actual function pointer.
170-
llvm::Value *getPointer() const { return Value; }
202+
llvm::Value *getPointer(IRGenFunction &IGF) const;
203+
204+
/// Return the actual function pointer.
205+
llvm::Value *getRawPointer() const { return Value; }
171206

172207
/// Given that this value is known to have been constructed from
173208
/// a direct function, return the function pointer.
@@ -205,6 +240,9 @@ namespace irgen {
205240

206241
llvm::Value *getExplosionValue(IRGenFunction &IGF,
207242
CanSILFunctionType fnType) const;
243+
244+
/// Form a FunctionPointer whose KindTy is ::Function.
245+
FunctionPointer getAsFunction(IRGenFunction &IGF) const;
208246
};
209247

210248
class Callee {

0 commit comments

Comments
 (0)