Skip to content

Commit 61e8585

Browse files
authored
Merge pull request #67040 from rjmccall/variadic-tuple-result-reabstraction-thunks
Handle variadic tuples in reabstraction thunk emission
2 parents 227c6a8 + c0777e6 commit 61e8585

23 files changed

+2271
-372
lines changed

SwiftCompilerSources/Sources/SIL/Argument.swift

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,17 @@ public enum ArgumentConvention {
141141
/// indirectly is recorded in the pack type.
142142
case packGuaranteed
143143

144+
/// This argument is a pack of indirect return value addresses. The
145+
/// addresses are stored in the pack by the caller and read out by the
146+
/// callee; within the callee, they are individually treated like
147+
/// indirectOut arguments.
148+
case packOut
149+
144150
public var isIndirect: Bool {
145151
switch self {
146152
case .indirectIn, .indirectInGuaranteed,
147153
.indirectInout, .indirectInoutAliasable, .indirectOut,
148-
.packInout, .packOwned, .packGuaranteed:
154+
.packOut, .packInout, .packOwned, .packGuaranteed:
149155
return true
150156
case .directOwned, .directUnowned, .directGuaranteed:
151157
return false
@@ -159,7 +165,19 @@ public enum ArgumentConvention {
159165
return true
160166
case .directOwned, .directUnowned, .directGuaranteed,
161167
.indirectInout, .indirectInoutAliasable, .indirectOut,
162-
.packInout:
168+
.packOut, .packInout:
169+
return false
170+
}
171+
}
172+
173+
public var isIndirectOut: Bool {
174+
switch self {
175+
case .indirectOut, .packOut:
176+
return true
177+
case .indirectInGuaranteed, .directGuaranteed, .packGuaranteed,
178+
.indirectIn, .directOwned, .directUnowned,
179+
.indirectInout, .indirectInoutAliasable,
180+
.packInout, .packOwned:
163181
return false
164182
}
165183
}
@@ -170,7 +188,7 @@ public enum ArgumentConvention {
170188
return true
171189
case .indirectIn, .directOwned, .directUnowned,
172190
.indirectInout, .indirectInoutAliasable, .indirectOut,
173-
.packInout, .packOwned:
191+
.packOut, .packInout, .packOwned:
174192
return false
175193
}
176194
}
@@ -181,6 +199,7 @@ public enum ArgumentConvention {
181199
.indirectOut,
182200
.indirectInGuaranteed,
183201
.indirectInout,
202+
.packOut,
184203
.packInout,
185204
.packOwned,
186205
.packGuaranteed:
@@ -207,6 +226,7 @@ public enum ArgumentConvention {
207226
.directUnowned,
208227
.directGuaranteed,
209228
.directOwned,
229+
.packOut,
210230
.packOwned,
211231
.packGuaranteed:
212232
return false
@@ -233,6 +253,7 @@ extension BridgedArgumentConvention {
233253
case .Direct_Owned: return .directOwned
234254
case .Direct_Unowned: return .directUnowned
235255
case .Direct_Guaranteed: return .directGuaranteed
256+
case .Pack_Out: return .packOut
236257
case .Pack_Inout: return .packInout
237258
case .Pack_Owned: return .packOwned
238259
case .Pack_Guaranteed: return .packGuaranteed

SwiftCompilerSources/Sources/SIL/Effects.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ extension Function {
143143
if convention.isIndirectIn {
144144
// Even a `[readnone]` function can read from an indirect argument.
145145
result.memory.read = true
146-
} else if convention == .indirectOut {
146+
} else if convention.isIndirectOut {
147147
// Even `[readnone]` and `[readonly]` functions write to indirect results.
148148
result.memory.write = true
149149
}
@@ -546,7 +546,7 @@ public struct SideEffects : CustomStringConvertible, NoReflectionChildren {
546546
case .indirectInGuaranteed, .packGuaranteed:
547547
result.memory.write = false
548548
result.ownership.destroy = false
549-
case .indirectOut, .packInout:
549+
case .indirectOut, .packOut, .packInout:
550550
result.memory.read = false
551551
result.ownership.copy = false
552552
result.ownership.destroy = false

SwiftCompilerSources/Sources/SIL/Function.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,6 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
8585
public var resultType: Type { bridged.getSILResultType().type }
8686

8787
public func getArgumentConvention(for argumentIndex: Int) -> ArgumentConvention {
88-
if argumentIndex < numIndirectResultArguments {
89-
return .indirectOut
90-
}
9188
return bridged.getSILArgumentConvention(argumentIndex).convention
9289
}
9390

include/swift/Basic/Generators.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ class ArrayRefGenerator {
146146
}
147147
};
148148

149+
namespace generator_details {
150+
template <class T> struct is_simple_generator_ref;
151+
}
152+
149153
/// An abstracting reference to an existing generator.
150154
///
151155
/// The implementation of this type holds the reference to the existing
@@ -182,7 +186,8 @@ class SimpleGeneratorRef {
182186
constexpr SimpleGeneratorRef() : vtable(nullptr), pointer(nullptr) {}
183187

184188
template <class G>
185-
constexpr SimpleGeneratorRef(G &generator)
189+
constexpr SimpleGeneratorRef(G &generator,
190+
typename std::enable_if<!generator_details::is_simple_generator_ref<G>::value, bool>::type = false)
186191
: vtable(&VTableImpl<G>::vtable), pointer(&generator) {}
187192

188193
/// Test whether this generator ref was initialized with a
@@ -212,6 +217,19 @@ class SimpleGeneratorRef {
212217
}
213218
};
214219

220+
namespace generator_details {
221+
222+
template <class T>
223+
struct is_simple_generator_ref<SimpleGeneratorRef<T>> {
224+
static constexpr bool value = true;
225+
};
226+
template <class T>
227+
struct is_simple_generator_ref {
228+
static constexpr bool value = false;
229+
};
230+
231+
}
232+
215233
} // end namespace swift
216234

217235
#endif

include/swift/SIL/AbstractionPattern.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,10 @@ class AbstractionPattern {
13541354
llvm::Optional<AbstractionPattern>
13551355
getVanishingTupleElementPatternType() const;
13561356

1357+
/// Does this tuple type vanish, i.e. is it flattened to a singleton
1358+
/// non-expansion element under substitution?
1359+
bool doesTupleVanish() const;
1360+
13571361
static AbstractionPattern
13581362
projectTupleElementType(const AbstractionPattern *base, size_t index) {
13591363
return base->getTupleElementType(index);

include/swift/SIL/AbstractionPatternGenerators.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,11 @@ class TupleElementGenerator {
224224
return origEltIndex == numOrigElts;
225225
}
226226

227+
/// Does the entire original tuple vanish?
228+
bool doesOrigTupleVanish() const {
229+
return origTupleVanishes;
230+
}
231+
227232
/// Advance to the next orig element.
228233
void advance() {
229234
assert(!isFinished());

include/swift/SIL/SILArgument.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,6 @@ class SILPhiArgument;
2828
class SILUndef;
2929
class TermInst;
3030

31-
// Map an argument index onto a SILArgumentConvention.
32-
inline SILArgumentConvention
33-
SILFunctionConventions::getSILArgumentConvention(unsigned index) const {
34-
assert(index <= getNumSILArguments());
35-
if (index < getNumIndirectSILResults()) {
36-
assert(silConv.loweredAddresses);
37-
return SILArgumentConvention::Indirect_Out;
38-
} else {
39-
auto param = funcTy->getParameters()[index - getNumIndirectSILResults()];
40-
return SILArgumentConvention(param.getConvention());
41-
}
42-
}
43-
4431
struct SILArgumentKind {
4532
enum innerty : std::underlying_type<ValueKind>::type {
4633
#define ARGUMENT(ID, PARENT) ID = unsigned(SILNodeKind::ID),

include/swift/SIL/SILArgumentConvention.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,28 @@ struct SILArgumentConvention {
164164
}
165165
llvm_unreachable("covered switch isn't covered?!");
166166
}
167+
168+
/// Returns true if \p Value is an indirect-out parameter.
169+
bool isIndirectOutParameter() {
170+
switch (Value) {
171+
case SILArgumentConvention::Indirect_Out:
172+
case SILArgumentConvention::Pack_Out:
173+
return true;
174+
175+
case SILArgumentConvention::Indirect_In:
176+
case SILArgumentConvention::Indirect_In_Guaranteed:
177+
case SILArgumentConvention::Indirect_Inout:
178+
case SILArgumentConvention::Indirect_InoutAliasable:
179+
case SILArgumentConvention::Direct_Unowned:
180+
case SILArgumentConvention::Direct_Guaranteed:
181+
case SILArgumentConvention::Direct_Owned:
182+
case SILArgumentConvention::Pack_Inout:
183+
case SILArgumentConvention::Pack_Owned:
184+
case SILArgumentConvention::Pack_Guaranteed:
185+
return false;
186+
}
187+
llvm_unreachable("covered switch isn't covered?!");
188+
}
167189
};
168190

169191
} // namespace swift

include/swift/SIL/SILBridging.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ struct BridgedFunction {
219219

220220
BridgedArgumentConvention getSILArgumentConvention(SwiftInt idx) const {
221221
swift::SILFunctionConventions conv(getFunction()->getConventionsInContext());
222-
return castToArgumentConvention(swift::SILArgumentConvention(conv.getParamInfoForSILArg(idx).getConvention()));
222+
return castToArgumentConvention(conv.getSILArgumentConvention(idx));
223223
}
224224

225225
swift::SILType getSILResultType() const {

include/swift/SIL/SILFunctionConventions.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,6 @@ class SILFunctionConventions {
409409
/// Return the SIL argument convention of apply/entry argument at
410410
/// the given argument index.
411411
SILArgumentConvention getSILArgumentConvention(unsigned index) const;
412-
// See SILArgument.h.
413412

414413
/// Return the SIL type of the apply/entry argument at the given index.
415414
SILType getSILArgumentType(unsigned index,

0 commit comments

Comments
 (0)