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 issues reported by build bots are fixed now.
rdar://23303031
There's a buggy SIL verifier check that was previously tautological,
and it turns out that it's violated, apparently harmlessly. Since it
was already doing nothing, I've commented it out temporarily while
I figure out the right way to fix SILGen to get the invariant right.
This commit adds a DebugVariable field that is shared by
- AllocBoxInst
- AllocStackInst
- DebugValueInst
- DebugValueAddrInst
Currently DebugVariable only holds the Swift argument number.
This allows us to retire several expensive heuristics in IRGen that
attempted to identify which local variables actually where arguments
and recover their relative order.
Memory footprint notes:
This commit adds a 4-byte field to 4 SILInstructin subclasses.
This was offset by 8ab1e2dd50
which removed 20 bytes from *every* SILInstruction.
Caveats:
This commit surfaces a known bug in FunctionSigantureOpts, tracked in
rdar://problem/23727705 — debug info for exploded function arguments
cannot be expressed until this is fixed.
This reapplies ed2b16dc5a with a bugfix for
generic function arrguments and an additional testcase.
<rdar://problem/21185379&22705926>
This commit adds a DebugVariable field that is shared by
- AllocBoxInst
- AllocStackInst
- DebugValueInst
- DebugValueAddrInst
Currently DebugVariable only holds the Swift argument number.
This allows us to retire several expensive heuristics in IRGen that
attempted to identify which local variables actually where arguments
and recover their relative order.
Memory footprint notes:
This commit adds a 4-byte field to 4 SILInstructin subclasses.
This was offset by 8ab1e2dd50
which removed 20 bytes from *every* SILInstruction.
Caveats:
This commit surfaces a known bug in FunctionSigantureOpts, tracked in
rdar://problem/23727705 — debug info for exploded function arguments
cannot be expressed until this is fixed.
<rdar://problem/21185379&22705926>
Handle such cases like partial applications of witness methods and applications of witness methods with substitutions.
Some of these uses-cases occur when there is a protocol defining an operator, a generic struct conforming to this protocol, and the operator conformance of this struct is expressed as a global function.
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
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.
rdar://23303031
Refines the results of getReleasingBehavior() by checking the
consumption kind of UnconditionalCheckedCastAddrInst and
CheckedCastAddrBranchInst, as well as whether a CopyAddrInst is an
initialization.
This will be used in call graph construction so that we can model calls
to deinits that are potentially called as a result of executing
instructions that can end up releasing memory.
This improves support for promoting to and generating
unchecked_ref_cast so we no longer need unchecked_ref_bit_cast, which
will just go away in the next commit.
Swift SVN r32597
_unsafeCastReference allows casting of any references types, regardless
of whether they are references to objects or class existentials. The
implementation is responsible for converting between representations.
_unsafeCastReference provides a dynamic check to ensure that the source
and dest are both actually references. If not, the implementation will
trap at runtime. Generally, the optimizer can prove that the source
and dest are references, and promote this cast to an
unchecked_ref_cast bitcast. There is no dynamic check that the
references types are compatible.
This differs from unsafeDownCast in two ways:
(1) The source and dest types are not statically typed
AnyObjects. Therefore, unsafeCastReference can be used when the
surrounding code dynamically handles both reference and nonreference
types.
(2) The source and dest also need not dynamically conform to AnyObject.
Either side of the cast may be a class existential. The primary
requirement is that the source and dest refer to the same reference
counted object.
Swift SVN r32588
Previously all uses of this instruction used the single element ArrayRef
constructor. The single element ArrayRef constructor does not require any extra
memory. In the case where one does need extra memory, one would need to allocate
the memory for the init_existential_metatype and pass it in. This commit changes
init_existential_metatype to tail allocate the memory for the conformance
pointers and memcpy them in from the array.
Discovered when a SmallVector of protocol conformances resulted in memory
corruption and frustration =--(.
rdar://22302277
Swift SVN r31276
If the compiler can prove that a throwing function actually does not throw it can
replace a try_apply with an "apply [nothrow]". Such an apply_inst calls a function
with an error result but does not have the overhead of checking for the error case.
Currently this flag is not set, yet.
Swift SVN r31151
dealloc_ref [destructor] is the existing behavior. It expects the
reference count to have reached zero and the isDeallocating bit to
be set.
The new [constructor] variant first drops the initial strong
reference.
This allows DI to properly free uninitialized instances in
constructors. Previously this would fail with an assertion if the
runtime was built with debugging enabled.
Progress on <rdar://problem/21991742>.
Swift SVN r31142
Often times one will want to process a BuiltinInst just based off of the
intrinsic or builtin kind. Generally one only wants to process one or
the other and has to introduce variables for the IntrinsicInfo or
BuiltinInfo to a wider scope than one wishes to. These builtins simplify
the processing of such builtins by allowing one to create an if
statement scope around the variable.
if (auto Kind = BI->getBuiltinKind()) {
...
}
if (auto ID = BI->getIntrinsicID()) {
...
}
Swift SVN r30835
I am going to use this functionality while performing refactoring of Projection,
ProjectionTree to make it easier to perform partial dead code elimination and
owned -> guaranteed optimization at the same time.
Swift SVN r30000
The usage in ConstantPropagation required checking if a branch was passed to the
erase action since in Constant Propagation we want to only invalidate
ProgramFlow if possible. I already fixed this part in r29604. In this commit, I
cleaned up the code by adding/using a "PreserveKindBuilder" that a pass can use
to conveniently accumulate invalidations. This part of the change is just a
refactoring.
In the case of SimplifyCFG we always invalidate everything, we do not need to do
any special checking beyond making sure that a non-null value is passed back
from the cast optimizer. From my investigations in the cast optimizer, it
appears that this always occurs currently. But just in case some future code is
added that allows for a nullptr to come back after it has made modifications, I
added code that ensures that we properly set MadeChange if we modify any
instructions. Since this currently can not happen, I can not write a test for it
that is meaningful.
In the case of SILCombine, we do not perform transformations that invalidate the
CFG, so the current method of using SILCombine's RAUW and inst erase hooks
handle the situation correctly.
Swift SVN r29778
We need a SIL level unsafe cast that supports arbitrary usage of
UnsafePointer, generalizes Builtin.reinterpretCast, and has the same
semantics on generic vs. nongeneric code. In other words, we need to
be able to promote the cast of an address type to the cast of an
object type without changing semantics, and that cast needs to support
types that are not layout identical.
This patch introduces an unchecked_bitwise_cast instruction for that
purpose. It is different from unsafe_addr_cast, which has been our
fall-back "unknown" cast in the past. With unchecked_bitwise_cast we
cannot assume layout or RC identity. The cast implies a store and
reload of the value to obtain the low order bytes. I know that
bit_cast is just an abbreviation for bitwise_cast, but we use
"bitcast" throught to imply copying a same sized value. No one could
come up with a better name for copying an objects low bytes via:
@addr = alloca $wideTy
store @addr, $wideTy
load @addr, $narrowTy
Followup patches will optimize unchecked_bitwise_cast into more
semantically useful unchecked casts when enough type information is
present. This way, the optimizer will rarely need to be taught about
the bitwise case.
Swift SVN r29510
Still no implementation yet; we'll need to renovate how boxes work a bit to make them projectable (and renovate SILGen to generate typed boxes for the insn to be useful).
Swift SVN r29490
This reverts commit r29475 because it conflicts with reverting r29474,
and it looks like that commit is breaking the build of the SpriteKit
overlay.
Swift SVN r29481
Still no implementation yet; we'll need to renovate how boxes work a bit to make them projectable (and renovate SILGen to generate typed boxes for the insn to be useful).
Swift SVN r29475
SILGen is used to passing in lowered types without getting their object types specifically, and the object type may not be a legal SIL type for address-only types. Fixes rdar://problem/21408736.
Swift SVN r29436