Skip to content

Commit cc5bea1

Browse files
committed
Fix some SILArgument infrastructure for pack results.
Getting this right convinces the memory verifier to not complain about untouched empty pack result arguments, which should be innocuous.
1 parent cc5854b commit cc5bea1

File tree

6 files changed

+84
-21
lines changed

6 files changed

+84
-21
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/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

lib/SIL/IR/SILArgument.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,42 @@ SILParameterInfo SILFunctionArgument::getKnownParameterInfo() const {
7575
return getFunction()->getConventions().getParamInfoForSILArg(getIndex());
7676
}
7777

78+
SILArgumentConvention
79+
SILFunctionConventions::getSILArgumentConvention(unsigned index) const {
80+
assert(index < getNumSILArguments());
81+
82+
// If the argument is a parameter, index into the parameters.
83+
if (index >= getNumIndirectSILResults()) {
84+
auto param = funcTy->getParameters()[index - getNumIndirectSILResults()];
85+
return SILArgumentConvention(param.getConvention());
86+
}
87+
88+
// If it's an indirect result, it could be either Pack_Out or
89+
// Indirect_Out.
90+
91+
// Handle the common case of a function with no pack results.
92+
if (funcTy->getNumPackResults() == 0) {
93+
assert(silConv.loweredAddresses);
94+
return SILArgumentConvention::Indirect_Out;
95+
}
96+
97+
// Otherwise, we need to index into the indirect results to figure out
98+
// whether the result is a pack or not, and unfortunately that is not a
99+
// linear algorithm.
100+
for (auto result : getIndirectSILResults()) {
101+
if (index == 0) {
102+
if (result.getConvention() == ResultConvention::Indirect) {
103+
assert(silConv.loweredAddresses);
104+
return SILArgumentConvention::Indirect_Out;
105+
} else {
106+
assert(result.getConvention() == ResultConvention::Pack);
107+
return SILArgumentConvention::Pack_Out;
108+
}
109+
}
110+
index--;
111+
}
112+
llvm_unreachable("mismatch with getNumIndirectSILResults()?");
113+
}
78114

79115
//===----------------------------------------------------------------------===//
80116
// SILBlockArgument

0 commit comments

Comments
 (0)