Skip to content

Commit 4769f21

Browse files
authored
Merge pull request swiftlang#36224 from slavapestov/reasync-sil-codegen
SIL: Preliminary support for 'apply [noasync]' calls
2 parents 9dbfd27 + 7ccc41a commit 4769f21

Some content is hidden

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

50 files changed

+437
-208
lines changed

include/swift/AST/Expr.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,10 +337,11 @@ class alignas(8) Expr {
337337
NumCaptures : 32
338338
);
339339

340-
SWIFT_INLINE_BITFIELD(ApplyExpr, Expr, 1+1+1,
340+
SWIFT_INLINE_BITFIELD(ApplyExpr, Expr, 1+1+1+1,
341341
ThrowsIsSet : 1,
342342
Throws : 1,
343-
ImplicitlyAsync : 1
343+
ImplicitlyAsync : 1,
344+
NoAsync : 1
344345
);
345346

346347
SWIFT_INLINE_BITFIELD_FULL(CallExpr, ApplyExpr, 1+1+16,
@@ -4383,6 +4384,7 @@ class ApplyExpr : public Expr {
43834384
assert(validateArg(Arg) && "Arg is not a permitted expr kind");
43844385
Bits.ApplyExpr.ThrowsIsSet = false;
43854386
Bits.ApplyExpr.ImplicitlyAsync = false;
4387+
Bits.ApplyExpr.NoAsync = false;
43864388
}
43874389

43884390
public:
@@ -4421,6 +4423,15 @@ class ApplyExpr : public Expr {
44214423
Bits.ApplyExpr.Throws = throws;
44224424
}
44234425

4426+
/// Is this a 'rethrows' function that is known not to throw?
4427+
bool isNoThrows() const { return !throws(); }
4428+
4429+
/// Is this a 'reasync' function that is known not to 'await'?
4430+
bool isNoAsync() const { return Bits.ApplyExpr.NoAsync; }
4431+
void setNoAsync(bool noAsync) {
4432+
Bits.ApplyExpr.NoAsync = noAsync;
4433+
}
4434+
44244435
/// Is this application _implicitly_ required to be an async call?
44254436
/// That is, does it need to be guarded by hop_to_executor.
44264437
/// Note that this is _not_ a check for whether the callee is async!

include/swift/SIL/ApplySite.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -443,20 +443,29 @@ class ApplySite {
443443
/// result argument to the apply site.
444444
bool isIndirectResultOperand(const Operand &op) const;
445445

446-
/// Return whether the given apply is of a formally-throwing function
447-
/// which is statically known not to throw.
448-
bool isNonThrowing() const {
446+
ApplyOptions getApplyOptions() const {
449447
switch (ApplySiteKind(getInstruction()->getKind())) {
450448
case ApplySiteKind::ApplyInst:
451-
return cast<ApplyInst>(Inst)->isNonThrowing();
449+
return cast<ApplyInst>(Inst)->getApplyOptions();
452450
case ApplySiteKind::BeginApplyInst:
453-
return cast<BeginApplyInst>(Inst)->isNonThrowing();
451+
return cast<BeginApplyInst>(Inst)->getApplyOptions();
454452
case ApplySiteKind::TryApplyInst:
455-
return false;
453+
return cast<TryApplyInst>(Inst)->getApplyOptions();
456454
case ApplySiteKind::PartialApplyInst:
457455
llvm_unreachable("Unhandled case");
458456
}
459457
}
458+
/// Return whether the given apply is of a formally-throwing function
459+
/// which is statically known not to throw.
460+
bool isNonThrowing() const {
461+
return getApplyOptions().contains(ApplyFlags::DoesNotThrow);
462+
}
463+
464+
/// Return whether the given apply is of a formally-async function
465+
/// which is statically known not to await.
466+
bool isNonAsync() const {
467+
return getApplyOptions().contains(ApplyFlags::DoesNotAwait);
468+
}
460469

461470
static ApplySite getFromOpaqueValue(void *p) { return ApplySite(p); }
462471

include/swift/SIL/SILBuilder.h

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -456,20 +456,30 @@ class SILBuilder {
456456

457457
ApplyInst *createApply(
458458
SILLocation Loc, SILValue Fn, SubstitutionMap Subs,
459-
ArrayRef<SILValue> Args, bool isNonThrowing = false,
459+
ArrayRef<SILValue> Args) {
460+
return createApply(Loc, Fn, Subs, Args,
461+
/*options=*/ApplyOptions(),
462+
/*SpecializationInfo=*/nullptr);
463+
}
464+
465+
ApplyInst *createApply(
466+
SILLocation Loc, SILValue Fn, SubstitutionMap Subs,
467+
ArrayRef<SILValue> Args,
468+
ApplyOptions options,
460469
const GenericSpecializationInformation *SpecializationInfo = nullptr) {
461470
return insert(ApplyInst::create(getSILDebugLocation(Loc), Fn, Subs, Args,
462-
isNonThrowing, C.silConv, *F,
471+
options, C.silConv, *F,
463472
C.OpenedArchetypes, SpecializationInfo));
464473
}
465474

466475
TryApplyInst *createTryApply(
467476
SILLocation Loc, SILValue fn, SubstitutionMap subs,
468477
ArrayRef<SILValue> args, SILBasicBlock *normalBB, SILBasicBlock *errorBB,
478+
ApplyOptions options = ApplyOptions(),
469479
const GenericSpecializationInformation *SpecializationInfo = nullptr) {
470480
return insertTerminator(TryApplyInst::create(
471-
getSILDebugLocation(Loc), fn, subs, args, normalBB, errorBB, *F,
472-
C.OpenedArchetypes, SpecializationInfo));
481+
getSILDebugLocation(Loc), fn, subs, args, normalBB, errorBB,
482+
options, *F, C.OpenedArchetypes, SpecializationInfo));
473483
}
474484

475485
PartialApplyInst *createPartialApply(
@@ -485,10 +495,10 @@ class SILBuilder {
485495

486496
BeginApplyInst *createBeginApply(
487497
SILLocation Loc, SILValue Fn, SubstitutionMap Subs,
488-
ArrayRef<SILValue> Args, bool isNonThrowing = false,
498+
ArrayRef<SILValue> Args, ApplyOptions options = ApplyOptions(),
489499
const GenericSpecializationInformation *SpecializationInfo = nullptr) {
490500
return insert(BeginApplyInst::create(
491-
getSILDebugLocation(Loc), Fn, Subs, Args, isNonThrowing, C.silConv, *F,
501+
getSILDebugLocation(Loc), Fn, Subs, Args, options, C.silConv, *F,
492502
C.OpenedArchetypes, SpecializationInfo));
493503
}
494504

include/swift/SIL/SILCloner.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ SILCloner<ImplClass>::visitApplyInst(ApplyInst *Inst) {
900900
Inst, getBuilder().createApply(
901901
getOpLocation(Inst->getLoc()), getOpValue(Inst->getCallee()),
902902
getOpSubstitutionMap(Inst->getSubstitutionMap()), Args,
903-
Inst->isNonThrowing(),
903+
Inst->getApplyOptions(),
904904
GenericSpecializationInformation::create(Inst, getBuilder())));
905905
}
906906

@@ -915,6 +915,7 @@ SILCloner<ImplClass>::visitTryApplyInst(TryApplyInst *Inst) {
915915
getOpSubstitutionMap(Inst->getSubstitutionMap()), Args,
916916
getOpBasicBlock(Inst->getNormalBB()),
917917
getOpBasicBlock(Inst->getErrorBB()),
918+
Inst->getApplyOptions(),
918919
GenericSpecializationInformation::create(Inst, getBuilder())));
919920
}
920921

@@ -941,7 +942,7 @@ SILCloner<ImplClass>::visitBeginApplyInst(BeginApplyInst *Inst) {
941942
Inst, getBuilder().createBeginApply(
942943
getOpLocation(Inst->getLoc()), getOpValue(Inst->getCallee()),
943944
getOpSubstitutionMap(Inst->getSubstitutionMap()), Args,
944-
Inst->isNonThrowing(),
945+
Inst->getApplyOptions(),
945946
GenericSpecializationInformation::create(Inst, getBuilder())));
946947
}
947948

include/swift/SIL/SILInstruction.h

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "swift/AST/TypeAlignments.h"
2727
#include "swift/Basic/Compiler.h"
2828
#include "swift/Basic/NullablePtr.h"
29+
#include "swift/Basic/OptionSet.h"
2930
#include "swift/Basic/ProfileCounter.h"
3031
#include "swift/Basic/Range.h"
3132
#include "swift/SIL/Consumption.h"
@@ -2152,6 +2153,16 @@ struct TerribleOverloadTokenHack :
21522153
template <class T>
21532154
using OverloadToken = TerribleOverloadTokenHack::Hack<T>;
21542155

2156+
enum class ApplyFlags : uint8_t {
2157+
/// This is a call to a 'rethrows' function that is known not to throw.
2158+
DoesNotThrow = 0x1,
2159+
2160+
/// This is a call to a 'reasync' function that is known not to 'await'.
2161+
DoesNotAwait = 0x2
2162+
};
2163+
2164+
using ApplyOptions = OptionSet<ApplyFlags>;
2165+
21552166
/// ApplyInstBase - An abstract class for different kinds of function
21562167
/// application.
21572168
template <class Impl, class Base,
@@ -2172,12 +2183,11 @@ class ApplyInstBase<Impl, Base, false> : public Base {
21722183
/// points to the specialization info of the inlined function.
21732184
const GenericSpecializationInformation *SpecializationInfo;
21742185

2175-
/// Used for apply_inst instructions: true if the called function has an
2176-
/// error result but is not actually throwing.
2177-
unsigned NonThrowing: 1;
2186+
/// Stores an ApplyOptions.
2187+
unsigned Options: 2;
21782188

21792189
/// The number of call arguments as required by the callee.
2180-
unsigned NumCallArguments : 31;
2190+
unsigned NumCallArguments : 30;
21812191

21822192
/// The total number of type-dependent operands.
21832193
unsigned NumTypeDependentOperands;
@@ -2198,7 +2208,7 @@ class ApplyInstBase<Impl, Base, false> : public Base {
21982208
As... baseArgs)
21992209
: Base(kind, DebugLoc, baseArgs...), SubstCalleeType(substCalleeType),
22002210
SpecializationInfo(specializationInfo),
2201-
NonThrowing(false), NumCallArguments(args.size()),
2211+
NumCallArguments(args.size()),
22022212
NumTypeDependentOperands(typeDependentOperands.size()),
22032213
Substitutions(subs) {
22042214

@@ -2230,12 +2240,24 @@ class ApplyInstBase<Impl, Base, false> : public Base {
22302240
ArrayRef<SILValue> typeDependentOperands) {
22312241
return NumStaticOperands + args.size() + typeDependentOperands.size();
22322242
}
2233-
2234-
void setNonThrowing(bool isNonThrowing) { NonThrowing = isNonThrowing; }
2235-
2236-
bool isNonThrowingApply() const { return NonThrowing; }
22372243

22382244
public:
2245+
void setApplyOptions(ApplyOptions options) {
2246+
Options = unsigned(options.toRaw());
2247+
}
2248+
2249+
ApplyOptions getApplyOptions() const {
2250+
return ApplyOptions(ApplyFlags(Options));
2251+
}
2252+
2253+
bool isNonThrowing() const {
2254+
return getApplyOptions().contains(ApplyFlags::DoesNotThrow);
2255+
}
2256+
2257+
bool isNonAsync() const {
2258+
return getApplyOptions().contains(ApplyFlags::DoesNotAwait);
2259+
}
2260+
22392261
/// The operand number of the first argument.
22402262
static unsigned getArgumentOperandNumber() { return NumStaticOperands; }
22412263

@@ -2555,22 +2577,16 @@ class ApplyInst final
25552577
SubstitutionMap Substitutions,
25562578
ArrayRef<SILValue> Args,
25572579
ArrayRef<SILValue> TypeDependentOperands,
2558-
bool isNonThrowing,
2580+
ApplyOptions options,
25592581
const GenericSpecializationInformation *SpecializationInfo);
25602582

25612583
static ApplyInst *
25622584
create(SILDebugLocation DebugLoc, SILValue Callee,
25632585
SubstitutionMap Substitutions, ArrayRef<SILValue> Args,
2564-
bool isNonThrowing, Optional<SILModuleConventions> ModuleConventions,
2586+
ApplyOptions options,
2587+
Optional<SILModuleConventions> ModuleConventions,
25652588
SILFunction &F, SILOpenedArchetypesState &OpenedArchetypes,
25662589
const GenericSpecializationInformation *SpecializationInfo);
2567-
2568-
public:
2569-
/// Returns true if the called function has an error result but is not actually
2570-
/// throwing an error.
2571-
bool isNonThrowing() const {
2572-
return isNonThrowingApply();
2573-
}
25742590
};
25752591

25762592
/// PartialApplyInst - Represents the creation of a closure object by partial
@@ -2670,13 +2686,13 @@ class BeginApplyInst final
26702686
SubstitutionMap substitutions,
26712687
ArrayRef<SILValue> args,
26722688
ArrayRef<SILValue> typeDependentOperands,
2673-
bool isNonThrowing,
2689+
ApplyOptions options,
26742690
const GenericSpecializationInformation *specializationInfo);
26752691

26762692
static BeginApplyInst *
26772693
create(SILDebugLocation debugLoc, SILValue Callee,
26782694
SubstitutionMap substitutions, ArrayRef<SILValue> args,
2679-
bool isNonThrowing, Optional<SILModuleConventions> moduleConventions,
2695+
ApplyOptions options, Optional<SILModuleConventions> moduleConventions,
26802696
SILFunction &F, SILOpenedArchetypesState &openedArchetypes,
26812697
const GenericSpecializationInformation *specializationInfo);
26822698

@@ -2691,12 +2707,6 @@ class BeginApplyInst final
26912707
return getAllResultsBuffer().drop_back();
26922708
}
26932709

2694-
/// Returns true if the called coroutine has an error result but is not
2695-
/// actually throwing an error.
2696-
bool isNonThrowing() const {
2697-
return isNonThrowingApply();
2698-
}
2699-
27002710
void getCoroutineEndPoints(
27012711
SmallVectorImpl<EndApplyInst *> &endApplyInsts,
27022712
SmallVectorImpl<AbortApplyInst *> &abortApplyInsts) const;
@@ -8903,14 +8913,18 @@ class TryApplyInst final
89038913
ArrayRef<SILValue> args,
89048914
ArrayRef<SILValue> TypeDependentOperands,
89058915
SILBasicBlock *normalBB, SILBasicBlock *errorBB,
8916+
ApplyOptions options,
89068917
const GenericSpecializationInformation *SpecializationInfo);
89078918

89088919
static TryApplyInst *
89098920
create(SILDebugLocation DebugLoc, SILValue callee,
89108921
SubstitutionMap substitutions, ArrayRef<SILValue> args,
8911-
SILBasicBlock *normalBB, SILBasicBlock *errorBB, SILFunction &F,
8922+
SILBasicBlock *normalBB, SILBasicBlock *errorBB,
8923+
ApplyOptions options, SILFunction &F,
89128924
SILOpenedArchetypesState &OpenedArchetypes,
89138925
const GenericSpecializationInformation *SpecializationInfo);
8926+
8927+
89148928
};
89158929

89168930
/// DifferentiableFunctionInst - creates a `@differentiable` function-typed

include/swift/SIL/TypeSubstCloner.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
213213
ApplyInst *N =
214214
getBuilder().createApply(getOpLocation(Inst->getLoc()),
215215
Helper.getCallee(), Helper.getSubstitutions(),
216-
Helper.getArguments(), Inst->isNonThrowing(),
216+
Helper.getArguments(),
217+
Inst->getApplyOptions(),
217218
GenericSpecializationInformation::create(
218219
Inst, getBuilder()));
219220
// Specialization can return noreturn applies that were not identified as
@@ -233,6 +234,7 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
233234
Helper.getSubstitutions(), Helper.getArguments(),
234235
getOpBasicBlock(Inst->getNormalBB()),
235236
getOpBasicBlock(Inst->getErrorBB()),
237+
Inst->getApplyOptions(),
236238
GenericSpecializationInformation::create(
237239
Inst, getBuilder()));
238240
recordClonedInstruction(Inst, N);

lib/IRGen/LoadableByAddress.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2530,7 +2530,8 @@ void LoadableByAddress::recreateSingleApply(
25302530
SILValue newApply =
25312531
applyBuilder.createApply(castedApply->getLoc(), callee,
25322532
applySite.getSubstitutionMap(),
2533-
callArgs, castedApply->isNonThrowing());
2533+
callArgs,
2534+
castedApply->getApplyOptions());
25342535
castedApply->replaceAllUsesWith(newApply);
25352536
break;
25362537
}
@@ -2547,7 +2548,7 @@ void LoadableByAddress::recreateSingleApply(
25472548
auto newApply =
25482549
applyBuilder.createBeginApply(oldApply->getLoc(), callee,
25492550
applySite.getSubstitutionMap(), callArgs,
2550-
oldApply->isNonThrowing());
2551+
oldApply->getApplyOptions());
25512552

25522553
// Use the new token result.
25532554
oldApply->getTokenResult()->replaceAllUsesWith(newApply->getTokenResult());

0 commit comments

Comments
 (0)