Skip to content

Commit d28445c

Browse files
committed
Make SILArgumentConvention a "method"-enum.
This means using a struct so we can put methods on the struct and using an anonymous enum to create namespaced values. Specifically: struct SILArgumentConvention { enum : uint8_t { Indirect_In, Indirect_In_Guaranteed, Indirect_Inout, Indirect_InoutAliasable, Indirect_Out, Direct_Owned, Direct_Unowned, Direct_Deallocating, Direct_Guaranteed, } Value; SILArgumentConvention(decltype(Value) NewValue) : Value(NewValue) {} operator decltype(Value)() const { return Value; } ParameterConvention getParameterConvention() const { switch (Value) { ... } } bool isIndirectConvention() const { ... } }; This allows for: 1. Avoiding abstraction leakage via the enum type. If someone wants to use decltype as well, I think that is enough work that the leakage is acceptable. 2. Still refer to enum cases like we are working with an enum class (e.g. SILArgumentConvention::Direct_Owned). 3. Avoid using the anonymous type in function arguments due to an implicit conversion. 4. And most importantly... *drum roll* add methods to our enums!
1 parent 3e00d00 commit d28445c

File tree

8 files changed

+136
-97
lines changed

8 files changed

+136
-97
lines changed

include/swift/AST/Types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ namespace swift {
6565
class ValueDecl;
6666
class ModuleDecl;
6767
class ProtocolConformance;
68-
enum class SILArgumentConvention : uint8_t;
68+
struct SILArgumentConvention;
6969
enum OptionalTypeKind : unsigned;
7070
enum PointerTypeKind : unsigned;
7171
enum class ValueOwnershipKind : uint8_t;

include/swift/SIL/SILArgument.h

Lines changed: 3 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -13,57 +13,15 @@
1313
#ifndef SWIFT_SIL_SILARGUMENT_H
1414
#define SWIFT_SIL_SILARGUMENT_H
1515

16-
#include "swift/SIL/SILValue.h"
16+
#include "swift/SIL/SILArgumentConvention.h"
1717
#include "swift/SIL/SILFunction.h"
18+
#include "swift/SIL/SILValue.h"
1819

1920
namespace swift {
2021

2122
class SILBasicBlock;
2223
class SILModule;
2324

24-
/// Conventions for apply operands and function-entry arguments in SIL.
25-
///
26-
/// By design, this is exactly the same as ParameterConvention, plus
27-
/// Indirect_Out.
28-
enum class SILArgumentConvention : uint8_t {
29-
Indirect_In,
30-
Indirect_In_Guaranteed,
31-
Indirect_Inout,
32-
Indirect_InoutAliasable,
33-
Indirect_Out,
34-
Direct_Owned,
35-
Direct_Unowned,
36-
Direct_Deallocating,
37-
Direct_Guaranteed,
38-
};
39-
40-
inline bool isIndirectConvention(SILArgumentConvention convention) {
41-
return convention <= SILArgumentConvention::Indirect_Out;
42-
}
43-
44-
/// Turn a ParameterConvention into a SILArgumentConvention.
45-
inline SILArgumentConvention getSILArgumentConvention(ParameterConvention conv){
46-
switch (conv) {
47-
case ParameterConvention::Indirect_In:
48-
return SILArgumentConvention::Indirect_In;
49-
case ParameterConvention::Indirect_Inout:
50-
return SILArgumentConvention::Indirect_Inout;
51-
case ParameterConvention::Indirect_InoutAliasable:
52-
return SILArgumentConvention::Indirect_InoutAliasable;
53-
case ParameterConvention::Indirect_In_Guaranteed:
54-
return SILArgumentConvention::Indirect_In_Guaranteed;
55-
case ParameterConvention::Direct_Unowned:
56-
return SILArgumentConvention::Direct_Unowned;
57-
case ParameterConvention::Direct_Guaranteed:
58-
return SILArgumentConvention::Direct_Guaranteed;
59-
case ParameterConvention::Direct_Owned:
60-
return SILArgumentConvention::Direct_Owned;
61-
case ParameterConvention::Direct_Deallocating:
62-
return SILArgumentConvention::Direct_Deallocating;
63-
}
64-
llvm_unreachable("covered switch isn't covered?!");
65-
}
66-
6725
inline SILArgumentConvention
6826
SILFunctionType::getSILArgumentConvention(unsigned index) const {
6927
assert(index <= getNumSILArguments());
@@ -72,44 +30,8 @@ SILFunctionType::getSILArgumentConvention(unsigned index) const {
7230
return SILArgumentConvention::Indirect_Out;
7331
} else {
7432
auto param = getParameters()[index - numIndirectResults];
75-
return swift::getSILArgumentConvention(param.getConvention());
76-
}
77-
}
78-
79-
enum class InoutAliasingAssumption {
80-
/// Assume that an inout indirect parameter may alias other objects.
81-
/// This is the safe assumption an optimization should make if it may break
82-
/// memory safety in case the inout aliasing rule is violation.
83-
Aliasing,
84-
85-
/// Assume that an inout indirect parameter cannot alias other objects.
86-
/// Optimizations should only use this if they can guarantee that they will
87-
/// not break memory safety even if the inout aliasing rule is violated.
88-
NotAliasing
89-
};
90-
91-
/// Returns true if \p conv is a not-aliasing indirect parameter.
92-
/// The \p isInoutAliasing specifies what to assume about the inout convention.
93-
/// See InoutAliasingAssumption.
94-
inline bool isNotAliasedIndirectParameter(SILArgumentConvention conv,
95-
InoutAliasingAssumption isInoutAliasing) {
96-
switch (conv) {
97-
case SILArgumentConvention::Indirect_In:
98-
case SILArgumentConvention::Indirect_Out:
99-
case SILArgumentConvention::Indirect_In_Guaranteed:
100-
return true;
101-
102-
case SILArgumentConvention::Indirect_Inout:
103-
return isInoutAliasing == InoutAliasingAssumption::NotAliasing;
104-
105-
case SILArgumentConvention::Indirect_InoutAliasable:
106-
case SILArgumentConvention::Direct_Unowned:
107-
case SILArgumentConvention::Direct_Guaranteed:
108-
case SILArgumentConvention::Direct_Owned:
109-
case SILArgumentConvention::Direct_Deallocating:
110-
return false;
33+
return SILArgumentConvention(param.getConvention());
11134
}
112-
llvm_unreachable("covered switch isn't covered?!");
11335
}
11436

11537
class SILArgument : public ValueBase {
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
//===--- SILArgumentConvention.h ------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 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_SIL_SILARGUMENTCONVENTION_H
14+
#define SWIFT_SIL_SILARGUMENTCONVENTION_H
15+
16+
#include "swift/AST/Types.h"
17+
18+
namespace swift {
19+
20+
enum class InoutAliasingAssumption {
21+
/// Assume that an inout indirect parameter may alias other objects.
22+
/// This is the safe assumption an optimization should make if it may break
23+
/// memory safety in case the inout aliasing rule is violation.
24+
Aliasing,
25+
26+
/// Assume that an inout indirect parameter cannot alias other objects.
27+
/// Optimizations should only use this if they can guarantee that they will
28+
/// not break memory safety even if the inout aliasing rule is violated.
29+
NotAliasing
30+
};
31+
32+
/// Conventions for apply operands and function-entry arguments in SIL.
33+
///
34+
/// By design, this is exactly the same as ParameterConvention, plus
35+
/// Indirect_Out.
36+
struct SILArgumentConvention {
37+
enum : uint8_t {
38+
Indirect_In,
39+
Indirect_In_Guaranteed,
40+
Indirect_Inout,
41+
Indirect_InoutAliasable,
42+
Indirect_Out,
43+
Direct_Owned,
44+
Direct_Unowned,
45+
Direct_Deallocating,
46+
Direct_Guaranteed,
47+
} Value;
48+
49+
SILArgumentConvention(decltype(Value) NewValue) : Value(NewValue) {}
50+
51+
/// Turn a ParameterConvention into a SILArgumentConvention.
52+
explicit SILArgumentConvention(ParameterConvention Conv) : Value() {
53+
switch (Conv) {
54+
case ParameterConvention::Indirect_In:
55+
Value = SILArgumentConvention::Indirect_In;
56+
return;
57+
case ParameterConvention::Indirect_Inout:
58+
Value = SILArgumentConvention::Indirect_Inout;
59+
return;
60+
case ParameterConvention::Indirect_InoutAliasable:
61+
Value = SILArgumentConvention::Indirect_InoutAliasable;
62+
return;
63+
case ParameterConvention::Indirect_In_Guaranteed:
64+
Value = SILArgumentConvention::Indirect_In_Guaranteed;
65+
return;
66+
case ParameterConvention::Direct_Unowned:
67+
Value = SILArgumentConvention::Direct_Unowned;
68+
return;
69+
case ParameterConvention::Direct_Guaranteed:
70+
Value = SILArgumentConvention::Direct_Guaranteed;
71+
return;
72+
case ParameterConvention::Direct_Owned:
73+
Value = SILArgumentConvention::Direct_Owned;
74+
return;
75+
case ParameterConvention::Direct_Deallocating:
76+
Value = SILArgumentConvention::Direct_Deallocating;
77+
return;
78+
}
79+
llvm_unreachable("covered switch isn't covered?!");
80+
}
81+
82+
operator decltype(Value)() const { return Value; }
83+
84+
bool isIndirectConvention() const {
85+
return Value <= SILArgumentConvention::Indirect_Out;
86+
}
87+
88+
/// Returns true if \p Value is a not-aliasing indirect parameter.
89+
/// The \p isInoutAliasing specifies what to assume about the inout
90+
/// convention.
91+
/// See InoutAliasingAssumption.
92+
bool isNotAliasedIndirectParameter(InoutAliasingAssumption isInoutAliasing) {
93+
switch (Value) {
94+
case SILArgumentConvention::Indirect_In:
95+
case SILArgumentConvention::Indirect_Out:
96+
case SILArgumentConvention::Indirect_In_Guaranteed:
97+
return true;
98+
99+
case SILArgumentConvention::Indirect_Inout:
100+
return isInoutAliasing == InoutAliasingAssumption::NotAliasing;
101+
102+
case SILArgumentConvention::Indirect_InoutAliasable:
103+
case SILArgumentConvention::Direct_Unowned:
104+
case SILArgumentConvention::Direct_Guaranteed:
105+
case SILArgumentConvention::Direct_Owned:
106+
case SILArgumentConvention::Direct_Deallocating:
107+
return false;
108+
}
109+
llvm_unreachable("covered switch isn't covered?!");
110+
}
111+
};
112+
113+
} // namespace swift
114+
115+
#endif

include/swift/SIL/SILInstruction.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@
2121
#include "swift/AST/ProtocolConformanceRef.h"
2222
#include "swift/SIL/Consumption.h"
2323
#include "swift/SIL/SILAllocated.h"
24+
#include "swift/SIL/SILArgumentConvention.h"
25+
#include "swift/SIL/SILDeclRef.h"
2426
#include "swift/SIL/SILLocation.h"
2527
#include "swift/SIL/SILSuccessor.h"
26-
#include "swift/SIL/SILDeclRef.h"
2728
#include "swift/SIL/SILValue.h"
28-
#include "llvm/ADT/ilist_node.h"
29-
#include "llvm/ADT/ilist.h"
3029
#include "llvm/ADT/APFloat.h"
3130
#include "llvm/ADT/APInt.h"
31+
#include "llvm/ADT/ilist.h"
32+
#include "llvm/ADT/ilist_node.h"
3233
#include "llvm/Support/TrailingObjects.h"
3334

3435
namespace swift {

lib/SILOptimizer/Analysis/ValueTracking.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ bool swift::isNotAliasingArgument(SILValue V,
2929
if (!Arg)
3030
return false;
3131

32-
return isNotAliasedIndirectParameter(Arg->getArgumentConvention(),
33-
isInoutAliasing);
32+
SILArgumentConvention Conv = Arg->getArgumentConvention();
33+
return Conv.isNotAliasedIndirectParameter(isInoutAliasing);
3434
}
3535

3636
/// Check if the parameter \V is based on a local object, e.g. it is an

lib/SILOptimizer/IPO/CapturePromotion.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ isNonescapingUse(Operand *O, SmallVectorImpl<SILInstruction*> &Mutations) {
717717
auto argIndex = O->getOperandNumber()-1;
718718
auto convention =
719719
AI->getSubstCalleeType()->getSILArgumentConvention(argIndex);
720-
if (isIndirectConvention(convention)) {
720+
if (convention.isIndirectConvention()) {
721721
Mutations.push_back(AI);
722722
return true;
723723
}

lib/SILOptimizer/Transforms/AllocBoxToStack.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,8 @@ static bool partialApplyEscapes(SILValue V, bool examineApply) {
194194

195195
// apply instructions do not capture the pointer when it is passed
196196
// indirectly
197-
if (isIndirectConvention(
198-
apply->getArgumentConvention(UI->getOperandNumber()-1)))
197+
if (apply->getArgumentConvention(UI->getOperandNumber() - 1)
198+
.isIndirectConvention())
199199
continue;
200200

201201
// Optionally drill down into an apply to see if the operand is

lib/SILOptimizer/Transforms/CopyForwarding.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -147,21 +147,21 @@ static SILArgumentConvention getAddressArgConvention(ApplyInst *Apply,
147147
SILValue Address,
148148
Operand *&Oper) {
149149
Oper = nullptr;
150-
SILArgumentConvention Conv;
151150
auto Args = Apply->getArgumentOperands();
151+
llvm::Optional<unsigned> FoundArgIdx;
152152
for (auto ArgIdx : indices(Args)) {
153153
if (Args[ArgIdx].get() != Address)
154154
continue;
155155

156-
Conv = Apply->getArgumentConvention(ArgIdx);
156+
FoundArgIdx = ArgIdx;
157157
assert(!Oper && "Address can only be passed once as an indirection.");
158158
Oper = &Args[ArgIdx];
159159
#ifndef NDEBUG
160160
break;
161161
#endif
162162
}
163163
assert(Oper && "Address value not passed as an argument to this call.");
164-
return Conv;
164+
return Apply->getArgumentConvention(FoundArgIdx.getValue());
165165
}
166166

167167
//===----------------------------------------------------------------------===//
@@ -457,10 +457,11 @@ bool CopyForwarding::collectUsers() {
457457
/// object. However, we can rely on a subsequent mark_dependent
458458
/// instruction to take that object as an operand, causing it to escape
459459
/// for the purpose of this analysis.
460-
assert(isIndirectConvention(
461-
Apply->getSubstCalleeType()->getSILArgumentConvention(
462-
UI->getOperandNumber() - Apply->getArgumentOperandNumber()))
463-
&& "copy_addr location should be passed indirect");
460+
assert(Apply->getSubstCalleeType()
461+
->getSILArgumentConvention(UI->getOperandNumber() -
462+
Apply->getArgumentOperandNumber())
463+
.isIndirectConvention() &&
464+
"copy_addr location should be passed indirect");
464465
SrcUserInsts.insert(Apply);
465466
continue;
466467
}

0 commit comments

Comments
 (0)