A fixed layout type is one about which the compiler is allowed to
make certain assumptions across resilience domains. The assumptions
will be documented elsewhere, but for the purposes of this patch
series, they will include:
- the size of the type
- offsets of stored properties
- whether accessed properties are stored or computed
When -enable-resilience is passed to the frontend, all types become
resilient unless annotated with the @fixed_layout attribute.
So far, the @fixed_layout attribute only comes into play in SIL type
lowering of structs and enums, which now become address-only unless
they are @fixed_layout. For now, @fixed_layout is also allowed on
classes, but has no effect. In the future, support for less resilient
type lowering within a single resilience domain will be added, with
appropriate loads and stores in function prologs and epilogs.
Resilience is not enabled by default, which gives all types fixed
layout and matches the behavior of the compiler today. Since
we do not want the -enable-resilience flag to change the behavior
of existing compiled modules, only the currently-compiling module,
Sema adds the @fixed_layout flag to all declarations when the flag
is off. To reduce the size of .swiftmodule files, this could become
a flag on the module itself in the future.
The reasoning behind this is that the usual case is building
applications and private frameworks, where there is no need to make
anything resilient.
For the standard library, we can start out with resilience disabled,
while perfoming an audit adding @fixed_layout annotations in the
right places. Once the implementation is robust enough we can then
build the standard library with resilience enabled.
Revert "Fix complete_decl_attribute test for @fixed_layout"
Revert "Sema: non-@objc private stored properties do not need accessors"
Revert "Sema: Access stored properties of resilient structs through accessors"
Revert "Strawman @fixed_layout attribute and -{enable,disable}-resilience flags"
This reverts commit c91c6a789e.
This reverts commit 693d3d339f.
This reverts commit 085f88f616.
This reverts commit 5d99dc9bb8.
A fixed layout type is one about which the compiler is allowed to
make certain assumptions across resilience domains. The assumptions
will be documented elsewhere, but for the purposes of this patch
series, they will include:
- the size of the type
- offsets of stored properties
- whether accessed properties are stored or computed
When -enable-resilience is passed to the frontend, all types become
resilient unless annotated with the @fixed_layout attribute.
So far, the @fixed_layout attribute only comes into play in SIL type
lowering of structs and enums, which now become address-only unless
they are @fixed_layout. For now, @fixed_layout is also allowed on
classes, but has no effect. In the future, support for less resilient
type lowering within a single resilience domain will be added, with
appropriate loads and stores in function prologs and epilogs.
Resilience is not enabled by default, which gives all types fixed
layout and matches the behavior of the compiler today. Since
we do not want the -enable-resilience flag to change the behavior
of existing compiled modules, only the currently-compiling module,
Sema adds the @fixed_layout flag to all declarations when the flag
is off. To reduce the size of .swiftmodule files, this could become
a flag on the module itself in the future.
The reasoning behind this is that the usual case is building
applications and private frameworks, where there is no need to make
anything resilient.
For the standard library, we can start out with resilience disabled,
while perfoming an audit adding @fixed_layout annotations in the
right places. Once the implementation is robust enough we can then
build the standard library with resilience enabled.
This reverts r32940. In reality this is not dead code, because
foreign to native thunks have the _TTO mangling. We need better
tests, which I will add in an upcoming commit.
Swift SVN r32945
And include some supplementary mangling changes:
- Give the first generic param (depth=0, index=0) a single character mangling. Even after removing the self type from method declaration types, 'Self' still shows up very frequently in protocol requirement signatures.
- Fix the mangling of generic parameter counts to elide the count when there's only one parameter at the starting depth of the mangling.
Together these carve another 154KB out of a debug standard library. There's some awkwardness in demangled strings that I'll clean up in subsequent commits; since decl types now only mangle the number of generic params at their own depth, it's context-dependent what depths those represent, which we get wrong now. Currying markers are also wrong, but since free function currying is going away, we can mangle the partial application thunks in different ways.
Swift SVN r32896
Previously we represented all successors in a list where each successor
was represented by a SuccessorID. A SuccessorID is essentially an
unsigned int that stores some flags in the lower bits of the
integer. The two flags are: 1. IsDead, 2. IsNonLocal (where non local
means that it is a loop exit edge). When the IsNonLocal flag is not set,
the integer that is actually stored represents the ID of the successor
region. If the IsNonLocal flag is set, then the integer represents the
index in the parent region's successor list of the actual loop exit
successor.
The bug I mentioned was that we were not being careful enough in the
replacement code to distinguish in between successors that were loop
exit successors and those that were not. This could cause us to replace
a loop exit successor whose integer value was the same as the index of a
non-loop exit successor with the non-loop exit successor. This then
would cause us to miscompile and or introduce duplicate values into the
successor list. Luckily an assert I added caught the latter condition.
After I fixed this problem, an interesting performance issue was
exposed. I had assumed when using a list that I would never have more
than 10-20 successors (in general a reasonable assumption). But
introducing loop exit successors adds in an interesting wrinkle, namely
every block with an unreachable terminator will result in a successor
edge. This makes just iterating over a uniqued list really slow.
I solved the issue by writing a new data structure called
BlotSetVector. The interesting thing about BlotSetVector is that all
operations preserve index offsets. This means that if one erases a
value, all other values in the set vector are not moved around in the
internal vector. This is important since a loop exit edge needs to refer
to an invariant offset in the parent region's successor array since we
do not want to have to go through and update large amounts of unrelated
edges every time we erase an edge.
In terms of a test case, this invariant was impossible for me to reproduce since
it is sensitive to the order of successors. Even dumping the file and running
the analysis would not catch it. After 2 days of trying to make a test case I
gave up. But I filed rdar://23228299 to verify that sil-opt can round trip
in memory ordering of various items such as use lists, successors, predecessors,
block ordering, function ordering, etc.
rdar://22238658
Swift SVN r32839
Canonical dependent member types are always based from a generic parameter, so we can use a more optimal mangling that assumes this. We can also introduce substitutions for AssociatedTypeDecls, and when a generic parameter in a signature is constrained by a single protocol, we can leave that protocol qualification out of the unsubstituted associated type mangling. These optimizations together shrink the standard library by 117KB, and bring the length of the longest Swift symbol in the stdlib down from 578 to 334 characters, shorter than the longest C++ symbol in the stdlib.
Swift SVN r32786
This is a WIP to make CompilerVersion more general.
- Rename CompilerVersion to just "Version"
- Make version comparison general and put _compiler_version special logic
with its second version component in a specialized parsing function
- Add a generic version parsing function
Swift SVN r32726
Internal compiler versions must be able to be packed into a 64-bit
value, and there is a limit on how many components we can use and which
values they can take on.
Versions must have no more than five components, assuming a version
X.Y.Z.a.b, where X, Y, Z, a, and b are integers with the following
inclusive ranges:
X: [0 - 214747]
Y: [0 - 999]
Z: [0 - 999]
a: [0 - 999]
b: [0 - 999]
Swift SVN r32724
When users try to print the interface of a specific type (most often through cursor
infor query of SourceKit), we should simplify the original decls by replacing
archetypes with instantiated types, hiding extension details, and omitting
unfulfilled extension requirements. So the users can get the straight-to-the-point
"type interface". This commit builds the testing infrastructure for this feature,
and implements the first trick that wraps extension contents into the interface body.
This commit also moves some generic testing support from SourceKit to Swift.
Swift SVN r32630
Prepend "is" to Boolean property names (e.g., "empty" becomes
"isEmpty") unless the property name strongly indicates its Boolean
nature or we're likely to ruin the name. Therefore, the presence of
one of the following in the property name will suppress this
transformation:
* An auxiliary verb, such as "is", "has", "may", "should", or "will".
* A word ending in "s", indicating either a plural (for which
prepending "is" would be incorrect) or a verb in the continuous
tense (which indicates its Boolean nature, e.g., "translates" in
"translatesCoordinates").
Swift SVN r32458
a ternary tree with a fixed-length per-node inline key buffer.
I plan to use this for metadata path caches, where it's useful to
be able to quickly find the most-derived point along a path that
you've already cached, but it should be useful for other things
in the compiler as well, like function-with-argument-label
lookups and possibly code completion.
This is quite a bit more space-efficient (and somewhat faster)
than doing scans after a lower_bound on a std::map<std::string, T>.
I haven't implemented balancing yet, and I don't need delete at
all for metadata paths, so I don't plan to work on that.
Swift SVN r32453
When the first parameter of a function has Boolean type, try to create
an argument label for it. We start with the (normally non-API)
parameter name as the argument label, then try to match that against
the end of the base name of the method to eliminate redundancy. Add a
little magic, and here are some diffs:
- func openUntitledDocumentAndDisplay(_: Bool) throws -> NSDocument
+ func openUntitledDocument(display _: Bool) throws -> NSDocument
- func fontMenu(_: Bool) -> NSMenu?
- func fontPanel(_: Bool) -> NSFontPanel?
+ func fontMenu(create _: Bool) -> NSMenu?
+ func fontPanel(create _: Bool) -> NSFontPanel?
- func lockFocusFlipped(_: Bool)
+ func lockFocus(flipped _: Bool)
- func rectForSearchTextWhenCentered(_: Bool) -> NSRect
+ func rectForSearchText(whenCentered _: Bool) -> NSRect
- func dismissPreviewAnimated(_: Bool)
- func dismissMenuAnimated(_: Bool)
+ func dismissPreview(animated _: Bool)
+ func dismissMenu(animated _: Bool)
Swift SVN r32392
'arch' and 'os' build configurations with valid identifiers as
arguments, but which are unknown to the compiler, will cause the
compiler to silently skip over that code as it has an inactive clause.
Emit a diagnostic, but not an error so as not to inadvertantly break
code that may be in a compiler without knowledge of a particular
operating system or architecture.
rdar://problem/22052176
Swift SVN r32219
A couple of small tweaks to _compiler_version based on review comments:
- Fix &&/|| rejection to work with _compiler_version on either side of the
expression. Also add some test cases around this.
- Use clang/LLVM facilities for isdigit and atoi.
- Assert if parsing an invalid version string and there is no diagnostic
engine.
- Clean up some crumbs in the CMake configs.
rdar://problem/22730282
Swift SVN r32212
This configuration clause will suppress lex diagnostics and skip parsing
altogether if the code under the clause isn't active - the compiler must
have a repository version greater than or equal to the version given to
_compiler_version.
This option is only meant to be used sparingly and not to track the
Swift *language* version.
Example, if using a compiler versioned 700.0.28:
#if _compiler_version("700.0.23")
print("This code will compile for versions 700.0.23 and later.")
#else
This + code + will + not + be + parsed
#endif
Included are new diagnostics for checking that the version is formatted
correctly and isn't empty.
New tests:
- Compiler version comparison unit tests
- Build configuration diagnostics
- Skipping parsing of code under inactive clauses
rdar://problem/22730282
Swift SVN r32195
When the context type of a declaraton matches the result type,
strip off redundant type information at the beginning of the
declaration name if it is followed by a preposition. This covers the
class of transformations on performs on a class that produce a value
of the same type as that class, e.g., NSURL's "URLWithHTTPS" or
NSString's "stringByAppendingString".
When that preposition is the magical "By" and is followed by a gerund,
strip the "By" as well. Note that this is slightly more conservative
now for methods, which previously stripped based on the result type
(always). For example, in NSCalendar:
- func adding(_: NSDateComponents, to: NSDate, options:
NSCalendarOptions = [])
-> NSDate?
+ func dateByAdding(_: NSDateComponents, to: NSDate, options:
NSCalendarOptions
= []) -> NSDate?
but it's more general for properties, e.g.,
- @NSCopying var bezierPathByFlattening: NSBezierPath { get }
- @NSCopying var bezierPathByReversing: NSBezierPath { get }
+ @NSCopying var byFlattening: NSBezierPath { get }
+ @NSCopying var reversing: NSBezierPath { get }
The important part is that the rules are more uniform and the code is
more regularly structured: we strip this leading type information when
it's redundant with the context and result type, regardless of whether
we have a property or a method, and the "By" rule is no longer special
in that regard.
Swift SVN r32129
This commit provides an enumerator that yields both the index of an element in a
random access collection and the index itself. This is useful when one wants the
post order and or rpo number of an element and the element itself.
Swift SVN r32102
Split the base name at the last preposition, but *only* when the first
parameter is defaulted, because defaulted arguments might not show up
at the call site and the longer base name can feel odd in such
cases. With this, stop avoiding the argument label "with": it's fine
when we have actual context at the call site, and the "with: nil" case
no longer happens now that we're defaulting nil.
Swift SVN r32098
Not every relative address makes sense to be conditionally indirect, so separate RelativeIndirectablePointer (which takes a tag bit to indicate whether the reference is directly to the object in question or to memory containing its address, such as its GOT entry) and RelativeDirectPointer. NFC.
Swift SVN r31839
I also added a macro called INITIALIZE_LLVM(argc, argv) which moves this logic
into one place and should be used at the beginning of *all* binaries. It
initializes an LLVM shutdown object, sets up the pretty stack trace, and then
initializes all of the parts of LLVM. This will make it easy to update this in
the future.
The reason why a macro was required was because of llvm_shutdown_obj, an RAII
object that cleans up LLVM. It has to be at the function level scope of the main
function.
Swift SVN r31815