Skip to content

Commit 0fd7cb8

Browse files
committed
SIL: Micro-optimize SILFunction layout
1 parent 19f5ac1 commit 0fd7cb8

File tree

2 files changed

+45
-39
lines changed

2 files changed

+45
-39
lines changed

include/swift/SIL/SILFunction.h

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,23 @@ class SILFunction
165165

166166
Identifier ObjCReplacementFor;
167167

168+
/// The function's set of semantics attributes.
169+
///
170+
/// TODO: Why is this using a std::string? Why don't we use uniqued
171+
/// StringRefs?
172+
std::vector<std::string> SemanticsAttrSet;
173+
174+
/// The function's remaining set of specialize attributes.
175+
std::vector<SILSpecializeAttr*> SpecializeAttrSet;
176+
177+
/// Has value if there's a profile for this function
178+
/// Contains Function Entry Count
179+
ProfileCounter EntryCount;
180+
181+
/// This is the number of uses of this SILFunction inside the SIL.
182+
/// It does not include references from debug scopes.
183+
unsigned RefCount = 0;
184+
168185
/// The function's bare attribute. Bare means that the function is SIL-only
169186
/// and does not require debug info.
170187
unsigned Bare : 1;
@@ -209,33 +226,9 @@ class SILFunction
209226
/// invoked with a `self` argument of the exact base class type.
210227
unsigned ExactSelfClass : 1;
211228

212-
/// If != OptimizationMode::NotSet, the optimization mode specified with an
213-
/// function attribute.
214-
OptimizationMode OptMode;
215-
216-
/// This is the number of uses of this SILFunction inside the SIL.
217-
/// It does not include references from debug scopes.
218-
unsigned RefCount = 0;
219-
220-
/// The function's set of semantics attributes.
221-
///
222-
/// TODO: Why is this using a std::string? Why don't we use uniqued
223-
/// StringRefs?
224-
llvm::SmallVector<std::string, 1> SemanticsAttrSet;
225-
226-
/// The function's remaining set of specialize attributes.
227-
std::vector<SILSpecializeAttr*> SpecializeAttrSet;
228-
229-
/// The function's effects attribute.
230-
EffectsKind EffectsKindAttr;
231-
232-
/// Has value if there's a profile for this function
233-
/// Contains Function Entry Count
234-
ProfileCounter EntryCount;
235-
236229
/// True if this function is inlined at least once. This means that the
237230
/// debug info keeps a pointer to this function.
238-
bool Inlined = false;
231+
unsigned Inlined : 1;
239232

240233
/// True if this function is a zombie function. This means that the function
241234
/// is dead and not referenced from anywhere inside the SIL. But it is kept
@@ -244,28 +237,35 @@ class SILFunction
244237
/// *) It is a dead method of a class which has higher visibility than the
245238
/// method itself. In this case we need to create a vtable stub for it.
246239
/// *) It is a function referenced by the specialization information.
247-
bool Zombie = false;
240+
unsigned Zombie : 1;
248241

249242
/// True if this function is in Ownership SSA form and thus must pass
250243
/// ownership verification.
251244
///
252245
/// This enables the verifier to easily prove that before the Ownership Model
253246
/// Eliminator runs on a function, we only see a non-semantic-arc world and
254247
/// after the pass runs, we only see a semantic-arc world.
255-
bool HasOwnership = true;
248+
unsigned HasOwnership : 1;
256249

257250
/// Set if the function body was deserialized from canonical SIL. This implies
258251
/// that the function's home module performed SIL diagnostics prior to
259252
/// serialization.
260-
bool WasDeserializedCanonical = false;
253+
unsigned WasDeserializedCanonical : 1;
261254

262255
/// True if this is a reabstraction thunk of escaping function type whose
263256
/// single argument is a potentially non-escaping closure. This is an escape
264257
/// hatch to allow non-escaping functions to be stored or passed as an
265258
/// argument with escaping function type. The thunk argument's function type
266259
/// is not necessarily @noescape. The only relevant aspect of the argument is
267260
/// that it may have unboxed capture (i.e. @inout_aliasable parameters).
268-
bool IsWithoutActuallyEscapingThunk = false;
261+
unsigned IsWithoutActuallyEscapingThunk : 1;
262+
263+
/// If != OptimizationMode::NotSet, the optimization mode specified with an
264+
/// function attribute.
265+
unsigned OptMode : NumOptimizationModeBits;
266+
267+
/// The function's effects attribute.
268+
unsigned EffectsKindAttr : NumEffectsKindBits;
269269

270270
static void
271271
validateSubclassScope(SubclassScope scope, IsThunk_t isThunk,
@@ -671,13 +671,17 @@ class SILFunction
671671

672672
/// Get this function's optimization mode or OptimizationMode::NotSet if it is
673673
/// not set for this specific function.
674-
OptimizationMode getOptimizationMode() const { return OptMode; }
674+
OptimizationMode getOptimizationMode() const {
675+
return OptimizationMode(OptMode);
676+
}
675677

676678
/// Returns the optimization mode for the function. If no mode is set for the
677679
/// function, returns the global mode, i.e. the mode of the module's options.
678680
OptimizationMode getEffectiveOptimizationMode() const;
679681

680-
void setOptimizationMode(OptimizationMode mode) { OptMode = mode; }
682+
void setOptimizationMode(OptimizationMode mode) {
683+
OptMode = unsigned(mode);
684+
}
681685

682686
/// \returns True if the function is optimizable (i.e. not marked as no-opt),
683687
/// or is raw SIL (so that the mandatory passes still run).
@@ -755,16 +759,16 @@ class SILFunction
755759
void setInlineStrategy(Inline_t inStr) { InlineStrategy = inStr; }
756760

757761
/// \return the function side effects information.
758-
EffectsKind getEffectsKind() const { return EffectsKindAttr; }
762+
EffectsKind getEffectsKind() const { return EffectsKind(EffectsKindAttr); }
759763

760764
/// \return True if the function is annotated with the @_effects attribute.
761765
bool hasEffectsKind() const {
762-
return EffectsKindAttr != EffectsKind::Unspecified;
766+
return EffectsKind(EffectsKindAttr) != EffectsKind::Unspecified;
763767
}
764768

765769
/// Set the function side effect information.
766770
void setEffectsKind(EffectsKind E) {
767-
EffectsKindAttr = E;
771+
EffectsKindAttr = unsigned(E);
768772
}
769773

770774
/// Get this function's global_init attribute.

lib/SIL/SILFunction.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,17 @@ SILFunction::SILFunction(SILModule &Module, SILLinkage Linkage, StringRef Name,
9393
IsExactSelfClass_t isExactSelfClass)
9494
: Module(Module), Name(Name), LoweredType(LoweredType),
9595
GenericEnv(genericEnv), SpecializationInfo(nullptr),
96-
Bare(isBareSILFunction), Transparent(isTrans),
96+
EntryCount(entryCount), Bare(isBareSILFunction), Transparent(isTrans),
9797
Serialized(isSerialized), Thunk(isThunk),
9898
ClassSubclassScope(unsigned(classSubclassScope)), GlobalInitFlag(false),
9999
InlineStrategy(inlineStrategy), Linkage(unsigned(Linkage)),
100100
HasCReferences(false), IsWeakLinked(false),
101101
IsDynamicReplaceable(isDynamic),
102102
ExactSelfClass(isExactSelfClass),
103-
OptMode(OptimizationMode::NotSet),
104-
EffectsKindAttr(E), EntryCount(entryCount) {
103+
Inlined(false), Zombie(false), HasOwnership(true),
104+
WasDeserializedCanonical(false), IsWithoutActuallyEscapingThunk(false),
105+
OptMode(unsigned(OptimizationMode::NotSet)),
106+
EffectsKindAttr(unsigned(E)) {
105107
assert(!Transparent || !IsDynamicReplaceable);
106108
validateSubclassScope(classSubclassScope, isThunk, nullptr);
107109
setDebugScope(DebugScope);
@@ -188,8 +190,8 @@ ASTContext &SILFunction::getASTContext() const {
188190
}
189191

190192
OptimizationMode SILFunction::getEffectiveOptimizationMode() const {
191-
if (OptMode != OptimizationMode::NotSet)
192-
return OptMode;
193+
if (OptimizationMode(OptMode) != OptimizationMode::NotSet)
194+
return OptimizationMode(OptMode);
193195

194196
return getModule().getOptions().OptMode;
195197
}

0 commit comments

Comments
 (0)