Skip to content

Commit c8465f1

Browse files
authored
Merge pull request swiftlang#28137 from ravikandhadai/constexpr-closure-subst-map
2 parents f519505 + 957dc8e commit c8465f1

File tree

3 files changed

+38
-9
lines changed

3 files changed

+38
-9
lines changed

include/swift/SIL/SILConstants.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818
#ifndef SWIFT_SIL_CONSTANTS_H
1919
#define SWIFT_SIL_CONSTANTS_H
2020

21+
#include "swift/AST/SubstitutionMap.h"
2122
#include "swift/SIL/SILValue.h"
2223
#include "llvm/Support/CommandLine.h"
2324

24-
2525
namespace swift {
2626
class SingleValueInstruction;
2727
class SILValue;
@@ -572,6 +572,7 @@ class SymbolicValue {
572572
static SymbolicValue makeClosure(
573573
SILFunction *target,
574574
ArrayRef<std::pair<SILValue, Optional<SymbolicValue>>> capturedArguments,
575+
SubstitutionMap substMap, SILType closureType,
575576
SymbolicValueAllocator &allocator);
576577

577578
SymbolicClosure *getClosure() const {
@@ -680,19 +681,29 @@ struct SymbolicClosure final
680681
// The number of SIL values captured by the closure.
681682
unsigned numCaptures;
682683

683-
// True iff there exists captured arguments whose constant value is not known.
684+
// True iff there exists a captured argument whose constant value is not
685+
// known.
684686
bool hasNonConstantCaptures = true;
685687

688+
// A substitution map that partially maps the generic paramters of the
689+
// applied function to the generic arguments of passed to the call.
690+
SubstitutionMap substitutionMap;
691+
692+
SILType closureType;
693+
686694
SymbolicClosure() = delete;
687695
SymbolicClosure(const SymbolicClosure &) = delete;
688696
SymbolicClosure(SILFunction *callee, unsigned numArguments,
697+
SubstitutionMap substMap, SILType closureType,
689698
bool nonConstantCaptures)
690699
: target(callee), numCaptures(numArguments),
691-
hasNonConstantCaptures(nonConstantCaptures) {}
700+
hasNonConstantCaptures(nonConstantCaptures), substitutionMap(substMap),
701+
closureType(closureType) {}
692702

693703
public:
694704
static SymbolicClosure *create(SILFunction *callee,
695705
ArrayRef<SymbolicClosureArgument> args,
706+
SubstitutionMap substMap, SILType closureType,
696707
SymbolicValueAllocator &allocator);
697708

698709
ArrayRef<SymbolicClosureArgument> getCaptures() const {
@@ -707,6 +718,10 @@ struct SymbolicClosure final
707718
SILFunction *getTarget() {
708719
return target;
709720
}
721+
722+
SILType getClosureType() { return closureType; }
723+
724+
SubstitutionMap getCallSubstitutionMap() { return substitutionMap; }
710725
};
711726

712727
} // end namespace swift

lib/SIL/SILConstants.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,9 @@ SymbolicValue::cloneInto(SymbolicValueAllocator &allocator) const {
247247
case RK_Closure: {
248248
SymbolicClosure *clo = getClosure();
249249
ArrayRef<SymbolicClosureArgument> closureArgs = clo->getCaptures();
250-
return SymbolicValue::makeClosure(clo->getTarget(), closureArgs, allocator);
250+
return SymbolicValue::makeClosure(clo->getTarget(), closureArgs,
251+
clo->getCallSubstitutionMap(),
252+
clo->getClosureType(), allocator);
251253
}
252254
}
253255
llvm_unreachable("covered switch");
@@ -744,8 +746,11 @@ Type SymbolicValue::getArrayType() const {
744746

745747
SymbolicValue SymbolicValue::makeClosure(SILFunction *target,
746748
ArrayRef<SymbolicClosureArgument> args,
749+
SubstitutionMap substMap,
750+
SILType closureType,
747751
SymbolicValueAllocator &allocator) {
748-
auto clo = SymbolicClosure::create(target, args, allocator);
752+
auto clo =
753+
SymbolicClosure::create(target, args, substMap, closureType, allocator);
749754
SymbolicValue result;
750755
result.representationKind = RK_Closure;
751756
result.value.closure = clo;
@@ -754,6 +759,8 @@ SymbolicValue SymbolicValue::makeClosure(SILFunction *target,
754759

755760
SymbolicClosure *SymbolicClosure::create(SILFunction *target,
756761
ArrayRef<SymbolicClosureArgument> args,
762+
SubstitutionMap substMap,
763+
SILType closureType,
757764
SymbolicValueAllocator &allocator) {
758765
// Determine whether there are captured arguments without a symbolic value.
759766
bool hasNonConstantCapture = false;
@@ -768,8 +775,8 @@ SymbolicClosure *SymbolicClosure::create(SILFunction *target,
768775
SymbolicClosure::totalSizeToAlloc<SymbolicClosureArgument>(args.size());
769776
auto rawMem = allocator.allocate(byteSizeOfArgs, alignof(SymbolicClosure));
770777
// Placement initialize the object.
771-
auto closure = ::new (rawMem)
772-
SymbolicClosure(target, args.size(), hasNonConstantCapture);
778+
auto closure = ::new (rawMem) SymbolicClosure(
779+
target, args.size(), substMap, closureType, hasNonConstantCapture);
773780
std::uninitialized_copy(
774781
args.begin(), args.end(),
775782
closure->getTrailingObjects<SymbolicClosureArgument>());

lib/SILOptimizer/Utils/ConstExpr.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,6 +1590,10 @@ llvm::Optional<SymbolicValue> ConstExprFunctionState::evaluateClosureCreation(
15901590

15911591
SmallVector<SymbolicClosureArgument, 4> captures;
15921592

1593+
// Map generic parameters of the target to the generic arguments passed to the
1594+
// call.
1595+
SubstitutionMap callSubstMap;
1596+
15931597
// If this is a partial-apply instruction, arguments to this partial-apply
15941598
// instruction are the captures of the closure.
15951599
if (PartialApplyInst *papply = dyn_cast<PartialApplyInst>(closureInst)) {
@@ -1601,10 +1605,13 @@ llvm::Optional<SymbolicValue> ConstExprFunctionState::evaluateClosureCreation(
16011605
}
16021606
captures.push_back({capturedSILValue, capturedSymbolicValue});
16031607
}
1608+
callSubstMap = papply->getSubstitutionMap().subst(this->substitutionMap);
16041609
}
16051610

1606-
auto closureVal =
1607-
SymbolicValue::makeClosure(target, captures, evaluator.getAllocator());
1611+
SILType closureType = closureInst->getType();
1612+
assert(closureType.is<SILFunctionType>());
1613+
auto closureVal = SymbolicValue::makeClosure(
1614+
target, captures, callSubstMap, closureType, evaluator.getAllocator());
16081615
setValue(closureInst, closureVal);
16091616
return None;
16101617
}

0 commit comments

Comments
 (0)