Commit Graph

17 Commits

Author SHA1 Message Date
Andrew Trick
badc5658bb Fix SIL MemBehavior queries with access markers.
This is in prepration for other bug fixes.

Clarify the SIL utilities that return canonical address values for
formal access given the address used by some memory operation:

- stripAccessMarkers
- getAddressAccess
- getAccessedAddress

These are closely related to the code in MemAccessUtils.

Make sure passes use these utilities consistently so that
optimizations aren't defeated by normal variations in SIL patterns.

Create an isLetAddress() utility alongside these basic utilities to
make sure it is used consistently with the address corresponding to
formal access. When this query is used inconsistently, it defeats
optimization. It can also cause correctness bugs because some
optimizations assume that 'let' initialization is only performed on a
unique address value.

Functional changes to Memory Behavior:

- An instruction with side effects now conservatively still has side
  effects even when the queried value is a 'let'. Let values are
  certainly sensitive to side effects, such as the parent object being
  deallocated.

- Return the correct MemBehavior for begin/end_access markers.
2020-03-03 09:24:18 -08:00
Andrew Trick
999b32e0fd EscapeAnalysis: add a refcount flag to content nodes.
This property will allow alias analysis to be safely optmistic when
querying the connection graph. A node that is known to have a ref
count is know to keep alive everything it points to. Therefore,
calling a deinitializer on a different reference cannot release the RC
node's contents.
2019-11-13 11:41:34 -08:00
Andrew Trick
f009cf3de8 EscapeAnalysis cleanup and add utilities [nearly NFC]
This is the first in a series of patches that reworks
EscapeAnalysis. For this patch, I extracted every change that does not
introduce new features, rewrite logic, or appear to change
functionality.

These cleanups were done in preparation for:

- adding a graph representation for reference counted objects

- rewriting parts to the query logic

- ...which then allows the analysis to safely assume that all
  exclusive arguments are unique

- ...which then allows more aggressive optimization of local variables
  that don't escape

There are two possible functional changes:

1. getUnderlyingAddressRoot in InstructionUtils now sees through OSSA
instructions: begin_borrow and copy_value

2. The getPointerBase helper in EscapeAnalysis now sees through all of
these reference and pointer casts:

+  case ValueKind::UncheckedRefCastInst:
+  case ValueKind::ConvertFunctionInst:
+  case ValueKind::UpcastInst:
+  case ValueKind::InitExistentialRefInst:
+  case ValueKind::OpenExistentialRefInst:
+  case ValueKind::RawPointerToRefInst:
+  case ValueKind::RefToRawPointerInst:
+  case ValueKind::RefToBridgeObjectInst:
+  case ValueKind::BridgeObjectToRefInst:
+  case ValueKind::UncheckedAddrCastInst:
+  case ValueKind::UnconditionalCheckedCastInst:
+  case ValueKind::RefTo##Name##Inst:
+  case ValueKind::Name##ToRefInst:

This coalesces a whole bunch of nodes together that were just there
because of casts. The existing code was already doing this for one
level of casts, but there was a bug that prevented it from happening
transitively. So, in theory, anything that breaks with this fix could
also break without this fix, but may not have been exposed. The fact
that this analysis coalesces address-to-reference casts at all is what
caused me to spent vast amounts of time debugging any time I tried to
force some structure on the graph via assertions. If it is done at
all, it should be done everywhere consistently to expose issues as
early as possible.

Here is a description of the changes in diff order. If something in
the diff is not listed here, then the code probably just moved around
in the file:

Rename isNotAliasedIndirectParameter to
isExclusiveIndirectParameter. The argument may be aliased in the
caller's scope and it's contents may have already escaped.

Add comments to SILType APIs (isTrivial, isReferenceCounted) that give
answers about the AST type which don't really make sense for address
SILTypes.

Add comments about CGNode's 'Value' field. I spent lots of time
attempting to tighten this down with asserts, but it's only possible
for non-content nodes. For content nodes, the node's value is highly
unpredictable and basically nonsense but needed for debugging.

Add comments about not assuming that the content nodes pointsTo edge
represents physical indirection. This matters when reasoning about
aliasing and it's a tempting assumption to make.

Add a CGNode::mergeProperties placeholder for adding node properties.

Factor out a CGNode::canAddDeferred helper for use later.

Rename `setPointsTo` to `setPointsToEdge` because it actually creates
an edge rather than just setting `pointsTo`.

Add CGNode::getValue() and related helpers to help maintain invariants.

Factor out a `markEscaping` helper.

Clean up the `escapesInsideFunction` helper.

Add node visitor helpers: visitSuccessors, visitDefers. This made is
much easier to prototype utilities.

Add comments to clarify the `pointsTo` invariant. In particular, an
entire defer web may have a null pointsTo for a while.

Add an `activeWorklist` to avoid nasty bugs when composing multiple
helpers that each use the worklist.

Remove the `EA` argument from `getNode`. I ended up needing access to
the `EA` context from the ConnectionGraph many times during
prototyping and passing `this` was all the `getNode` calls was very
silly.

Add graph visitor helpers: backwardTraverse, forwardTraverseDefer,
forwardTraversePointsToEdges, and mayReach for ease in developing new
logic and utilities.

Add isExclusiveArgument helper and distinguish exclusive arguments
from local objects. Confusing these properties could lead to scary
bugs. For example, unlike a local object, an exclusive argument's
contents may still escape even when the content's connection graph
node is non-escaping!

Add isUniquelyIdentified helper when we want to treat exclusive
arguments and local objects uniformly.

getUnderlyingAddressRoot now looks through OSSA instructions.

Rename `getAccessedMemory` to `getDirectlyAccessedMemory` with
comments. This is another dangerous API because it assumes the memory
access to a given address won't touch memory represented by different
graph nodes, but graph edges don't necessarily represent physical
indirection. Further clarify this issue in comments in
AliasAnalysis.cpp.

Factor out a 'findRecursiveRefType' helper from the old
'mayContainReference' for checking whether types may or must contain
references. Support both kinds of queries so the analysis can be
certain when a pointer's content is a physical heap object.

Factor out 'getPointerBase' and 'getPointerRoot' helpers that follow
address projections within what EscapeAnalysis will consider a single
node.

Create a CGNodeWorklist abstraction to safely formalize the worklist
mechanism that's used all over the place. In one place, there were
even two separate independent lists used independently (nodes added to
one list could appear to be in the other list).

The CGNodeMap abstraction did not significantly change, it was just moved.

Added 'dumpCG' for dumping .dot files making it possible to remote debug.

Added '-escapes-enable-graphwriter' option to dump .dot files, since
they are so much more useful than the textual dump of the connection
graph, which lacks node identity!
2019-11-06 11:07:52 -08:00
Erik Eckstein
8e21379ffc SILOptimizer: always assume that inout arguments are not aliasing
We can do that now as we have exclusivity checking
2019-10-14 16:35:50 +02:00
Andrew Trick
1abeddcc5d [SILType] SILFunctionConventions API.
Separate formal lowered types from SIL types.
The SIL type of an argument will depend on the SIL module's conventions.
The module conventions are determined by the SIL stage and LangOpts.

Almost NFC, but specialized manglings are broken incidentally as a result of
fixes to the way passes handle book-keeping of aruments. The mangler is fixed in
the subsequent commit.

Otherwise, NFC is intended, but quite possible do to rewriting the logic in many
places.
2017-01-26 15:35:48 -08:00
practicalswift
6d1ae2a39c [gardening] 2016 → 2017 2017-01-06 16:41:22 +01:00
practicalswift
797b80765f [gardening] Use the correct base URL (https://swift.org) in references to the Swift website
Remove all references to the old non-TLS enabled base URL (http://swift.org)
2016-11-20 17:36:03 +01:00
John McCall
e249fd680e Destructure result types in SIL function types.
Similarly to how we've always handled parameter types, we
now recursively expand tuples in result types and separately
determine a result convention for each result.

The most important code-generation change here is that
indirect results are now returned separately from each
other and from any direct results.  It is generally far
better, when receiving an indirect result, to receive it
as an independent result; the caller is much more likely
to be able to directly receive the result in the address
they want to initialize, rather than having to receive it
in temporary memory and then copy parts of it into the
target.

The most important conceptual change here that clients and
producers of SIL must be aware of is the new distinction
between a SILFunctionType's *parameters* and its *argument
list*.  The former is just the formal parameters, derived
purely from the parameter types of the original function;
indirect results are no longer in this list.  The latter
includes the indirect result arguments; as always, all
the indirect results strictly precede the parameters.
Apply instructions and entry block arguments follow the
argument list, not the parameter list.

A relatively minor change is that there can now be multiple
direct results, each with its own result convention.
This is a minor change because I've chosen to leave
return instructions as taking a single operand and
apply instructions as producing a single result; when
the type describes multiple results, they are implicitly
bound up in a tuple.  It might make sense to split these
up and allow e.g. return instructions to take a list
of operands; however, it's not clear what to do on the
caller side, and this would be a major change that can
be separated out from this already over-large patch.

Unsurprisingly, the most invasive changes here are in
SILGen; this requires substantial reworking of both call
emission and reabstraction.  It also proved important
to switch several SILGen operations over to work with
RValue instead of ManagedValue, since otherwise they
would be forced to spuriously "implode" buffers.
2016-02-18 01:26:28 -08:00
Erik Eckstein
aef0a11a7c remove some unneeded forward declearations 2016-01-25 15:00:49 -08:00
Erik Eckstein
b745691a38 SIL refactoring: Move some functions out of SILValue and Operand
SILValue.h/.cpp just defines the SIL base classes. Referring to specific instructions is a (small) kind of layering violation.
Also I want to keep SILValue small so that it is really just a type alias of ValueBase*.
NFC.
2016-01-25 10:37:03 -08:00
practicalswift
1339b5403b Consistent use of header comment format.
Correct format:
//===--- Name of file - Description ----------------------------*- Lang -*-===//
2016-01-04 13:26:31 +01:00
practicalswift
f91525a10f Consistent placement of "-*- [language] -*-===//" in header. 2016-01-04 09:46:20 +01:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
Erik Eckstein
c7e8cb0332 Remove now unused utility functions for escape checking.
Those functions were replaced by EscapeAnalysis.
2015-12-23 16:48:41 -08:00
Erik Eckstein
8b79b0d7f5 Change parameter of isNotAliasedIndirectParameter from bool to an enum.
And fix indentation of switch cases.
2015-12-18 12:57:21 -08:00
Erik Eckstein
fc08b60af4 add utility functions for checking not-aliased indirect function arguments. 2015-12-18 08:02:18 -08:00
Andrew Trick
84450b4c43 Reorganize SILOptimizer directories for better discoverability.
(Headers first)

It has been generally agreed that we need to do this reorg, and now
seems like the perfect time. Some major pass reorganization is in the
works.

This does not have to be the final word on the matter. The consensus
among those working on the code is that it's much better than what we
had and a better starting point for future bike shedding.

Note that the previous organization was designed to allow separate
analysis and optimization libraries. It turns out this is an
artificial distinction and not an important goal.
2015-12-11 12:34:51 -08:00