This commit changes the Swift mangler from a utility that writes tokens into a
stream into a name-builder that has two phases: "building a name", and "ready".
This clear separation is needed for the implementation of the compression layer.
Users of the mangler can continue to build the name using the mangleXXX methods,
but to access the results the users of the mangler need to call the finalize()
method. This method can write the result into a stream, like before, or return
an std::string.
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
Because the swift compiler relies on Clang to setup the Module,
the clang CU is always created first. Several dwarf-reading
tools (older versions of ld64, and lldb) can get confused if the
first CU in an object is empty, so ensure that the Swift CU comes
first by rearranging the list of CUs in the LLVM module.
rdar://problem/23434643
prologue is handled in the line table.
We now mark the first instruction after the stack setup as end_prologue and
any further initilizations (which may include function calls to metadata
accessors) with line 0 which lldb will skip. This allows swiftc to emit
debug info for compiler-generated functions such as metadata accessors.
Mixing debug and non-debug functions is not very well supported by LLVM
and the resulting line table makes it impossible for LLDB to determine
where a function with debug info ends and a nondebug function starts.
rdar://problem/23042642
Swift SVN r32816
the regressions that r31105 introduced in the validation tests, as well as fixing a number
of other validation tests as well.
Introduce a new UnresolvedType to the type system, and have CSDiags start to use it
as a way to get more type information out of incorrect subexpressions. UnresolvedType
generally just propagates around the type system like a type variable:
- it magically conforms to all protocols
- it CSGens as an unconstrained type variable.
- it ASTPrints as _, just like a type variable.
The major difference is that UnresolvedType can be used outside the context of a
ConstraintSystem, which is useful for CSGen since it sets up several of them to
diagnose subexpressions w.r.t. their types.
For now, our use of this is extremely limited: when a closureexpr has no contextual
type available and its parameters are invalid, we wipe them out with UnresolvedType
(instead of the previous nulltype dance) to get ambiguities later on.
We also introduce a new FreeTypeVariableBinding::UnresolvedType approach for
constraint solving (and use this only in one place in CSDiags so far, to resolve
the callee of a CallExpr) which solves a system and rewrites any leftover type
variables as UnresolvedTypes. This allows us to get more precise information out,
for example, diagnosing:
func r22162441(lines: [String]) {
lines.map { line in line.fooBar() }
}
with: value of type 'String' has no member 'fooBar'
instead of: type of expression is ambiguous without more context
This improves a number of other diagnostics as well, but is just the infrastructural
stepping stone for greater things.
Swift SVN r31130
as a way to get more type information out of incorrect subexpressions. UnresolvedType
generally just propagates around the type system like a type variable:
- it magically conforms to all protocols
- it CSGens as an unconstrained type variable.
- it ASTPrints as _, just like a type variable.
The major difference is that UnresolvedType can be used outside the context of a
ConstraintSystem, which is useful for CSGen since it sets up several of them to
diagnose subexpressions w.r.t. their types.
For now, our use of this is extremely limited: when a closureexpr has no contextual
type available and its parameters are invalid, we wipe them out with UnresolvedType
(instead of the previous nulltype dance) to get ambiguities later on.
We also introduce a new FreeTypeVariableBinding::UnresolvedType approach for
constraint solving (and use this only in one place in CSDiags so far, to resolve
the callee of a CallExpr) which solves a system and rewrites any leftover type
variables as UnresolvedTypes. This allows us to get more precise information out,
for example, diagnosing:
func r22162441(lines: [String]) {
lines.map { line in line.fooBar() }
}
with: value of type 'String' has no member 'fooBar'
instead of: type of expression is ambiguous without more context
This improves a number of other diagnostics as well, but is just the infrastructural
stepping stone for greater things.
Swift SVN r31105
When computing the locations for local indirect enums, we could enter
an infinite loop if the first field is a recursive reference.
Just bail out of the field-splitting logic if we encounter an indirect
case. More work might be needed if indirect enums get exploded.
rdar://problem/21927941
Swift SVN r30717
This changes the behavior to match NominalTypeDecls, which don't have a type
until everything is set up either. In a few places we construct TypeAliasDecls
from known types directly, and we have to call computeType().
Fixes <rdar://problem/19534837>.
Swift SVN r30386
MDModule was a bitcode-incompatible internal-only extension that has
since been replaced with a blessed IR node on trunk.
<rdar://problem/20965932> Upstream DIModule and support it in clang-700, swiftlang-700, and lldb-700
Swift SVN r29832
Represents a heap allocation containing a value of type T, which we'll be able to use to represent the payloads of indirect enum cases, and also improve codegen of current boxes, which generates non-uniqued box metadata on every allocation, which is dumb. No codegen changes or IRGen support yet; that will come later.
This time, fix a paste-o that caused SILBlockStorageTypes to get replaced with SILBoxTypes during type substitution. Oops.
Swift SVN r29489
Represents a heap allocation containing a value of type T, which we'll be able to use to represent the payloads of indirect enum cases, and also improve codegen of current boxes, which generates non-uniqued box metadata on every allocation, which is dumb. No codegen changes or IRGen support yet; that will come later.
Swift SVN r29474
create a replaceable forward declaration while building it.
This fixes a crash when building generic enums a tuple element recursively
referenceing the enum.
rdar://problem/21326786
Swift SVN r29416
and create a replaceable forward declaration while building it.
This fixes a crash when building generic enums with a constructor
function.
<rdar://problem/21294835>
Swift SVN r29411
With all the previous bugfixes it is no longer necessary to keep separate
copies because inlining and generic specialization is now handled
correctly so each specialized variable has its own specialized version
of the archetype.
rdar://problem/21109015
Swift SVN r29187
A dbg.declare is only meaningful if there is a single alloca for
the variable that is live throughout the function. With SIL
optimizations this is not guranteed and a variable can end up in
two allocas (for example, one function inlined twice).
Caught by an assertion in LLVM.
rdar://problem/21109015
Swift SVN r29186
emitting indirect pieces — LLVM (ToT, 700) now supports this.
Since this only happens in optimized code it is currently not feasible
to write a non-flaky testcase for this. I'll revisit this once our
SIL serialization efforts progressed further.
<rdar://problem/19427586> Support indirect pieces
Swift SVN r28051