Commit Graph

4580 Commits

Author SHA1 Message Date
Michael Gottesman
aeceaf7d78 Merge pull request #40478 from gottesmm/pr-cfbd8a7087ef5ca3ec578da8993a686ad7a50077
[move-function] Add support for loadable vars
2021-12-09 16:19:39 -08:00
Michael Gottesman
4a9c26ff96 [move-function] Make MandatoryInlining always convert builtin.move -> mark_unresolved_move_addr.
To give a bit more information, currently the way the move function is
implemented is that:

1. SILGen emits a builtin "move" that is called within the function _move in the
   stdlib.

2. Mandatory Inlining today if the final inlined type is address only, inlines
   builtin "move" as mark_unresolved_move_addr. Otherwise, if the inlined type
   is loadable, it performs a load [take] + move [diagnostic] + store [init].

3. In the diagnostic pipeline before any mem optimizations have run, we run the
   move checker for addresses. This eliminates /all/ mark_unresolved_move_addr
   as part of emitting diagnostics. In order to make this work, we perform a
   small optimization before the checker runs that moves the
   mark_unresolved_move_addr from being on temporary alloc_stacks to the true
   base underlying address we are trying to move. This optimization is necessary
   since _move is generic and often times SILGen will emit this temporary that
   we do not want.

4. Then after we have run the guaranteed mem optimizations, we run the object
   based move checker emitting diagnostics.

This PR changes the scheme above to the following:

1. SILGen emits a builtin "move" that is called within the function _move in the
   stdlib.

2. Mandatory Inlining inlines builtin "move" as mark_unresolved_move_addr.

3. In the diagnostic pipeline before we have run any mem optimizations and
   before we have run the actual move address checker, we massage the IR as we
   do above but in a separate pass where in addition we try to match this pattern:

     ```
     %temporary = alloc_stack $LoadableType
     store %1 to [init] %temporary : $*LoadableType
     mark_unresolved_move_addr %temporary to %otherAddr : $*LoadableType
     destroy_addr %temporary : $*LoadableType
     ```

   and transform it to:

     ```
     %temporary = alloc_stack $LoadableType
     %2 = move_value [allows_diagnostics] %1 : $*LoadableType
     store %2 to [init] %temporary : $*LoadableType
     destroy_addr %temporary : $*LoadableType
     ```

   ensuring that the object move checker will handle this.

4. Then after we have run the guaranteed mem optimizations, we run the object
   based move checker emitting diagnostics.
2021-12-09 12:48:29 -08:00
Zoe Carver
a46a3c525a Merge pull request #39605 from zoecarver/cxx-interop-import-as-class
[cxx-interop] Implement foreign reference types.
2021-12-08 19:33:50 +00:00
zoecarver
fc3b3a1d71 [cxx-interop] Implement foreign reference types.
This is an expiremental feature to allow an attribute, `import_as_ref`, to import a C++ record as a non-reference-counted reference type in Swift.
2021-12-08 15:35:18 +00:00
Nate Chandler
f0bd5839a2 [OwnershipUtils] Extracted utility for common use.
Promoted isRedundantLexicalBeginBorrow function to OwnershipUtils so
that it can be used in more than just SemanticARCOpts.
2021-12-07 17:51:18 -08:00
Nate Chandler
cde250a3e3 [CopyPropagation] Add ShrinkBorrowScope.
During copy propagation (for which -enable-copy-propagation must still
be passed), also try to shrink borrow scopes by hoisting end_borrows
using the newly added ShrinkBorrowScope utility.

Allow end_borrow instructions to be hoisted over instructions that are
not deinit barriers for the value which is borrowed.  Deinit barriers
include uses of the value, loads of memory, loads of weak references
that may be zeroed during deinit, and "synchronization points".

rdar://79149830
2021-12-07 09:43:57 -08:00
Michael Gottesman
e3f9eaca58 [move-function] Implement the move-function checker for address only lets. 2021-12-06 12:47:31 -08:00
Michael Gottesman
8f22966ff7 [move-function] Emit mark_unresolved_move_addr when we inline Builtin._move in a generic context.
This turns off the diagnostic that prevented the user from calling _move in such
contexts. I left that in for _copy.
2021-12-06 12:47:31 -08:00
Michael Gottesman
d74299e68d [move-function] Add a new instruction called mark_unresolved_move_addr.
This instruction is similar to a copy_addr except that it marks a move of an
address that has to be checked. In order to keep the memory lifetime verifier
happy, the semantics before the checker runs are the mark_unresolved_move_addr is
equivalent to copy_addr [init] (not copy_addr [take][init]).

The use of this instruction is that Mandatory Inlining converts builtin "move"
to a mark_unresolved_move_addr when inlining the function "_move" (the only
place said builtin is invoked).

This is then run through a special checker (that is later in this PR) that
either proves that the mark_unresolved_move_addr can actually be a move in which
case it converts it to copy_addr [take][init] or if it can not be a move, emit
an error and convert the instruction to a copy_addr [init]. After this is done
for all instructions, we loop back through again and emit an error on any
mark_unresolved_move_addr that were not processed earlier allowing for us to
know that we have completeness.

NOTE: The move kills checker for addresses is going to run after Mandatory
Inlining, but before predictable memory opts and friends.
2021-12-06 12:47:29 -08:00
Michael Gottesman
5d5b0daf9c [silgen] Add the lexical flag on more alloc_stack that are used to represent variables.
And update all of the tests.
2021-12-03 14:33:00 -08:00
swift-ci
373a2bffa4 Merge pull request #40374 from gottesmm/pr-d0ec3f8f6e01340a26b31191a360af58a9533a50 2021-12-02 15:53:18 -08:00
Michael Gottesman
ef23e1fcca [debug-utils] Add a new utility getDebugVarName to translate a SILValue to a potential debug name.
If we don't find a name, we just return unknown so code that uses this still
gets valid output.
2021-12-02 12:02:11 -08:00
Andrew Trick
056ebe3514 Add Builtin.assumeAlignment(RawPointer, Int64) 2021-11-30 11:53:58 -08:00
Michael Gottesman
a89955ba95 Merge pull request #40201 from gottesmm/pr-37acc70949f783d302c5ba7e99f6fbe5fb7baaed
[move-operator] Start having SILGen emit lexical lifetimes and teach the optimizer how to maintain lexical lifetimes until the lexical lifetime elimination.
2021-11-30 02:15:26 -08:00
Michael Gottesman
1ea21dbf87 Merge pull request #40287 from gottesmm/pr-8bb19fcfe173f5e7b33ddd95dcbc5566be2262b8
[sil] Ban casting AnyObject with a guaranteed ownership forwarding checked_cast_br and fix up semantic-arc-opts given that.
2021-11-29 21:26:32 -08:00
Michael Gottesman
785153045b [move-operator] Start having SILGen emit lexical lifetimes and teach the optimizer how to maintain lexical lifetimes until the lexical lifetime elimination.
I am doing this so that I can use lexical lifetimes to emit diagnostics such as
the move operator diagnostics.
2021-11-29 18:02:13 -08:00
Michael Gottesman
8e5fb2164a [sil] Ban casting AnyObject with a guaranteed ownership forwarding checked_cast_br and fix up semantic-arc-opts given that.
The reason why I am doing this is that currently checked_cast_br of an AnyObject
may return a different value due to boxing. As an example, this can occur when
performing a checked_cast_br of a __SwiftValue(AnyHashable(Klass())).

To model this in SIL, I added to OwnershipForwardingMixin a bit of information
that states if the instruction directly forwards ownership with a default value
of true. In checked_cast_br's constructor though I specialize this behavior if
the source type is AnyObject and thus mark the checked_cast_br as not directly
forwarding its operand. If an OwnershipForwardingMixin directly forwards
ownership, one can assume that if it forwards ownership, it will always do so in
a way that ensures that each forwarded value is rc-identical to whatever result
it algebraically forwards ownership to. So in the context of checked_cast_br, it
means that the source value is rc-identical to the argument of the success and
default blocks.

I added a verifier check to CheckedCastBr that makes sure that it can never
forward guaranteed ownership and have a source type of AnyObject.

In SemanticARCOpts, I modified the code that builds extended live ranges of
owned values (*) to check if a OwnershipForwardingMixin is directly
forwarding. If it is not directly forwarding, then we treat the use just as an
unknown consuming use. This will then prevent us from converting such an owned
value to guaranteed appropriately in such a case.

I also in SILGen needed to change checked_cast_br emission in SILGenBuilder to
perform an ensurePlusOne on the input operand (converting it to +1 with an
appropriate cleanup) if the source type is an AnyObject. I found this via the
verifier check catching this behavior from SILGen when compiling libswift. This
just shows how important IR verification of invariants can be.

(*) For those unaware, SemanticARCOpts contains a model of an owned value and
all forwarding uses of it called an OwnershipLiveRange.

rdar://85710101
2021-11-29 15:39:00 -08:00
Erik Eckstein
f97876c9e7 RLE: better handling of ref_element/tail_addr [immutable]
Rerun RLE with cutting off the base address of loads at `ref_element/tail_addr [immutable]`. This increases the chance of catching loads of immutable COW class properties or elements.
2021-11-29 09:41:05 +01:00
Erik Eckstein
27dc5afb10 libswift: add a few utilities
* add the IntegerLiteralInst + the Builder function to create it
* add Value.nonDebugUses
* add a general utility Sequence.isEmpty
* add PassContext.replaceAllUses
* add a function to erase all `debug_value` uses in PassContext.erase
2021-11-29 09:41:05 +01:00
Saleem Abdulrasool
6785663a26 SIL: support non-clang compilers again
The toolchain has traditionally been buildable with clang, cl (MSVC),
and gcc.  `__has_feature` is a clang-specific directive, ensure that we
are portable to other compilers by providing a definition of the macro
incase it is not available (which also includes older clang releases).
2021-11-26 09:12:56 -08:00
Meghana Gupta
39f74bb980 Merge pull request #40002 from meg-gupta/newfixoutliner
Fix OSSA Outliner for scoped guaranteed values
2021-11-17 15:39:36 -08:00
Michael Gottesman
3eba144b83 Merge pull request #40189 from gottesmm/pr-aeffd0309402b8c9a744770c71ce40ca6f0459ff
[move-operator] Specify if LexicalLifetimes is enabled using an enum instead of a bool.
2021-11-15 16:47:38 -08:00
Michael Gottesman
72eb5e2eec [move-operator] Specify if LexicalLifetimes is enabled using an enum instead of a bool.
The reason why I am doing this is that we are going to be enabling lexical
lifetimes early in the pipeline so that I can use it for the move operator's
diagnostics.

To make it easy for passes to know whether or not they should support lexical
lifetimes, I included a query on SILOptions called
supportsLexicalLifetimes. This will return true if the pass (given the passed in
option) should insert the lexical lifetime flag. This ensures that passes that
run in both pipelines (e.x.: AllocBoxToStack) know whether or not to set the
lexical lifetime flag without having to locally reason about it.

This is just chopping off layers of a larger patch I am upstreaming.

NOTE: This is technically NFC since it leaves the default alone of not inserting
lexical lifetimes at all.
2021-11-15 13:47:22 -08:00
Andrew Trick
90c0c8b60f Add rebind_memory SIL instruction.
Required for UnsafeRawPointer.withMemoryReboud(to:).

%out_token = rebind_memory %0 : $Builtin.RawPointer to %in_token

%0 must be of $Builtin.RawPointer type

%in_token represents a cached set of bound types from a prior memory state.

%out_token is an opaque $Builtin.Word representing the previously bound
types for this memory region.

This instruction's semantics are identical to ``bind_memory``, except
that the types to which memory will be bound, and the extent of the
memory region is unknown at compile time. Instead, the bound-types are
represented by a token that was produced by a prior memory binding
operation. ``%in_token`` must be the result of bind_memory or
2021-11-14 22:44:46 -08:00
Andrew Trick
17fef2fb1e Give bind_memory a token result.
Required for UnsafeRawPointer.withMemoryRebound(to:)

%token = bind_memory %0 : $Builtin.RawPointer, %1 : $Builtin.Word to $T

%0 must be of $Builtin.RawPointer type

%1 must be of $Builtin.Word type

%token is an opaque $Builtin.Word representing the previously bound types
for this memory region.
2021-11-14 22:04:46 -08:00
Michael Gottesman
06039917bd Merge pull request #40162 from gottesmm/pr-7573070cdfd753af9f3f7dc3bf3a5f64359710c1
[moveOnly] Add a new pass called the LexicalLifetimeEliminator that runs after we finish lexical diagnostics.
2021-11-13 17:01:31 -08:00
Michael Gottesman
d526f36dc0 [moveOnly] Add a new pass called the LexicalLifetimeEliminator that runs after we finish lexical diagnostics.
NOTE: This pass is disabled when -enable-experimental-lexical-lifetimes is
enabled.

When that flag is disabled, this removes the lexical flag from begin_borrow and
alloc_stack. This ensures that we can begin using begin_borrow [lexical] and
friends to emit diagnostics without impacting performance. I am going to be
preparing a subsequent patch that causes us to emit lexical lifetimes by
default. Due to this pass, I am not expecting any issues around perf.
2021-11-12 13:17:02 -08:00
Robert Widmann
2c993d01bf Merge pull request #40137 from compnerd/ints-for-all
SIL: correct the definition of `SwiftInt`
2021-11-11 14:55:41 -08:00
Saleem Abdulrasool
1eade544c3 SIL: correct the definition of SwiftInt
`Int` in Swift is defined to be `intptr_t`.  `long` is equivalent, but
not portable as it relies on `LP64` which is not guaranteed (Windows is
LLP64, not LP64).  This corrects the definition to be more portable.
2021-11-11 08:03:54 -08:00
Joe Groff
5c404acbde SIL: More robust substituted function type lowering.
This change separates out the formation of the generic signature and
substitutions for a SIL substituted function type as a pre-pass
before doing the actual function type lowering. The only input we
really need to form this signature is the original abstraction pattern
that a type is being lowered against, and pre-computing it should make
the code less side-effecty and confusing. It also allows us to handle
generic nominal types in a more robust way; we transfer over all of
the nominal type requirements to the generalized generic signature,
then when recursively visiting the bindings, we same-type-constrain
the generic parameters used in those requirements to the newly-generalized
generic arguments. This ensures that the minimized signature preserves
any non-trivial requirements imposed by the nominal type, such as
conditional conformances on its type arguments, same-type constraints
among associated types, etc.

This approach does lead to less-than-optimal generalized generic
signatures getting generated, since nominal type generic arguments
get same-type-bound either to other generic arguments or fixed to
concrete types almost always. It would be useful to do a minimization
pass on the final generic signature to eliminate these unnecessary
generic arguments, but that can be done in a follow-up PR.
2021-11-10 12:45:34 -08:00
Michael Gottesman
8f062adedc Merge pull request #40017 from gottesmm/pr-a66d3d5fb98774eb8736a7507948a18b05510673
[sil] Add SILValue::dump() for use in the debugger.
2021-11-07 12:38:53 -08:00
Michael Gottesman
4aa4ac3027 [moveOnly] Add checker that validates that if a let/param copyable value has _move applied to it, the let doesn't have any later uses.
This is just an initial prototype for people to play with. It is as always
behind the -enable-experimental-move-only flag.

NOTE: In this PR I implemented this only for 'local let' like things (local
lets/params). I did not implement in this PR support for local var and haven't
done anything with class ivars or globals.

rdar://83957028
2021-11-04 17:13:29 -07:00
Michael Gottesman
99d87c35f8 [moveOnly] Allow for move_value to have an optional [allows_diagnostics] modifier.
This is a signal to the move value kill analysis that this is a move that should
have diagnostics emitted for it. It is a temporary addition until we add
MoveOnly to the SIL type system.
2021-11-04 17:13:29 -07:00
Michael Gottesman
a670a34f75 [sil] Add SILValue::dump() for use in the debugger.
It just trampolines to calling ValueBase::dump(). The reason I added this is
sometimes one wants to do this in the debugger and confuses if one has a
ValueBase or a SILValue causing lldb to be unhappy. By mirroring this API, one
can do the same operation on either type and just move on with ones life.

I also wrapped this in LLVM_ATTRIBUTE_DEPRECATED with a msg saying only for use
in the debugger so people do not call dump() in the codebase by mistake.
2021-11-02 09:55:17 -07:00
Erik Eckstein
5321a7cae8 SIL: Only enable instruction leaks checking in the frontend's and SILOpt's modules.
Leaks checking is not thread safe and e.g. lldb creates multiple SILModules in multiple threads, which would result in false alarms.
Ideally we would make it thread safe, e.g. by putting the instruction counters in the SILModule, but this would be a big effort and it's not worth doing it. Leaks checking in the frontend's and SILOpt's SILModule (not including SILModules created for module interface building) is a good enough test.

rdar://84688015
2021-11-02 10:23:46 +01:00
Meghana Gupta
59cb243385 Add a new utility to mark a new block as reachable in DeadEndBlocks 2021-11-01 14:03:22 -07:00
Michael Gottesman
4cd1201bab [noImplicitCopy] Add support for marking a SILArgument as being a NoImplicitCopy argument.
I am purposely doing this in SILGen rather than at the type system level to
avoid having to have to add a bunch of boilerplate to the type system. Instead
of doing that, I am in SILGen checking for the isNoImplicitCopy bit on the
ParamDecl when we emit arguments. At that point, I set on the specific
SILArgument being emitted the bit that it is no implicit copy. In terms of
printing at the SIL level, I just printed it in front of the function argument
type like @owned, e.x.:

  func myFunc(_ x: @_noImplicitCopy T) -> T {
  ...
  }

becomes:

  bb0(%0 : @noImplicitCopy @owned $T):

Some notes:

* Just to be explicit, I am making it so that no implicit copy parameters by
  default are always passed at +1. The reason why I think this makes sense is
  that this is the natural way of working with a move only value.

* As always, one can not write no implicit copy the attribute without passing
  the flag -enable-experimental-move-only so this is NFC.

rdar://83957088
2021-11-01 09:34:38 -07:00
Michael Gottesman
f9122a79b7 [moveOnly] Implement a new _copy function that performs an explicit copy value.
The key thing is that the move checker will not consider the explicit copy value
to be a copy_value that can be rewritten, ensuring that any uses of the result
of the explicit copy_value (consuming or other wise) are not checked.

Similar to the _move operator I recently introduced, this is a transparent
function so we can perform one level of specialization and thus at least be
generic over all concrete types.
2021-10-29 15:37:46 -07:00
eeckstein
d5ae51130d Merge pull request #39902 from eeckstein/performance-annotations
First prototype of Performance Annotations
2021-10-29 07:39:41 +02:00
nate-chandler
03361671be Merge pull request #39939 from nate-chandler/dce/keep-outer-borrow-scope-alive-when-reborrowing
[DCE] Keep outer borrows alive when reborrowing.
2021-10-28 15:31:29 -07:00
Michael Gottesman
e5d0f386e4 [moveOnly] Add a new experimental move only checker that checks noImplicitCopy variables.
NOTE: This is only available when the flag -enable-experimental-move-only. There
are no effects when the flag is disabled.

The way that this works is that it takes advantage of the following changes to
SILGen emission:

* When SILGen initializes a let with NoImplicitCopyAttribute, SILGen now emits
a begin_borrow [lexical] + copy + move_only. This is a pattern that we can check
and know that we are processing a move only value. When performing move
checking, we check move_only as a move only value and that it isn't consumed
multiple times.

* The first point works well for emitting all diagnostics except for
initializing an additional let var. To work around that I changed let
initialization to always bind to an owned value to a move of that owned
value. There is no semantic difference since that value is going to be consumed
by the binding operation anyways so we effectively just move the cleanup from
the original value we wanted to bind to the move. We still then actually borrow
the new let value with a begin_borrow [lexical] for the new let value. This
ensures that an initialization of a let value appears to be a consuming use to
the move only value checker while ensuring that the value has a proper
begin_borrow [lexical].

Some notes on functionality:

1. This attribute can only be applied to local 'let'.

2. "print" due to how we call it today with a vararg array is treated as a
   consuming use (unfortunately).

3. I have not added the builtin copy operator yet, but I recently added a _move
   skeleton attribute so one can end the lifetimes of these values early.

4. This supports all types that are not address only types (similar to
   _move). To support full on address only types we need opaque values.

rdar://83957088
2021-10-28 11:32:22 -07:00
Erik Eckstein
ff2db93922 SIL/IRGen: analysis of runtime effects for an instruction
Define the possible runtime effects of an instruction in an enum `RuntimeEffect`.
Add a new utility `swift:getRuntimeEffect` to estimate the runtime effects of an instruction.

Also, add a mechanism to validate the correctness of the analysis in IRGen: annotate all runtime functions in RuntimeFunctions.def with the actual effect what the runtime function has or can have. Then check if the effects of emitted runtime functions for an instruction match what `getRuntimeEffect` predicts.
This check is only enabled on demand by defining the CHECK_RUNTIME_EFFECT_ANALYSIS macro in RuntimeEffect.h
2021-10-28 18:43:14 +02:00
Erik Eckstein
8229b374b1 Performance annotations: add attributes @_noLocks and @_noAllocation 2021-10-28 18:43:14 +02:00
Michael Gottesman
114789707c [moveOnly] Implement a semi-generic _move function that can be used on non-generic, non-existential values.
This patch introduces a new stdlib function called _move:

```Swift
  @_alwaysEmitIntoClient
  @_transparent
  @_semantics("lifetimemanagement.move")
  public func _move<T>(_ value: __owned T) -> T {
  #if $ExperimentalMoveOnly
    Builtin.move(value)
  #else
    value
  #endif
  }
```

It is a first attempt at creating a "move" function for Swift, albeit a skleton
one since we do not yet perform the "no use after move" analysis. But this at
leasts gets the skeleton into place so we can built the analysis on top of it
and churn tree in a manageable way. Thus in its current incarnation, all it does
is take in an __owned +1 parameter and returns it after moving it through
Builtin.move.

Given that we want to use an OSSA based analysis for our "no use after move"
analysis and we do not have opaque values yet, we can not supporting moving
generic values since they are address only. This has stymied us in the past from
creating this function. With the implementation in this PR via a bit of
cleverness, we are now able to support this as a generic function over all
concrete types by being a little clever.

The trick is that when we transparent inline _move (to get the builtin), we
perform one level of specialization causing the inlined Builtin.move to be of a
loadable type. If after transparent inlining, we inline builtin "move" into a
context where it is still address only, we emit a diagnostic telling the user
that they applied move to a generic or existential and that this is not yet
supported.

The reason why we are taking this approach is that we wish to use this to
implement a new (as yet unwritten) diagnostic pass that verifies that _move
(even for non-trivial copyable values) ends the lifetime of the value. This will
ensure that one can write the following code to reliably end the lifetime of a
let binding in Swift:

```Swift
  let x = Klass()
  let _ = _move(x)
  // hypotheticalUse(x)
```

Without the diagnostic pass, if one were to write another hypothetical use of x
after the _move, the compiler would copy x to at least hypotheticalUse(x)
meaning the lifetime of x would not end at the _move, =><=.

So to implement this diagnostic pass, we want to use the OSSA infrastructure and
that only works on objects! So how do we square this circle: by taking advantage
of the mandatory SIL optimzier pipeline! Specifically we take advantage of the
following:

1. Mandatory Inlining and Predictable Dead Allocation Elimination run before any
   of the move only diagnostic passes that we run.

2. Mandatory Inlining is able to specialize a callee a single level when it
   inlines code. One can take advantage of this to even at -Onone to
   monomorphosize code.

and then note that _move is such a simple function that predictable dead
allocation elimination is able to without issue eliminate the extra alloc_stack
that appear in the caller after inlining without issue. So we (as the tests
show) get SIL that for concrete types looks exactly like we just had run a
move_value for that specific type as an object since we promote away the
stores/loads in favor of object operations when we eliminate the allocation.

In order to prevent any issue with this being used in a context where multiple
specializations may occur, I made the inliner emit a diagnostic if it inlines
_move into a function that applies it to an address only value. The diagnostic
is emitted at the source location where the function call occurs so it is easy
to find, e.x.:

```
func addressOnlyMove<T>(t: T) -> T {
    _move(t) // expected-error {{move() used on a generic or existential value}}
}

moveonly_builtin_generic_failure.swift:12:5: error: move() used on a generic or existential value
    _move(t)
    ^
```

To eliminate any potential ABI impact, if someone calls _move in a way that
causes it to be used in a context where the transparent inliner will not inline
it, I taught IRGen that Builtin.move is equivalent to a take from src -> dst and
marked _move as always emit into client (AEIC). I also took advantage of the
feature flag I added in the previous commit in order to prevent any cond_fails
from exposing Builtin.move in the stdlib. If one does not pass in the flag
-enable-experimental-move-only then the function just returns the value without
calling Builtin.move, so we are safe.

rdar://83957028
2021-10-27 19:36:49 -07:00
Nate Chandler
5d85ad393c [SILOpt] Add utility to find guaranteed roots.
The new utility looks through ownership forwarding instructions to find
the original values with guaranteed ownership.
2021-10-27 10:44:18 -07:00
Andrew Trick
b4a47b6463 Fix findInnerTransitiveUsesForAddress; add AddressUseKind
findInnerTransitiveUsesForAddress was incorrectly returning true for
pointer escapes.

Introduce enum AddressUseKind { NonEscaping, PointerEscape, Unknown };

Clients need to handle each of these cases differently.
2021-10-12 19:58:11 -07:00
Andrew Trick
a336bcdea9 Fix findTransitiveUses to only record leaf uses.
Recording uses is now optional. This utility is also used simply to
check for PointerEscape. When uses are recorded, they are used to
extend a live range. There could be a large number of transitive uses
that we don't want to pass back to the caller.
2021-10-12 19:58:10 -07:00
Arnold Schwaighofer
8866a2dcb1 Merge pull request #39656 from aschwaighofer/delay_import_prespecializations
Delay import of prespecialized decls until generic specialization
2021-10-12 12:20:16 -07:00
Alex Hoppen
5f60aad8f1 Merge pull request #39633 from ahoppen/pr/fix-warnings
Fix a couple of build warnings
2021-10-12 12:46:23 +02:00
Arnold Schwaighofer
81dd5d9cb6 Delay import of prespecialize decls until generic specialization 2021-10-11 11:10:09 -07:00