The C++ ABI for static locals is a bit heavy compared to dispatch_once; doing this saves more than 1KB in runtime code size. Dispatch_once/call_once is also more likely to be hot because it's also used by Swift and ObjC code.
Alas, llvm::get_execution_seed() from llvm/ADT/Hashing.h still inflicts one static local initialization on us we can't override (without forking Hashing.h, anyway).
When we see an unused variable in a simple-enough "if/let" (also guard and
while of course), fixit it into a comparison against nil instead of replacing
the name of the variable with "_". Also special case initialization with an
as? expression, since we can transform that into an "is" boolean test.
This improves the error message when attempting an array to UnsafeMutablePointer
conversion but where the element type of the array is incorrect or where the array itself
is immutable.
As a bonus fix, this dramatically improves the diagnostic when you pass "&array" to
a function that takes an UnsafePointer. We decided to not require & in this case, so
we can just provide a nice fixit to rip it off when this common error happens.
The SIL serializer can decide not to serialize the body of functions in the SIL
module, and only emit a declaration. If we keep the original linkage kind
(public, private, etc) then the deserialized module won't pass verification
because we do not allow internal functions to have external declarations. This
commit changes the linkage kind for the functions that the serializer decides to
emit as a declaration (without a body).
rdar://21989088
Add a small verification method that checks that we run our function analysis
only on functions with bodies (not on external definitions). I ran into this bug
when working on the pass manager.
Add a cache for calls to typesMayAlias. We never invalidate this cache
because type aliasing relations never change.
The hit rate of this cache is really high.
This commit removes the public method for fetching SideEffectsAnalysis. The
dependency on SEA is now an implementation detail of AliasAnalysis and
computeMemoryBehavior.
The AliasAnalysis is unsafe. When we delete instructions we don't have a good
mechanism for invalidating the cache and we don't want instructions to
explicitly invalidate AliasAnalysis after every deletion of an instruction.
Morever, the alias analysis cache _always_ misses. Removing the cache did not
change the build time of the standard library at all.
getMemoryBehavior is also used by SILInstruction. This commit renames
getMemoryBehavior to computeMemoryBehavior and cleans some of the code
that touches it.
// I forgot to add this file in my previous commit.
Now with a change to the AST printer to never print @_fixed_layout.
Once some more groundwork is in place, we will be able to only print
this attribute when its needed, but this is good enough for now.
This fixes type punning issues with unsafeBitCast.
The optimizer is still too aggressive with UnsafePointer. To fix that,
we first need an explicit API for circumventing type safety
(rdar://23406272).
I should be able to fix the following regressions by migrating the
stdlib away from unsafeBitCast to unsafeReferenceCast (~2 weeks).
Slowdowns:
|.Benchmark.................|..Before.|...After.|.Speedup|
|.ArrayInClass..............|...49.00.|...78.00.|.-37.2%.|
|.Sim2DArray................|..471.00.|..549.00.|.-14.2%.|
|.PrimeNum..................|.1876.00.|.1980.00.|..-5.3%.|
Speedups:
|.Benchmark.................|..Before.|...After.|.Speedup|
|.HeapSort..................|.2962.00.|.2663.00.|..11.2%.|
|.StdlibSort................|.2672.00.|.2537.00.|...5.3%.|
This series of commits is reverted because it introduces risk. This type
of change requires design discussion and thorough unit testing.
Revert "Refactor in alias analysis. NFC"
This reverts commit 3390a584b8.
Revert "Update SILArgument alias analysis to make use of the new alias() interface"
This reverts commit 5940fcca78.
Revert "Clean up uneeded SIL in a LIT test"
This reverts commit 81ebb5667f.
Revert "Fix LIT test in basic-aa."
This reverts commit a55340394f.
Revert "Improve comments in alias analysis"
This reverts commit 44ddc5b4df.
Revert "Implement SILArgument and select_enum handling for alias analysis"
This reverts commit 23c257938f.
The drivers for this change are providing a simpler API to SIL pass
authors, having a more efficient of the in-memory representation,
and ruling out an entire class of common bugs that usually result
in hard-to-debug backend crashes.
Summary
-------
SILInstruction
Old New
+---------------+ +------------------+ +-----------------+
|SILInstruction | |SILInstruction | |SILDebugLocation |
+---------------+ +------------------+ +-----------------+
| ... | | ... | | ... |
|SILLocation | |SILDebugLocation *| -> |SILLocation |
|SILDebugScope *| +------------------+ |SILDebugScope * |
+---------------+ +-----------------+
We’re introducing a new class SILDebugLocation which represents the
combination of a SILLocation and a SILDebugScope.
Instead of storing an inline SILLocation and a SILDebugScope pointer,
SILInstruction now only has one SILDebugLocation pointer. The APIs of
SILBuilder and SILDebugLocation guarantees that every SILInstruction
has a nonempty SILDebugScope.
Developer-visible changes include:
SILBuilder
----------
In the old design SILBuilder populated the InsertedInstrs list to
allow setting the debug scopes of all built instructions in bulk
at the very end (as the responsibility of the user). In the new design,
SILBuilder now carries a "current debug scope" state and immediately
sets the debug scope when an instruction is inserted.
This fixes a use-after-free issue with with SIL passes that delete
instructions before destroying the SILBuilder that created them.
Because of this, SILBuilderWithScopes no longer needs to be a template,
which simplifies its call sites.
SILInstruction
--------------
It is neither possible or necessary to manually call setDebugScope()
on a SILInstruction any more. The function still exists as a private
method, but is only used when splicing instructions from one function
to another.
Efficiency
----------
In addition to dropping 20 bytes from each SILInstruction,
SILDebugLocations are now allocated in the SILModule's bump pointer
allocator and are uniqued by SILBuilder. Unfortunately repeat compiles
of the standard library already vary by about 5% so I couldn’t yet
produce reliable numbers for how much this saves overall.
rdar://problem/22017421
This reverts commit bf2fdb6764.
One of the build bots reported a malloc/free error, while other bots had successful builds. It could indicate a non-deterministic failure.
Preventively revert this patch as it is the most likely cause of these issues.
rdar://23611346
Use malloc/free for allocating/freeing SIL instructions instead of using the BumpPtrAllocator. This allows for memory reuse and significantly reduces the memory footprint of the compiler.
For example, a peak memory usage during a compilation of the standard library and StdlibUnitTest is reduced by 25%-30%. The performance of the compiler seems to be not affected by this change, i.e. no slowdown is measured.
The use-after-free issue reported by build bots is fixed now.
rdar://23303031
The cache is using SILValues as keys and such key would contain dangling pointers after the instruction corresponding to a given SILValue is erased.
Therefore, the cache needs to be invalidated between queries. It still makes sense to use the cache during queries, because sometimes queries may be recursive and pretty expensive to compute. It is safe to use caching during the query, because no instructions are being erased while processing it.
The removal of the cache does not seem to affect compile times in a negative way.
The cache was using SILValue as a key and this key would contain a dangling pointer after the instruction corresponding to a given SILValue is erased.
The removal of the cache does not seem to affect compile times in a negative way.
rdar://23602657
This commit changes the way passes invalidate analysis. Passes now report the
list of traits that they invalidate. We went back and forth on this a few times
and we are now going back to the invalidation mode. In a few places in the
optimizer passes had to record the fact that they deleted a call or a branch and
had to construct the enum that will contain the preserve list. Now passes can
either use the new enum states that are the intersection of traits or even send
multiple invalidation message.
We are making this change now because Mark added a new kind of invalidation
trait ("function"). Adopting this new invalidation trait required that we
inspect all of the invalidation sites anyway. This commit includes a more
efficient use of the 'function' attribute, and our function passes don't
invalidate the 'function' attribute anymore.