Commit Graph

64 Commits

Author SHA1 Message Date
Erik Eckstein
09755659a1 SIL: remove the sub-classes of MultipleValueInstructionResult
They are not really needed, because they don't contain any stored properties and for isa-checks we can check the parent instruction.
2021-04-11 19:14:34 +02:00
Erik Eckstein
2c7027da97 SIL: fix a header-file layering violation: SILArgument.h should not include SILFunction.h
"Containers" should include their "content" and not the other way round.
Also, remove some unused stuff of SILArgument.
2021-01-22 10:05:09 +01:00
Andrew Trick
cc0aa2f8b8 Add an AccessPath abstraction and formalize memory access
Things that have come up recently but are somewhat blocked on this:

- Moving AccessMarkerElimination down in the pipeline
- SemanticARCOpts correctness and improvements
- AliasAnalysis improvements
- LICM performance regressions
- RLE/DSE improvements

Begin to formalize the model for valid memory access in SIL. Ignoring
ownership, every access is a def-use chain in three parts:

object root -> formal access base -> memory operation address

AccessPath abstracts over this path and standardizes the identity of a
memory access throughout the optimizer. This abstraction is the basis
for a new AccessPathVerification.

With that verification, we now have all the properties we need for the
type of analysis requires for exclusivity enforcement, but now
generalized for any memory analysis. This is suitable for an extremely
lightweight analysis with no side data structures. We currently have a
massive amount of ad-hoc memory analysis throughout SIL, which is
incredibly unmaintainable, bug-prone, and not performance-robust. We
can begin taking advantage of this verifably complete model to solve
that problem.

The properties this gives us are:

Access analysis must be complete over memory operations: every memory
operation needs a recognizable valid access. An access can be
unidentified only to the extent that it is rooted in some non-address
type and we can prove that it is at least *not* part of an access to a
nominal class or global property. Pointer provenance is also required
for future IRGen-level bitfield optimizations.

Access analysis must be complete over address users: for an identified
object root all memory accesses including subobjects must be
discoverable.

Access analysis must be symmetric: use-def and def-use analysis must
be consistent.

AccessPath is merely a wrapper around the existing accessed-storage
utilities and IndexTrieNode. Existing passes already very succesfully
use this approach, but in an ad-hoc way. With a general utility we
can:

- update passes to use this approach to identify memory access,
  reducing the space and time complexity of those algorithms.

- implement an inexpensive on-the-fly, debug mode address lifetime analysis

- implement a lightweight debug mode alias analysis

- ultimately improve the power, efficiency, and maintainability of
  full alias analysis

- make our type-based alias analysis sensistive to the access path
2020-10-16 15:00:10 -07:00
Andrew Trick
5ae231eaab Rename getFieldNo() to getFieldIndex().
Do I really need to justify this?
2020-09-24 22:44:13 -07:00
swift-ci
4324c7c5ce Merge remote-tracking branch 'origin/master' into master-rebranch 2020-02-03 22:43:48 -08:00
Michael Gottesman
377b7b131e [pattern-match] Make sure that when we are extracting a tuple that we fail if we have a non-instruction result.
The specific problem here is this:

```
sil @builtin_array_opt_index_raw_pointer_to_index_addr_no_crash : $@convention(thin) (Builtin.RawPointer, Builtin.
Word) -> Builtin.Word {
bb0(%0 : $Builtin.RawPointer, %1 : $Builtin.Word):
  %2 = index_raw_pointer %0 : $Builtin.RawPointer, %1 : $Builtin.Word
  %3 = pointer_to_address %2 : $Builtin.RawPointer to [strict] $*Builtin.Word
  %4 = load %3 : $*Builtin.Word
  return %4 : $Builtin.Word
}
```

before this commit, we unconditionally called getDefiningInstruction when
looking at %1. This of course returned a null value causing the compiler to
crash in a dyn_cast<TupleExtractInst>().

rdar://59138369
2020-02-03 21:02:13 -08:00
swift-ci
1155f033a4 Merge remote-tracking branch 'origin/master' into master-next 2019-09-19 13:29:07 -07:00
Michael Gottesman
20c5dff4b5 [builtin] Implement polymorphic builtins for all BUILTIN_BINARY_OPERATIONs.
TLDR: This patch introduces a new kind of builtin, "a polymorphic builtin". One
calls it like any other builtin, e.x.:

```
Builtin.generic_add(x, y)
```

but it has a contract: it must be specialized to a concrete builtin by the time
we hit Lowered SIL. In this commit, I add support for the following generic
operations:

Type           | Op
------------------------
FloatOrVector  |FAdd
FloatOrVector  |FDiv
FloatOrVector  |FMul
FloatOrVector  |FRem
FloatOrVector  |FSub
IntegerOrVector|AShr
IntegerOrVector|Add
IntegerOrVector|And
IntegerOrVector|ExactSDiv
IntegerOrVector|ExactUDiv
IntegerOrVector|LShr
IntegerOrVector|Mul
IntegerOrVector|Or
IntegerOrVector|SDiv
IntegerOrVector|SRem
IntegerOrVector|Shl
IntegerOrVector|Sub
IntegerOrVector|UDiv
IntegerOrVector|Xor
Integer        |URem

NOTE: I only implemented support for the builtins in SIL and in SILGen. I am
going to implement the optimizer parts of this in a separate series of commits.

DISCUSSION
----------

Today there are polymorphic like instructions in LLVM-IR. Yet, at the
swift and SIL level we represent these operations instead as Builtins whose
names are resolved by splatting the builtin into the name. For example, adding
two things in LLVM:

```
  %2 = add i64 %0, %1
  %2 = add <2 x i64> %0, %1
  %2 = add <4 x i64> %0, %1
  %2 = add <8 x i64> %0, %1
```

Each of the add operations are done by the same polymorphic instruction. In
constrast, we splat out these Builtins in swift today, i.e.:

```
let x, y: Builtin.Int32
Builtin.add_Int32(x, y)
let x, y: Builtin.Vec4xInt32
Builtin.add_Vec4xInt32(x, y)
...
```

In SIL, we translate these verbatim and then IRGen just lowers them to the
appropriate polymorphic instruction. Beyond being verbose, these prevent these
Builtins (which need static types) from being used in polymorphic contexts where
we can guarantee that eventually a static type will be provided.

In contrast, the polymorphic builtins introduced in this commit can be passed
any type, with the proviso that the expert user using this feature can guarantee
that before we reach Lowered SIL, the generic_add has been eliminated. This is
enforced by IRGen asserting if passed such a builtin and by the SILVerifier
checking that the underlying builtin is never called once the module is in
Lowered SIL.

In forthcoming commits, I am going to add two optimizations that give the stdlib
tool writer the tools needed to use this builtin:

1. I am going to add an optimization to constant propagation that changes a
"generic_*" op to the type of its argument if the argument is a type that is
valid for the builtin (i.e. integer or vector).

2. I am going to teach the SILCloner how to specialize these as it inlines. This
ensures that when we transparent inline, we specialize the builtin automatically
and can then form SSA at -Onone using predictable memory access operations.

The main implication around these polymorphic builtins are that if an author is
not able to specialize the builtin, they need to ensure that after constant
propagation, the generic builtin has been DCEed. The general rules are that the
-Onone optimizer will constant fold branches with constant integer operands. So
if one can use a bool of some sort to trigger the operation, one can be
guaranteed that the code will not codegen. I am considering putting in some sort
of diagnostic to ensure that the stdlib writer has a good experience (e.x. get
an error instead of crashing the compiler).
2019-09-19 11:42:10 -07:00
Alex Langford
2e72610509 Replace last uses of llvm::index_sequence_{,for} 2019-08-15 14:07:26 -07:00
Michael Gottesman
9c58e4b0a3 [patternmatch] Add InstructionOperand_match to support for matching against instructions with misc number of operands.
NOTE:

1. To test this I changed UnaryOp_match to use this under the hood.

2. These types of m_##ID##Inst matchers now will only accept compound types and
I added a static assert to verify that this mistake doesn't happen. We
previously had matchers that would take an int or the like to match tuple
extract patterns. I converted those to use TupleExtractOperation that also
properly handles destructures.
2019-08-05 17:26:02 -07:00
Arnold Schwaighofer
c187c8ac13 SIL: Replace uses of getReferencedFunction() by getReferencedFunctionOrNull() and getInitialReferencedFunction()
With the advent of dynamic_function_ref the actual callee of such a ref
my vary. Optimizations should not assume to know the content of a
function referenced by dynamic_function_ref. Introduce
getReferencedFunctionOrNull which will return null for such function
refs. And getInitialReferencedFunction to return the referenced
function.
Use as appropriate.

rdar://50959798
2019-05-26 08:58:14 -07:00
Michael Gottesman
0cdc2d6a35 [sil] Teach constant folding how to handle destructures and multiple value instructions.
I also ported the constant_propagation.sil tests over for ownership and updated
a few parts of the cast optimizer so that those tests pass with and without
ownership. I purposely only updated the parts of the cast optimizer that crashed
with ownership in the relevant test so that I can add new sil code coverage for
those uncovered code paths.
2019-02-12 20:15:02 -08:00
Carl Peto
db24809cc1 Remove apparently obsolete builtin functions (#20947)
* Remove apparently obsolete builtin functions.

- Remove s_to_u_checked_conversion and u_to_s_checked_conversion functions from builtin AST parsing, SIL/IR generation and from SIL optimisations.

* Remove apparently obsolete builtin functions - unit tests.

- Remove unit tests for SIL transformations relating to s_to_u_checked_conversion and u_to_s_checked_conversion builtin functions.
2018-12-03 23:44:27 -08:00
Stephen Canon
a5c38d099c Revert "Remove apparently obsolete builtin functions (#20947)" (#20975)
This reverts commit b914464712, which passed the public CI bots, but broke some tests on watchOS.
2018-12-03 17:48:24 -05:00
Carl Peto
b914464712 Remove apparently obsolete builtin functions (#20947)
* Remove apparently obsolete builtin functions.

- Remove s_to_u_checked_conversion and u_to_s_checked_conversion functions from builtin AST parsing, SIL/IR generation and from SIL optimisations.

* Remove apparently obsolete builtin functions - unit tests.

- Remove unit tests for SIL transformations relating to s_to_u_checked_conversion and u_to_s_checked_conversion builtin functions.
2018-12-03 07:07:34 -05:00
David Zarzycki
476d869e55 [SIL] NFC: Adopt reference storage type meta-programming macros 2018-06-30 06:44:33 -04:00
Sho Ikeda
03fbd4a6de [gardening][SIL] Replace typedef with using 2018-04-05 13:53:20 +09:00
Joe Shajrawi
f732ea66ef Builtins: add ValueToBridgeObject instruction 2018-02-12 13:27:59 +02:00
Chris Lattner
415cd50ba2 Reduce array abstraction on apple platforms dealing with literals (#13665)
* Reduce array abstraction on apple platforms dealing with literals

Part of the ongoing quest to reduce swift array literal abstraction
penalties: make the SIL optimizer able to eliminate bridging overhead
 when dealing with array literals.

Introduce a new classify_bridge_object SIL instruction to handle the
logic of extracting platform specific bits from a Builtin.BridgeObject
value that indicate whether it contains a ObjC tagged pointer object,
or a normal ObjC object. This allows the SIL optimizer to eliminate
these, which allows constant folding a ton of code. On the example
added to test/SILOptimizer/static_arrays.swift, this results in 4x
less SIL code, and also leads to a lot more commonality between linux
and apple platform codegen when passing an array literal.

This also introduces a couple of SIL combines for patterns that occur
in the array literal passing case.
2018-01-02 15:23:48 -08:00
Slava Pestov
0acf3ac8d9 SIL: Remove is_nonnull instruction 2017-10-13 17:38:32 -07:00
Slava Pestov
e806b6248d SIL: Remove dynamic_method instruction 2017-10-04 03:53:16 -07:00
Slava Pestov
7bf3b90b62 SIL: Split off objc_method / objc_super_method from class_method / super_method
This replaces the '[volatile]' flag. Now, class_method and
super_method are only used for vtable dispatch.

The witness_method instruction is still overloaded for use
with both ObjC protocol requirements and Swift protocol
requirements; the next step is to make it only mean the
latter, also using objc_method for ObjC protocol calls.
2017-10-03 22:13:31 -07:00
John McCall
ab3f77baf2 Make SILInstruction no longer a subclass of ValueBase and
introduce a common superclass, SILNode.

This is in preparation for allowing instructions to have multiple
results.  It is also a somewhat more elegant representation for
instructions that have zero results.  Instructions that are known
to have exactly one result inherit from a class, SingleValueInstruction,
that subclasses both ValueBase and SILInstruction.  Some care must be
taken when working with SILNode pointers and testing for equality;
please see the comment on SILNode for more information.

A number of SIL passes needed to be updated in order to handle this
new distinction between SIL values and SIL instructions.

Note that the SIL parser is now stricter about not trying to assign
a result value from an instruction (like 'return' or 'strong_retain')
that does not produce any.
2017-09-25 02:06:26 -04:00
Andrew Trick
f657ad2d3a Rename *ExistentialOpaque instructions to *ExistentialValue.
These instructions have the same semantics as the *ExistentialAddr instructions
but operate directly on the existential value, not its address.

This is in preparation for adding ExistentialBoxValue instructions.
The previous name would cause impossible confusion with "opaque existentials"
and "opaque existential boxes".
2017-07-17 23:46:41 -07:00
practicalswift
492f5cd35a [gardening] Remove redundant repetition of type names (DRY): RepeatedTypeName foo = dyn_cast<RepeatedTypeName>(bar)
Replace `NameOfType foo = dyn_cast<NameOfType>(bar)` with DRY version `auto foo = dyn_cast<NameOfType>(bar)`.

The DRY auto version is by far the dominant form already used in the repo, so this PR merely brings the exceptional cases (redundant repetition form) in line with the dominant form (auto form).

See the [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es11-use-auto-to-avoid-redundant-repetition-of-type-names) for a general discussion on why to use `auto` to avoid redundant repetition of type names.
2017-05-05 09:45:53 +02:00
Joe Shajrawi
0d0cac357a retain_value_addr and release_value_addr SIL instructions: take as an input an address, load the value inside it and call retain_value and release_value respectively 2017-04-30 10:23:55 -07:00
Joe Shajrawi
16b6cb5e1d Support for deinit of opaque existentials: deinit_existential_opaque instruction + SILGen support 2017-02-27 14:46:43 -08:00
Joe Shajrawi
1e521c453b Add support for Init Existentials for opaque value types 2017-02-20 16:40:02 -08:00
Joe Shajrawi
c478828de7 Support for Open Existentials that do no take an address 2017-02-09 11:25:34 -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
Michael Gottesman
a5be2fff01 [sil] Use FullApplySite instead of ApplyInst in SILInstruction::getMemoryBehavior().
We were giving special handling to ApplyInst when we were attempting to use
getMemoryBehavior(). This commit changes the special handling to work on all
full apply sites instead of just AI. Additionally, we look through partial
applies and thin to thick functions.

I also added a dumper called BasicInstructionPropertyDumper that just dumps the
results of SILInstruction::get{Memory,Releasing}Behavior() for all instructions
in order to verify this behavior.
2016-02-23 15:00:43 -08:00
Erik Eckstein
74d44b74e7 SIL: remove SILValue::getDef and add a cast operator to ValueBase * as a repelacement. NFC. 2016-01-25 15:00:49 -08:00
practicalswift
71e00fefa1 [gardening] Fix typos: "word word" (two spaces) → "word word" (one space) 2016-01-24 21:27:16 +01:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
Ge Sen
7ac02d54ba Erase redundant whitespaces. 2015-12-10 13:35:06 +08:00
John McCall
5fddd4a704 Remove the autorelease_return and strong_retain_autoreleased instructions.
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.
2015-12-09 14:50:20 -08:00
Erik Eckstein
7f2522b92e Use getCalleeFunction in some places to simplify code. NFC 2015-11-15 18:29:54 -08:00
Slava Pestov
7cc59e01d7 SIL: Add DeallocPartialRefInst
This instruction destroys instance variables in a partially-initialized
object, then frees it.

Swift SVN r32661
2015-10-13 19:56:20 +00:00
Andrew Trick
c20370a664 Remove the last remnants of unchecked_ref_bit_cast
Swift SVN r32598
2015-10-10 05:42:57 +00:00
Mark Lacey
406fe20129 Add forward declarations for SILInstruction.
Remove the include of SILInstruction.h in a couple places since it is
not necessary and forces more recompilation than necessary when edits
are made to SILInstruction.h.

Swift SVN r32091
2015-09-19 02:48:06 +00:00
Andrew Trick
7565a65235 Introduce unchecked_bitwise_cast SIL instruction.
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
2015-06-19 16:29:35 +00:00
Joe Groff
962a87f444 SIL: Rename address-only existential instructions to '{init,deinit,open}_existential_addr'.
For better consistency with other address-only instruction variants, and to open the door to new exciting existential representations (such as a refcounted boxed representation for ErrorType).

Swift SVN r25902
2015-03-09 23:55:31 +00:00
Joe Groff
e3f9a2035c SIL: Move SILGen and passes over to use "builtin" instead of "apply (builtin_function_ref)".
Swift SVN r22785
2014-10-15 23:37:22 +00:00
Joe Groff
9205bf64cf SIL: Remove enum_is_tag.
Swift SVN r22616
2014-10-09 05:03:43 +00:00
Joe Groff
782833f054 SIL: Remove the project_existential* instructions.
Swift SVN r22457
2014-10-02 04:06:10 +00:00
Joe Groff
3a606b9eb8 SIL: Drop the protocol_method instruction.
Swift SVN r22446
2014-10-01 23:35:41 +00:00
Joe Groff
be45322668 SIL: Drop the upcast_existential* instructions.
Swift SVN r22388
2014-09-30 16:11:54 +00:00
Joe Groff
152aa9e244 Revert "SIL: Drop the upcast_existential* instructions."
This reverts commit r22345.

Swift SVN r22353
2014-09-29 13:46:41 +00:00
Joe Groff
1e343fb430 SIL: Drop the upcast_existential* instructions.
Swift SVN r22345
2014-09-28 19:24:33 +00:00