Commit Graph

87 Commits

Author SHA1 Message Date
Erik Eckstein
9b51e69dac Swift Optimizer: constant fold builtins in the simplification passes 2023-05-08 21:23:36 +02:00
Slava Pestov
43a35992fd SILOptimizer: Teach constant folding about add, sub, mul variants without overflow checks 2023-04-12 18:27:50 -04:00
Erik Eckstein
ab1b343dad use new llvm::Optional API
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`

The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.

rdar://102362022
2022-11-21 19:44:24 +01:00
Michael Gottesman
1e6187c4f4 [sil] Update all usages of old API SILValue::getOwnershipKind() in favor of new ValueBase::getOwnershipKind().
Andy some time ago already created the new API but didn't go through and update
the old occurences. I did that in this PR and then deprecated the old API. The
tree is clean, so I could just remove it, but I decided to be nicer to
downstream people by deprecating it first.
2022-07-26 11:46:23 -07:00
Andrew Trick
d3e945e27f Remove temporary InstructionDeleter in ConstantFolding.
I believe the original issue was actually fixed by:

  Add isReadOnlyConstantEvaluableCall to handle stdlib asserts #40254
  https://github.com/apple/swift/pull/40254

Fixes rdar://85849838 (Remove InstructionDeleter workaround in
ConstantPropagation)
2022-02-18 17:53:25 -08:00
Erik Eckstein
9016c2c0b3 ConstantFolding: don't constant fold availability checks in inlinable functions. 2022-01-27 13:20:38 +01:00
Andrew Trick
c3ddd94b34 Revert recent dead-code elimination improvement in constant prop.
Revert part of a fix that used InstructionDeleter consistently during
ConstantPropagation. This had a side effect of removing more dead code
at -Onone. For some reason, that breaks SIL linkage. This showed up
when rebuilding the Foundation module against a debug (-Onone)
standard library, and verifying Data.InlineData.subscript.getter.

Fixes rdar://85809683 (Swift CI: SIL verification failed: external
declarations of SILFunctions with shared visibility is not allowed:
SingleFunction || !hasSharedVisibility(RefF->getLinkage()) ||
RefF->hasForeignBody())
2021-11-29 15:31:28 -08:00
Andrew Trick
f9d31ca116 InstructionDeleter ctor moves callbacks to fix iterator invalidation
The InstructionDeleter needs to move the callbacks during construction
to prevent the client code from using the old callbacks.

Fixes iterator invalidation bugs.
2021-11-18 11:38:08 -08:00
Andrew Trick
c86d112891 Update #include for InstructionDeleter.h 2021-11-18 11:38:08 -08:00
Erik Eckstein
bec687db1b ConstantFolding: remove a wrong peephole optimization for signed "< 0" and ">= 0" comparisons
The wrong optimization was: fold x < 0 into false, if x is known to be a result of an unsigned operation with overflow checks enabled.
It was done under the wrong assumption that the result of an overflow-checked unsigned operation fits into a signed integer and is positive.
This is wrong, because the result of an unsigned operation can be larger than Int.max and therefore, when used in a signed integer operation, be re-interpreted as a negative signed value.

Fixes a miscompile which resulted in a missing abort on arithmetic overflow.

rdar://73596890
2021-10-27 14:20:19 +02:00
Kuba (Brecka) Mracek
b413a0f4dd Add Builtin.ifdef_<FLAGNAME> as a facility to peek at -D flag that client code is building with (#39797) 2021-10-21 15:36:47 -07:00
swift-ci
cb32b553de Merge remote-tracking branch 'origin/main' into rebranch 2021-09-04 11:32:57 -07:00
Hamish Knight
cead30d639 [SIL] Adopt ArgumentList 2021-09-01 18:40:27 +01:00
swift-ci
2aedbaa7ef Merge remote-tracking branch 'origin/main' into rebranch 2021-08-10 12:13:26 -07:00
Hamish Knight
e82edadee7 Remove some obsolete literal handling logic
We no longer convert literals into constructor
calls in Sema, SILGen emits the necessary calls.
2021-08-06 17:07:22 +01:00
Evan Wilde
9bd93db2be Update all the APInt toStrings
Just went through and updated the rest of the APInt toString calls.
This should take care of them, I hope.
2021-06-25 10:44:13 -07:00
Andrew Trick
0f88e0f3cc Rewrite instruction deletion logic in many passes
Fix innumerable latent bugs with iterator invalidation and callback invocation.

Removes dead code earlier and chips away at all the redundant copies the compiler generates.
2021-06-02 07:38:27 -07:00
Michael Gottesman
7b55cbc669 [sil-optimizer] Make InstructionDeleter and related APIs to use an InstModCallback instead of a notification callback.
I recently have been running into the issue that many of these APIs perform the
deletion operation themselves and notify the caller it is going to delete
instead of allowing the caller to specify how the instruction is deleted. This
causes interesting semantic issues (see the loop in deleteInstruction I
simplified) and breaks composition since many parts of the optimizer use
InstModCallbacks for this purpose.

To fix this, I added a notify will be deleted construct to InstModCallback. In a
similar way to the rest of it, if the notify is not set, we do not call any code
implying that we should have good predictable performance in loops since we will
always skip the function call.

I also changed InstModCallback::deleteInst() to notify before deleting so we
have a default safe behavior. All previous use sites of this API do not care
about being notified and the only new use sites of this API are in
InstructionDeleter that perform special notification behavior (it notifies for
certain sets of instructions it is going to delete before it deletes any of
them). To work around this, I added a bool to deleteInst to control this
behavior and defaulted to notifying. This should ensure that all other use sites
still compose correctly.
2021-04-26 16:37:43 -07:00
Azoy
9ed732f0ab Introduce isDecl and getDeclType
fix enum logic issue

fix tests

guard against null types
2021-04-20 02:22:16 -04:00
Arnold Schwaighofer
30ac6e6440 Constant fold known availability checks
rdar://73408505
2021-01-20 10:00:31 -08:00
Meghana Gupta
68ec810b32 Rename stripOwnershipInsts to lookThroughCopyValueInsts 2020-12-22 22:01:55 -08:00
Michael Gottesman
c026e95cce [ownership] Extract out SILOwnershipKind from ValueOwnershipKind into its own type and rename Invalid -> Any.
This makes it easier to understand conceptually why a ValueOwnershipKind with
Any ownership is invalid and also allowed me to explicitly document the lattice
that relates ownership constraints/value ownership kinds.
2020-11-10 14:29:11 -08:00
Andrew Trick
5ae231eaab Rename getFieldNo() to getFieldIndex().
Do I really need to justify this?
2020-09-24 22:44:13 -07:00
Erik Eckstein
63c275c45f SILOptimizer: move String concatination optimization from SILCombine/ConstantFolding to StringOptimization.
This simplifies some code and it's not required to try this optimization on every run of SILCombine and ConstantPropagation.
2020-08-04 16:16:11 +02:00
Saleem Abdulrasool
fa46f7131c sprinkle some llvm_unreachable for MSVC (NFC)
MSVC does not realize that the switch is exhaustive and requires that
the path is explicitly marked as unreachable.  This silences the C4715
warning ("not all control paths return a value").
2020-04-24 18:59:07 -07:00
Stephen Canon
248c554524 Add Float16 to stdlib (#30130)
Add Float16 (IEEE 754 binary16) to the standard library, plus assorted runtime support operations.

Swift Evolution thread: https://forums.swift.org/t/se-0277-float16/33546
2020-04-06 17:57:44 -04:00
Jonas Devlieghere
4db7f40686 Update for upstream intrinsics change (NFC)
The Intrinsic ID is now an opaque typedef to facilitate splitting up
the enum into target-specific enums.
2020-01-03 10:53:22 -08:00
Ravi Kandhadai
935686460c [SIL Optimization] Create a new utility InstructionDeleter to delete instructions
and eliminate dead code. This is meant to be a replacement for the utility:
recursivelyDeleteTriviallyDeadInstructions. The new utility performs more aggresive
dead-code elimination for ownership SIL.

This patch also migrates most non-force-delete uses of
recursivelyDeleteTriviallyDeadInstructions to the new utility.
and migrates one force-delete use of recursivelyDeleteTriviallyDeadInstructions
(in IRGenPrepare) to use the new utility.
2019-12-18 13:17:17 -08:00
zoecarver
12883d07d9 Merge branch 'master' into semantics-def 2019-11-19 13:02:47 -08:00
zoecarver
2ca448b23d Address review comments
* add namespace
* fix block comment style
* SEMA_ATTR -> SEMANTICS_ATTR
* error when SEMANTICS_ATTR isn't defined
2019-11-02 21:58:26 -07:00
Michael Gottesman
719ee25693 [constant-folding] When simplifying destructures, do not handle cases where we have a non-trivial value with .none ownership.
In certain cases, in OSSA, non-trivial values with .none ownership can be merged
into .owned aggregates such that when we extract the value back out from the
aggregate we lost the information that the original value was not .owned. As an
example of this consider the following SIL:

bb0(%0 : @owned Builtin.NativeObject):
  %1 = enum $Optional<Builtin.NativeObject>, #Optional.none!enumelt
  %2 = tuple(%0 : $Builtin.NativeObject, %1 : $Optional<Builtin.NativeObject>)
  (%3, %4) = destructure_tuple %2 : $(Builtin.NativeObject, Optional<Builtin.NativeObject>)

In this case, %4 has .owned ownership, while %1 has .none ownership. This is
because we have lost the refined information that we originally had a .none
value as input to the tuple we are destructuring. Due to this when we RAUW, we
would need to insert a destroy on %4 to make sure that we maintain ossa
invariants. This is safe since the destroy_value will be on a dynamically .none
value, which is a no-op.

That being said, the intention here was actually not to implement this pattern
in the code (as can be seen by not handling @owned destructures). Thus this
commit just makes the constant folding code more conservative to ensure that we
do not try to handle this case.
2019-11-02 14:34:30 -07:00
zoecarver
9c1a614efb Fix based on review comments 2019-11-02 13:07:20 -07:00
zoecarver
d4129d8659 Add def file for semantics attributes and use constants instead of cstring literals 2019-11-02 11:36:13 -07:00
Michael Gottesman
8cb8e7512e [constant-folding] Eliminate complexity introducing pre-mature optimization.
The code that is deleted in this PR attempted to save a bit of compile time by:

1. Checking if after constant folding we have a tuple that is immediately tuple
   extracted from.
2. RAUW the tuple extracts directly from the tuple's operands.

This adds a bunch of complexity to the pass and also moves code that should be
in a visitor into the main pass workloop function.

After this PR what happens instead is that after we fold, we add the tuple to
the worklist. Then during the next iteration we look at the tuple_extract users
and simplify them at that point.
2019-10-31 13:13:22 -07:00
Ravi Kandhadai
ffd3fef199 [OSLogOptimization] Create a SIL test for OSLogOptimization pass to test folding logic,
add -enable-ownership-stripping-after-serialization flag to OSLog optimization tests,
and update the folding logic and end-of-use discovery logic to handle ownership
and non-ownership SIL.
2019-10-28 15:33:01 -07:00
Michael Gottesman
16b1765c95 [constant-folding] Remove unneeded code.
recursivelyDeleteTriviallyDeadInstructions will handle this for us when it
deletes the instruction. So in fact, this was actually a use of an invalid
pointer. Good thing we never dereferenced it.
2019-10-27 22:03:11 -07:00
Andrew Trick
bddc69c8a6 Organize SILOptimizer/Utils headers. Remove Local.h.
The XXOptUtils.h convention is already established and parallels
the SIL/XXUtils convention.

New:
- InstOptUtils.h
- CFGOptUtils.h
- BasicBlockOptUtils.h
- ValueLifetime.h

Removed:
- Local.h
- Two conflicting CFG.h files

This reorganization is helpful before I introduce more
utilities for block cloning similar to SinkAddressProjections.

Move the control flow utilies out of Local.h, which was an
unreadable, unprincipled mess. Rename it to InstOptUtils.h, and
confine it to small APIs for working with individual instructions.
These are the optimizer's additions to /SIL/InstUtils.h.

Rename CFG.h to CFGOptUtils.h and remove the one in /Analysis. Now
there is only SIL/CFG.h, resolving the naming conflict within the
swift project (this has always been a problem for source tools). Limit
this header to low-level APIs for working with branches and CFG edges.

Add BasicBlockOptUtils.h for block level transforms (it makes me sad
that I can't use BBOptUtils.h, but SIL already has
BasicBlockUtils.h). These are larger APIs for cloning or removing
whole blocks.
2019-10-02 11:34:54 -07:00
Michael Gottesman
534781ef8c [global-string-table] Fix for ownership.
This involves teaching the constant folder to look through a borrow when trying
to find the string literal. I also added an additional run with ownership
lowering after diagnostics enabled to make sure this doesn't break again.
2019-10-01 21:18:39 -07:00
Michael Gottesman
22f580e5c6 [polymorphic-builtin] Fix ASAN error. 2019-09-20 11:35:07 -07:00
Michael Gottesman
9864cb9c06 [polymorphic-builtins] Teach constant folding how to fold a polymorphic builtin to its static overload if the passed in type is a concrete builtin type
Specifically, this transforms:

builtin "generic_add"<Builtin.Vec4xInt32>(

  ->

builtin "add_Vec4xInt32"(

If we do not have a static overload for the type, we just leave the generic call
alone. If the generic builtin takes addresses as its arguments (i.e. 2x
in_guaranteed + 1x out), we load the arguments, evaluate the static overloaded
builtin and then store the result into the out parameter.
2019-09-19 17:10:14 -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
Nikolai Vazquez
931ab4633b Remove unused call to constantFoldIsConcrete 2019-08-27 16:51:10 -07:00
Nikolai Vazquez
c4cd641cbf Fix variable reference in ConstantFolding phase 2019-08-27 16:51:09 -07:00
Nikolai Vazquez
ba0612f2e9 Add Builtin.isConcrete<T>(T.Type) -> Int1
Returns `true` if `T.Type` is known to refer to a concrete type. The
implementation allows for the optimizer to specialize this at -O and
eliminate conditional code.

Includes `Swift._isConcrete<T>(T.Type) -> Bool` wrapper function.
2019-08-27 16:51:09 -07:00
Michael Gottesman
7e6b07c307 [constant-folding] Visit struct, tuple when we initialize our worklist as well as when we are processing the worklist.
This simplifies the IR and eliminates in a certain sense "constant information"
from the IR by allowing us to remove extract, nominal literal round trips.

NOTE: I had to modify the pound_assert test slightly on the location of a note
that it emits. The reason that I did this is that the test output is technically
correct. The instruction we are interpreting when we error is (after this
commit), a debug_value in the prelude of the function (and thus has the new
location). I am going to talk with Ravi and others on what to do with this.
2019-08-12 03:32:59 -07:00
Michael Gottesman
297f48a7c2 [constant-folding] Fix asan error. 2019-08-12 01:51:43 -07:00
Michael Gottesman
dff965f912 [constant-folding] Teach constant folding how to transform Builtin.cond_fail => cond_fail.
When this was originally implemented, this transform was put into
SILCombine. This patch also puts it into constant folding so we can also perform
the transform at -Onone.

My hunch is that the reason why this isn't happening with the -Onone
serialization change is that we were relying only this code being specialized
before serialization in the stdlib. But transparent functions are now not
optimized until after serialization, so it isn't done. Rather than mess with
that, I just added the support here.
2019-08-11 17:21:42 -07:00
Michael Gottesman
70666486c6 [constant-folding] Teach constant folding how to remove (int_to_ptr (ptr_to_int)).
I put in a little bit of infrastructure that should provide the appropriate
places for adding information about other cases where we can run into this with
other casts.

The reason I added this is that the codegen around condfail_message has changed
slightly and thus has this round trip in it, messing with various pattern
matching routines.

Example:

```
%x = string_literal
%x1 = ptr_to_int %x    // <=== This messes with pattern matching from
%x2 = int_to_ptr %x1   // <=== the cond_fail to %x.
cond_fail(%x2)
```

=>

```
%x = string_literal    // <=== Happiness = ).
cond_fail(%x)
```
2019-08-11 14:43:28 -07:00
Jordan Rose
844ae38722 Remove some Swift STLExtras that LLVM now provides (#26443)
No functionality change.
2019-07-31 18:34:52 -07:00
Ravi Kandhadai
37f524e647 [Constant Folding][OSLogOptimization] Fold the uses of the builtin
"globalStringTablePointer": String -> Builtin.RawPointer` to a
string_literal instruction if the string that is passed is constructed
from a literal. Otherwise, emit diagnostics.
2019-07-03 16:47:34 -07:00