Skip to content

Commit a89d93c

Browse files
authored
Merge pull request swiftlang#12907 from eeckstein/function-opt-modes
Function-level optimization attributes.
2 parents a5de4cc + 8033476 commit a89d93c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+544
-172
lines changed

include/swift/AST/Attr.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,10 @@ SIMPLE_DECL_ATTR(_implicitly_unwrapped_optional,
299299
ImplicitlyUnwrappedOptional,
300300
OnFunc | OnVar | OnSubscript | OnConstructor | RejectByParser, 72)
301301

302+
DECL_ATTR(_optimize, Optimize,
303+
OnFunc | OnConstructor | OnDestructor | OnSubscript | OnVar |
304+
UserInaccessible, 73)
305+
302306
#undef TYPE_ATTR
303307
#undef DECL_ATTR_ALIAS
304308
#undef SIMPLE_DECL_ATTR

include/swift/AST/Attr.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/Basic/UUID.h"
2222
#include "swift/Basic/STLExtras.h"
2323
#include "swift/Basic/Range.h"
24+
#include "swift/Basic/OptimizationMode.h"
2425
#include "swift/Basic/Version.h"
2526
#include "swift/AST/Identifier.h"
2627
#include "swift/AST/AttrKind.h"
@@ -925,6 +926,23 @@ class InlineAttr : public DeclAttribute {
925926
}
926927
};
927928

929+
/// Represents the optimize attribute.
930+
class OptimizeAttr : public DeclAttribute {
931+
OptimizationMode Mode;
932+
public:
933+
OptimizeAttr(SourceLoc atLoc, SourceRange range, OptimizationMode mode)
934+
: DeclAttribute(DAK_Optimize, atLoc, range, /*Implicit=*/false),
935+
Mode(mode) {}
936+
937+
OptimizeAttr(OptimizationMode mode)
938+
: OptimizeAttr(SourceLoc(), SourceRange(), mode) {}
939+
940+
OptimizationMode getMode() const { return Mode; }
941+
static bool classof(const DeclAttribute *DA) {
942+
return DA->getKind() == DAK_Optimize;
943+
}
944+
};
945+
928946
/// Represents the side effects attribute.
929947
class EffectsAttr : public DeclAttribute {
930948
EffectsKind Kind;

include/swift/AST/DiagnosticsParse.def

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1365,10 +1365,10 @@ ERROR(opened_attribute_id_value,none,
13651365
ERROR(opened_attribute_expected_rparen,none,
13661366
"expected ')' after id value for 'opened' attribute", ())
13671367

1368-
// inline
1369-
ERROR(inline_attribute_expect_option,none,
1370-
"expected '%0' option such as 'never'", (StringRef))
1371-
ERROR(inline_attribute_unknown_option,none,
1368+
// inline, optimize
1369+
ERROR(optimization_attribute_expect_option,none,
1370+
"expected '%0' option such as '%1'", (StringRef, StringRef))
1371+
ERROR(optimization_attribute_unknown_option,none,
13721372
"unknown option '%0' for attribute '%1'", (StringRef, StringRef))
13731373

13741374
// effects

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,8 +1024,6 @@ ERROR(functions_mutating_and_not,none,
10241024
ERROR(static_functions_not_mutating,none,
10251025
"static functions must not be declared mutating", ())
10261026

1027-
ERROR(transparent_stored_property,none,
1028-
"@_transparent cannot be applied to stored properties", ())
10291027
ERROR(transparent_in_protocols_not_supported,none,
10301028
"@_transparent is not supported on declarations within protocols", ())
10311029
ERROR(transparent_in_classes_not_supported,none,
@@ -3705,8 +3703,8 @@ ERROR(class_designated_init_inlineable_resilient,none,
37053703
"'%select{@_transparent|@inline(__always)|@_inlineable|%error}1' and must "
37063704
"delegate to another initializer", (Type, unsigned))
37073705

3708-
ERROR(inlineable_stored_property,
3709-
none, "'@_inlineable' attribute cannot be applied to stored properties", ())
3706+
ERROR(attribute_invalid_on_stored_property,
3707+
none, "@%0 cannot be applied to stored properties", (StringRef))
37103708

37113709
ERROR(inlineable_dynamic_not_supported,
37123710
none, "'@_inlineable' attribute cannot be applied to 'dynamic' declarations", ())

include/swift/AST/IRGenOptions.h

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/AST/LinkLibrary.h"
2222
#include "swift/Basic/Sanitizers.h"
2323
#include "swift/Basic/OptionSet.h"
24+
#include "swift/Basic/OptimizationMode.h"
2425
// FIXME: This include is just for llvm::SanitizerCoverageOptions. We should
2526
// split the header upstream so we don't include so much.
2627
#include "llvm/Transforms/Instrumentation.h"
@@ -94,11 +95,7 @@ class IRGenOptions {
9495
/// well-formed?
9596
unsigned Verify : 1;
9697

97-
/// Whether or not to run optimization passes.
98-
unsigned Optimize : 1;
99-
100-
/// Whether or not to optimize for code size.
101-
unsigned OptimizeForSize : 1;
98+
OptimizationMode OptMode;
10299

103100
/// Which sanitizer is turned on.
104101
OptionSet<SanitizerKind> Sanitizers;
@@ -179,7 +176,7 @@ class IRGenOptions {
179176

180177
IRGenOptions()
181178
: DWARFVersion(2), OutputKind(IRGenOutputKind::LLVMAssembly),
182-
Verify(true), Optimize(false), OptimizeForSize(false),
179+
Verify(true), OptMode(OptimizationMode::NotSet),
183180
Sanitizers(OptionSet<SanitizerKind>()),
184181
DebugInfoKind(IRGenDebugInfoKind::None), UseJIT(false),
185182
DisableLLVMOptzns(false), DisableLLVMARCOpts(false),
@@ -202,9 +199,7 @@ class IRGenOptions {
202199
// Get a hash of all options which influence the llvm compilation but are not
203200
// reflected in the llvm module itself.
204201
unsigned getLLVMCodeGenOptionsHash() {
205-
unsigned Hash = 0;
206-
Hash = (Hash << 1) | Optimize;
207-
Hash = (Hash << 1) | OptimizeForSize;
202+
unsigned Hash = (unsigned)OptMode;
208203
Hash = (Hash << 1) | DisableLLVMOptzns;
209204
Hash = (Hash << 1) | DisableLLVMARCOpts;
210205
return Hash;
@@ -222,6 +217,14 @@ class IRGenOptions {
222217
}
223218
}
224219

220+
bool shouldOptimize() const {
221+
return OptMode > OptimizationMode::NoOptimization;
222+
}
223+
224+
bool optimizeForSize() const {
225+
return OptMode == OptimizationMode::ForSize;
226+
}
227+
225228
/// Return a hash code of any components from these options that should
226229
/// contribute to a Swift Bridging PCH hash.
227230
llvm::hash_code getPCHHashComponents() const {

include/swift/AST/PrintOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ struct PrintOptions {
386386
result.PrintImplicitAttrs = false;
387387
result.ExcludeAttrList.push_back(DAK_Exported);
388388
result.ExcludeAttrList.push_back(DAK_Inline);
389+
result.ExcludeAttrList.push_back(DAK_Optimize);
389390
result.ExcludeAttrList.push_back(DAK_Rethrows);
390391
result.PrintOverrideKeyword = false;
391392
result.AccessFilter = AccessLevel::Public;

include/swift/AST/SILOptions.h

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "swift/Basic/Sanitizers.h"
2222
#include "swift/Basic/OptionSet.h"
23+
#include "swift/Basic/OptimizationMode.h"
2324
#include "llvm/ADT/Hashing.h"
2425
#include "llvm/ADT/StringRef.h"
2526
#include <string>
@@ -52,16 +53,6 @@ class SILOptions {
5253
LinkAll
5354
};
5455

55-
/// Representation of optimization modes.
56-
enum class SILOptMode: unsigned {
57-
NotSet,
58-
None,
59-
Debug,
60-
Optimize,
61-
OptimizeForSize,
62-
OptimizeUnchecked
63-
};
64-
6556
/// Controls how to perform SIL linking.
6657
LinkingMode LinkMode = LinkNormal;
6758

@@ -91,7 +82,7 @@ class SILOptions {
9182
bool EmitVerboseSIL = false;
9283

9384
/// Optimization mode being used.
94-
SILOptMode Optimization = SILOptMode::NotSet;
85+
OptimizationMode OptMode = OptimizationMode::NotSet;
9586

9687
enum AssertConfiguration: unsigned {
9788
// Used by standard library code to distinguish between a debug and release
@@ -167,6 +158,10 @@ class SILOptions {
167158
llvm::hash_code getPCHHashComponents() const {
168159
return llvm::hash_value(0);
169160
}
161+
162+
bool shouldOptimize() const {
163+
return OptMode > OptimizationMode::NoOptimization;
164+
}
170165
};
171166

172167
} // end namespace swift
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===-------- OptimizationMode.h - Swift optimization modes -----*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 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_BASIC_OPTIMIZATIONMODE_H
14+
#define SWIFT_BASIC_OPTIMIZATIONMODE_H
15+
16+
#include "llvm/Support/DataTypes.h"
17+
18+
namespace swift {
19+
20+
// The optimization mode specified on the command line or with function
21+
// attributes.
22+
enum class OptimizationMode : uint8_t {
23+
NotSet = 0,
24+
NoOptimization = 1, // -Onone
25+
ForSpeed = 2, // -Ospeed == -O
26+
ForSize = 3, // -Osize
27+
LastMode = ForSize
28+
};
29+
30+
} // end namespace swift
31+
32+
#endif // SWIFT_BASIC_OPTIMIZATIONMODE_H

include/swift/SIL/SILFunction.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ class SILFunction
171171
/// pre-specialization.
172172
unsigned KeepAsPublic : 1;
173173

174+
/// If != OptimizationMode::NotSet, the optimization mode specified with an
175+
/// function attribute.
176+
OptimizationMode OptMode;
177+
174178
/// This is the number of uses of this SILFunction inside the SIL.
175179
/// It does not include references from debug scopes.
176180
unsigned RefCount = 0;
@@ -479,10 +483,26 @@ class SILFunction
479483

480484
void addSpecializeAttr(SILSpecializeAttr *Attr);
481485

486+
487+
/// Get this function's optimization mode or OptimizationMode::NotSet if it is
488+
/// not set for this specific function.
489+
OptimizationMode getOptimizationMode() const { return OptMode; }
490+
491+
/// Returns the optimization mode for the function. If no mode is set for the
492+
/// function, returns the global mode, i.e. the mode of the module's options.
493+
OptimizationMode getEffectiveOptimizationMode() const;
494+
495+
void setOptimizationMode(OptimizationMode mode) { OptMode = mode; }
496+
482497
/// \returns True if the function is optimizable (i.e. not marked as no-opt),
483498
/// or is raw SIL (so that the mandatory passes still run).
484499
bool shouldOptimize() const;
485500

501+
/// Returns true if this function should be optimized for size.
502+
bool optimizeForSize() const {
503+
return getEffectiveOptimizationMode() == OptimizationMode::ForSize;
504+
}
505+
486506
/// Returns true if this is a function that should have its ownership
487507
/// verified.
488508
bool shouldVerifyOwnership() const;

include/swift/SILOptimizer/PassManager/PassManager.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,19 +97,27 @@ class SILPassManager {
9797
/// same function.
9898
bool RestartPipeline = false;
9999

100+
/// If true, passes are also run for functions which have
101+
/// OptimizationMode::NoOptimization.
102+
bool isMandatoryPipeline = false;
100103

101104
/// The IRGen SIL passes. These have to be dynamically added by IRGen.
102105
llvm::DenseMap<unsigned, SILTransform *> IRGenPasses;
103106

104107
public:
105108
/// C'tor. It creates and registers all analysis passes, which are defined
106109
/// in Analysis.def.
107-
SILPassManager(SILModule *M, llvm::StringRef Stage = "");
110+
///
111+
/// If \p isMandatoryPipeline is true, passes are also run for functions
112+
/// which have OptimizationMode::NoOptimization.
113+
SILPassManager(SILModule *M, llvm::StringRef Stage = "",
114+
bool isMandatoryPipeline = false);
108115

109116
/// C'tor. It creates an IRGen pass manager. Passes can query for the
110117
/// IRGenModule.
111118
SILPassManager(SILModule *M, irgen::IRGenModule *IRMod,
112-
llvm::StringRef Stage = "");
119+
llvm::StringRef Stage = "",
120+
bool isMandatoryPipeline = false);
113121

114122
const SILOptions &getOptions() const;
115123

0 commit comments

Comments
 (0)