Skip to content

Commit

Permalink
[IRGen] Pull async polymorphic params from explosion.
Browse files Browse the repository at this point in the history
Previously, the polymorphic arguments were being discarded.  Here, that
situation is improved by pulling the polymorphic arguments out of the
explosion when having the polymorphic parameters via the
NecessaryBindings instance.  In order to eanble that, an overload of
NecessaryBindings::save is added which takes an explosion and asserts
that the polymorphic parameter pulled from the explosion matches with
the polymorphic parameter in the NecessaryBindings instance.
  • Loading branch information
nate-chandler committed Oct 6, 2020
1 parent d2fc2c1 commit 15d90d8
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 23 deletions.
15 changes: 9 additions & 6 deletions lib/IRGen/GenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1989,13 +1989,16 @@ class AsyncCallEmission final : public CallEmission {
if (layout.hasBindings()) {
auto bindingLayout = layout.getBindingsLayout();
auto bindingsAddr = bindingLayout.project(IGF, context, /*offsets*/ None);
layout.getBindings().save(IGF, bindingsAddr);
layout.getBindings().save(IGF, bindingsAddr, llArgs);
}
// At this point, llArgs contains the arguments that are being passed along
// via the async context. We can safely drop them on the floor.
(void)llArgs.claimAll();
// TODO: Validation: we should be able to check that the contents of llArgs
// matches what is expected by the layout.
if (selfValue) {
auto fieldLayout = layout.getLocalContextLayout();
Address fieldAddr =
fieldLayout.project(IGF, context, /*offsets*/ llvm::None);
auto &ti = cast<LoadableTypeInfo>(fieldLayout.getType());
ti.initialize(IGF, llArgs, fieldAddr, isOutlined);
}
}
}
void emitCallToUnmappedExplosion(llvm::CallInst *call, Explosion &out) override {
SILFunctionConventions fnConv(getCallee().getSubstFunctionType(),
Expand Down
55 changes: 38 additions & 17 deletions lib/IRGen/GenProto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2728,24 +2728,45 @@ void NecessaryBindings::restore(IRGenFunction &IGF, Address buffer,
[&](CanType type) { return type;});
}

template <typename Transform>
static void save(const NecessaryBindings &bindings, IRGenFunction &IGF,
Address buffer, Transform transform) {
emitInitOfGenericRequirementsBuffer(
IGF, bindings.getRequirements().getArrayRef(), buffer,
[&](GenericRequirement requirement) -> llvm::Value * {
CanType type = requirement.TypeParameter;
if (auto protocol = requirement.Protocol) {
if (auto archetype = dyn_cast<ArchetypeType>(type)) {
auto wtable =
emitArchetypeWitnessTableRef(IGF, archetype, protocol);
return transform(requirement, wtable);
} else {
auto conformance = bindings.getConformance(requirement);
auto wtable = emitWitnessTableRef(IGF, type, conformance);
return transform(requirement, wtable);
}
} else {
auto metadata = IGF.emitTypeMetadataRef(type);
return transform(requirement, metadata);
}
});
};

void NecessaryBindings::save(IRGenFunction &IGF, Address buffer,
Explosion &source) const {
::save(*this, IGF, buffer,
[&](GenericRequirement requirement,
llvm::Value *expected) -> llvm::Value * {
auto *value = source.claimNext();
assert(value == expected);
return value;
});
}

void NecessaryBindings::save(IRGenFunction &IGF, Address buffer) const {
emitInitOfGenericRequirementsBuffer(IGF, Requirements.getArrayRef(), buffer,
[&](GenericRequirement requirement) -> llvm::Value* {
CanType type = requirement.TypeParameter;
if (auto protocol = requirement.Protocol) {
if (auto archetype = dyn_cast<ArchetypeType>(type)) {
auto wtable = emitArchetypeWitnessTableRef(IGF, archetype, protocol);
return wtable;
} else {
auto conformance = getConformance(requirement);
auto wtable = emitWitnessTableRef(IGF, type, conformance);
return wtable;
}
} else {
auto metadata = IGF.emitTypeMetadataRef(type);
return metadata;
}
});
::save(*this, IGF, buffer,
[](GenericRequirement requirement,
llvm::Value *value) -> llvm::Value * { return value; });
}

void NecessaryBindings::addTypeMetadata(CanType type) {
Expand Down
4 changes: 4 additions & 0 deletions lib/IRGen/NecessaryBindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "llvm/ADT/SetVector.h"
#include "swift/AST/Types.h"

#include "Explosion.h"

namespace swift {
class CanType;
enum class MetadataState : size_t;
Expand Down Expand Up @@ -94,6 +96,8 @@ class NecessaryBindings {
/// Save the necessary bindings to the given buffer.
void save(IRGenFunction &IGF, Address buffer) const;

void save(IRGenFunction &IGF, Address buffer, Explosion &source) const;

/// Restore the necessary bindings from the given buffer.
void restore(IRGenFunction &IGF, Address buffer, MetadataState state) const;

Expand Down

0 comments on commit 15d90d8

Please sign in to comment.