Skip to content

Commit 9afe41b

Browse files
authored
Merge pull request #8073 from gottesmm/splitting_arg_scopes_and_indirect_result_scopes
2 parents 4cf0389 + 213ddd7 commit 9afe41b

15 files changed

+295
-155
lines changed

lib/SILGen/Callee.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//===--- Callee.h ---------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 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_SILGEN_CALLEE_H
14+
#define SWIFT_SILGEN_CALLEE_H
15+
16+
#include "swift/AST/ForeignErrorConvention.h"
17+
#include "swift/AST/Types.h"
18+
#include "swift/SIL/AbstractionPattern.h"
19+
20+
namespace swift {
21+
namespace Lowering {
22+
23+
class CalleeTypeInfo {
24+
public:
25+
CanSILFunctionType substFnType;
26+
AbstractionPattern origResultType;
27+
CanType substResultType;
28+
Optional<ForeignErrorConvention> foreignError;
29+
30+
private:
31+
Optional<SILFunctionTypeRepresentation> overrideRep;
32+
33+
public:
34+
CalleeTypeInfo(CanSILFunctionType substFnType,
35+
AbstractionPattern origResultType, CanType substResultType,
36+
const Optional<ForeignErrorConvention> &foreignError,
37+
Optional<SILFunctionTypeRepresentation> overrideRep = None)
38+
: substFnType(substFnType), origResultType(origResultType),
39+
substResultType(substResultType), foreignError(foreignError),
40+
overrideRep(overrideRep) {}
41+
42+
CalleeTypeInfo(CanSILFunctionType substFnType,
43+
AbstractionPattern origResultType, CanType substResultType,
44+
Optional<SILFunctionTypeRepresentation> overrideRep = None)
45+
: substFnType(substFnType), origResultType(origResultType),
46+
substResultType(substResultType), foreignError(),
47+
overrideRep(overrideRep) {}
48+
49+
SILFunctionTypeRepresentation getOverrideRep() const {
50+
return overrideRep.getValueOr(substFnType->getRepresentation());
51+
}
52+
};
53+
54+
} // namespace Lowering
55+
} // namespace swift
56+
57+
#endif

lib/SILGen/ResultPlan.cpp

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "ResultPlan.h"
14+
#include "Callee.h"
1415
#include "Initialization.h"
1516
#include "RValue.h"
1617
#include "SILGenFunction.h"
@@ -37,6 +38,10 @@ class InPlaceInitializationResultPlan : public ResultPlan {
3738
init->finishInitialization(SGF);
3839
return RValue();
3940
}
41+
void
42+
gatherIndirectResultAddrs(SmallVectorImpl<SILValue> &outList) const override {
43+
outList.emplace_back(init->getAddressForInPlaceInitialization());
44+
}
4045
};
4146

4247
/// A result plan for working with a single value and potentially
@@ -114,6 +119,13 @@ class ScalarResultPlan : public ResultPlan {
114119
return RValue(SGF, loc, substType, value);
115120
}
116121
}
122+
123+
void
124+
gatherIndirectResultAddrs(SmallVectorImpl<SILValue> &outList) const override {
125+
if (!temporary)
126+
return;
127+
outList.emplace_back(temporary->getAddress());
128+
}
117129
};
118130

119131
/// A result plan which calls copyOrInitValueInto on an Initialization
@@ -142,6 +154,11 @@ class InitValueFromTemporaryResultPlan : public ResultPlan {
142154

143155
return RValue();
144156
}
157+
158+
void
159+
gatherIndirectResultAddrs(SmallVectorImpl<SILValue> &outList) const override {
160+
subPlan->gatherIndirectResultAddrs(outList);
161+
}
145162
};
146163

147164
/// A result plan which calls copyOrInitValueInto using the result of
@@ -164,6 +181,11 @@ class InitValueFromRValueResultPlan : public ResultPlan {
164181

165182
return RValue();
166183
}
184+
185+
void
186+
gatherIndirectResultAddrs(SmallVectorImpl<SILValue> &outList) const override {
187+
subPlan->gatherIndirectResultAddrs(outList);
188+
}
167189
};
168190

169191
/// A result plan which produces a larger RValue from a bunch of
@@ -198,6 +220,13 @@ class TupleRValueResultPlan : public ResultPlan {
198220

199221
return tupleRV;
200222
}
223+
224+
void
225+
gatherIndirectResultAddrs(SmallVectorImpl<SILValue> &outList) const override {
226+
for (const auto &eltPlan : eltPlans) {
227+
eltPlan->gatherIndirectResultAddrs(outList);
228+
}
229+
}
201230
};
202231

203232
/// A result plan which evaluates into the sub-components
@@ -243,6 +272,13 @@ class TupleInitializationResultPlan : public ResultPlan {
243272

244273
return RValue();
245274
}
275+
276+
void
277+
gatherIndirectResultAddrs(SmallVectorImpl<SILValue> &outList) const override {
278+
for (const auto &eltPlan : eltPlans) {
279+
eltPlan->gatherIndirectResultAddrs(outList);
280+
}
281+
}
246282
};
247283

248284
} // end anonymous namespace
@@ -275,7 +311,6 @@ ResultPlanPtr ResultPlanBuilder::build(Initialization *init,
275311
if (initAddr && SGF.silConv.isSILIndirect(result) &&
276312
!initAddr->getType().hasAbstractionDifference(
277313
rep, result.getSILStorageType())) {
278-
indirectResultAddrs.push_back(initAddr);
279314
return ResultPlanPtr(new InPlaceInitializationResultPlan(init));
280315
}
281316
}
@@ -292,7 +327,6 @@ ResultPlanPtr ResultPlanBuilder::build(Initialization *init,
292327
if (SGF.silConv.isSILIndirect(result)) {
293328
auto &resultTL = SGF.getTypeLowering(result.getType());
294329
temporary = SGF.emitTemporary(loc, resultTL);
295-
indirectResultAddrs.push_back(temporary->getAddress());
296330
}
297331

298332
return ResultPlanPtr(
@@ -341,3 +375,46 @@ ResultPlanPtr ResultPlanBuilder::buildForTuple(Initialization *init,
341375
return ResultPlanPtr(
342376
new InitValueFromRValueResultPlan(init, std::move(subplan)));
343377
}
378+
379+
ResultPlanPtr
380+
ResultPlanBuilder::computeResultPlan(SILGenFunction &SGF,
381+
CalleeTypeInfo &calleeTypeInfo,
382+
SILLocation loc, SGFContext evalContext) {
383+
auto origResultTypeForPlan = calleeTypeInfo.origResultType;
384+
auto substResultTypeForPlan = calleeTypeInfo.substResultType;
385+
ArrayRef<SILResultInfo> allResults = calleeTypeInfo.substFnType->getResults();
386+
SILResultInfo optResult;
387+
388+
// The plan needs to be built using the formal result type
389+
// after foreign-error adjustment.
390+
if (auto foreignError = calleeTypeInfo.foreignError) {
391+
switch (foreignError->getKind()) {
392+
// These conventions make the formal result type ().
393+
case ForeignErrorConvention::ZeroResult:
394+
case ForeignErrorConvention::NonZeroResult:
395+
assert(calleeTypeInfo.substResultType->isVoid());
396+
allResults = {};
397+
break;
398+
399+
// These conventions leave the formal result alone.
400+
case ForeignErrorConvention::ZeroPreservedResult:
401+
case ForeignErrorConvention::NonNilError:
402+
break;
403+
404+
// This convention changes the formal result to the optional object
405+
// type; we need to make our own make SILResultInfo array.
406+
case ForeignErrorConvention::NilResult: {
407+
assert(allResults.size() == 1);
408+
CanType objectType = allResults[0].getType().getAnyOptionalObjectType();
409+
optResult = allResults[0].getWithType(objectType);
410+
allResults = optResult;
411+
break;
412+
}
413+
}
414+
}
415+
416+
ResultPlanBuilder builder(SGF, loc, allResults,
417+
calleeTypeInfo.getOverrideRep());
418+
return builder.build(evalContext.getEmitInto(), origResultTypeForPlan,
419+
substResultTypeForPlan);
420+
}

lib/SILGen/ResultPlan.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,18 @@ class Initialization;
3030
class ManagedValue;
3131
class RValue;
3232
class SILGenFunction;
33+
class SGFContext;
34+
class CalleeTypeInfo;
3335

3436
/// An abstract class for working with results.of applies.
3537
class ResultPlan {
3638
public:
3739
virtual RValue finish(SILGenFunction &SGF, SILLocation loc, CanType substType,
3840
ArrayRef<ManagedValue> &directResults) = 0;
3941
virtual ~ResultPlan() = default;
42+
43+
virtual void
44+
gatherIndirectResultAddrs(SmallVectorImpl<SILValue> &outList) const = 0;
4045
};
4146

4247
using ResultPlanPtr = std::unique_ptr<ResultPlan>;
@@ -47,21 +52,23 @@ struct ResultPlanBuilder {
4752
SILLocation loc;
4853
ArrayRef<SILResultInfo> allResults;
4954
SILFunctionTypeRepresentation rep;
50-
SmallVectorImpl<SILValue> &indirectResultAddrs;
5155

5256
ResultPlanBuilder(SILGenFunction &SGF, SILLocation loc,
5357
ArrayRef<SILResultInfo> allResults,
54-
SILFunctionTypeRepresentation rep,
55-
SmallVectorImpl<SILValue> &resultAddrs)
56-
: SGF(SGF), loc(loc), allResults(allResults), rep(rep),
57-
indirectResultAddrs(resultAddrs) {}
58+
SILFunctionTypeRepresentation rep)
59+
: SGF(SGF), loc(loc), allResults(allResults), rep(rep) {}
5860

5961
ResultPlanPtr build(Initialization *emitInto, AbstractionPattern origType,
6062
CanType substType);
6163
ResultPlanPtr buildForTuple(Initialization *emitInto,
6264
AbstractionPattern origType,
6365
CanTupleType substType);
6466

67+
static ResultPlanPtr computeResultPlan(SILGenFunction &SGF,
68+
CalleeTypeInfo &calleeTypeInfo,
69+
SILLocation loc,
70+
SGFContext evalContext);
71+
6572
~ResultPlanBuilder() {
6673
assert(allResults.empty() && "didn't consume all results!");
6774
}

0 commit comments

Comments
 (0)