Skip to content

Commit e9dfb73

Browse files
committed
SIL: Micro-optimize SILFunction layout
1 parent 53f32e6 commit e9dfb73

File tree

2 files changed

+47
-40
lines changed

2 files changed

+47
-40
lines changed

include/swift/SIL/SILFunction.h

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

161161
Identifier ObjCReplacementFor;
162162

163+
/// The function's set of semantics attributes.
164+
///
165+
/// TODO: Why is this using a std::string? Why don't we use uniqued
166+
/// StringRefs?
167+
std::vector<std::string> SemanticsAttrSet;
168+
169+
/// The function's remaining set of specialize attributes.
170+
std::vector<SILSpecializeAttr*> SpecializeAttrSet;
171+
172+
/// Has value if there's a profile for this function
173+
/// Contains Function Entry Count
174+
ProfileCounter EntryCount;
175+
176+
/// This is the number of uses of this SILFunction inside the SIL.
177+
/// It does not include references from debug scopes.
178+
unsigned RefCount = 0;
179+
163180
/// The function's bare attribute. Bare means that the function is SIL-only
164181
/// and does not require debug info.
165182
unsigned Bare : 1;
@@ -200,33 +217,9 @@ class SILFunction
200217
// Whether the implementation can be dynamically replaced.
201218
unsigned IsDynamicReplaceable : 1;
202219

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

231224
/// True if this function is a zombie function. This means that the function
232225
/// is dead and not referenced from anywhere inside the SIL. But it is kept
@@ -235,28 +228,35 @@ class SILFunction
235228
/// *) It is a dead method of a class which has higher visibility than the
236229
/// method itself. In this case we need to create a vtable stub for it.
237230
/// *) It is a function referenced by the specialization information.
238-
bool Zombie = false;
231+
unsigned Zombie : 1;
239232

240233
/// True if this function is in Ownership SSA form and thus must pass
241234
/// ownership verification.
242235
///
243236
/// This enables the verifier to easily prove that before the Ownership Model
244237
/// Eliminator runs on a function, we only see a non-semantic-arc world and
245238
/// after the pass runs, we only see a semantic-arc world.
246-
bool HasOwnership = true;
239+
unsigned HasOwnership : 1;
247240

248241
/// Set if the function body was deserialized from canonical SIL. This implies
249242
/// that the function's home module performed SIL diagnostics prior to
250243
/// serialization.
251-
bool WasDeserializedCanonical = false;
244+
unsigned WasDeserializedCanonical : 1;
252245

253246
/// True if this is a reabstraction thunk of escaping function type whose
254247
/// single argument is a potentially non-escaping closure. This is an escape
255248
/// hatch to allow non-escaping functions to be stored or passed as an
256249
/// argument with escaping function type. The thunk argument's function type
257250
/// is not necessarily @noescape. The only relevant aspect of the argument is
258251
/// that it may have unboxed capture (i.e. @inout_aliasable parameters).
259-
bool IsWithoutActuallyEscapingThunk = false;
252+
unsigned IsWithoutActuallyEscapingThunk : 1;
253+
254+
/// If != OptimizationMode::NotSet, the optimization mode specified with an
255+
/// function attribute.
256+
unsigned OptMode : NumOptimizationModeBits;
257+
258+
/// The function's effects attribute.
259+
unsigned EffectsKindAttr : NumEffectsKindBits;
260260

261261
static void
262262
validateSubclassScope(SubclassScope scope, IsThunk_t isThunk,
@@ -650,13 +650,17 @@ class SILFunction
650650

651651
/// Get this function's optimization mode or OptimizationMode::NotSet if it is
652652
/// not set for this specific function.
653-
OptimizationMode getOptimizationMode() const { return OptMode; }
653+
OptimizationMode getOptimizationMode() const {
654+
return OptimizationMode(OptMode);
655+
}
654656

655657
/// Returns the optimization mode for the function. If no mode is set for the
656658
/// function, returns the global mode, i.e. the mode of the module's options.
657659
OptimizationMode getEffectiveOptimizationMode() const;
658660

659-
void setOptimizationMode(OptimizationMode mode) { OptMode = mode; }
661+
void setOptimizationMode(OptimizationMode mode) {
662+
OptMode = unsigned(mode);
663+
}
660664

661665
/// \returns True if the function is optimizable (i.e. not marked as no-opt),
662666
/// or is raw SIL (so that the mandatory passes still run).
@@ -726,16 +730,16 @@ class SILFunction
726730
void setInlineStrategy(Inline_t inStr) { InlineStrategy = inStr; }
727731

728732
/// \return the function side effects information.
729-
EffectsKind getEffectsKind() const { return EffectsKindAttr; }
733+
EffectsKind getEffectsKind() const { return EffectsKind(EffectsKindAttr); }
730734

731735
/// \return True if the function is annotated with the @_effects attribute.
732736
bool hasEffectsKind() const {
733-
return EffectsKindAttr != EffectsKind::Unspecified;
737+
return EffectsKind(EffectsKindAttr) != EffectsKind::Unspecified;
734738
}
735739

736740
/// Set the function side effect information.
737741
void setEffectsKind(EffectsKind E) {
738-
EffectsKindAttr = E;
742+
EffectsKindAttr = unsigned(E);
739743
}
740744

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

lib/SIL/SILFunction.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,16 @@ SILFunction::SILFunction(SILModule &Module, SILLinkage Linkage, StringRef Name,
9898
IsDynamicallyReplaceable_t isDynamic)
9999
: Module(Module), Name(Name), LoweredType(LoweredType),
100100
GenericEnv(genericEnv), SpecializationInfo(nullptr),
101-
DebugScope(DebugScope), Bare(isBareSILFunction), Transparent(isTrans),
102-
Serialized(isSerialized), Thunk(isThunk),
101+
DebugScope(DebugScope), EntryCount(entryCount), Bare(isBareSILFunction),
102+
Transparent(isTrans), Serialized(isSerialized), Thunk(isThunk),
103103
ClassSubclassScope(unsigned(classSubclassScope)), GlobalInitFlag(false),
104104
InlineStrategy(inlineStrategy), Linkage(unsigned(Linkage)),
105105
HasCReferences(false), IsWeakLinked(false),
106-
IsDynamicReplaceable(isDynamic), OptMode(OptimizationMode::NotSet),
107-
EffectsKindAttr(E), EntryCount(entryCount) {
106+
IsDynamicReplaceable(isDynamic),
107+
Inlined(false), Zombie(false), HasOwnership(true),
108+
WasDeserializedCanonical(false), IsWithoutActuallyEscapingThunk(false),
109+
OptMode(unsigned(OptimizationMode::NotSet)),
110+
EffectsKindAttr(unsigned(E)) {
108111
assert(!Transparent || !IsDynamicReplaceable);
109112
validateSubclassScope(classSubclassScope, isThunk, nullptr);
110113

@@ -189,8 +192,8 @@ ASTContext &SILFunction::getASTContext() const {
189192
}
190193

191194
OptimizationMode SILFunction::getEffectiveOptimizationMode() const {
192-
if (OptMode != OptimizationMode::NotSet)
193-
return OptMode;
195+
if (OptimizationMode(OptMode) != OptimizationMode::NotSet)
196+
return OptimizationMode(OptMode);
194197

195198
return getModule().getOptions().OptMode;
196199
}

0 commit comments

Comments
 (0)