Commit Graph

98 Commits

Author SHA1 Message Date
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
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
5910829830 [constant-prop] When replacing uses of destructure_tuple, only RAUW if we actually have uses since we may not delete the actual destructure.
The specific case where this happened here is:

```
  // Worklist = [
  %0 = struct $Int (...)
  %1 = $Klass
  %2 = tuple (%0, %1)
  (%3, %4) = destructure_tuple %2
  store %3 to [trivial] %3stack
  store %4 to [init] %4stack
```

What would happen is we would visit the destructure_tuple, replace %3 with %0
but fail to propagate %4:

```
  %0 = struct $Int (...)
  %1 = $Klass
  %2 = tuple (%0, %1)
  (%3, %4) = destructure_tuple %2
  store %0 to [trivial] %3stack
  store %4 to [init] %4stack
```

This then causes the tuple to be added to the worklist. When we visit the tuple,
we see that we have a destructure_tuple that is a user of the tuple, we see that
it still has that Struct as a user despite us having constant propagated that
component of the tuple. This then causes us to add the struct back to the
worklist despite that tuple component having no uses. Then when we visit the
struct. Which causes us to visit the tuple, etc.

rdar://49947112
2019-05-18 15:26:25 -07:00
Michael Gottesman
f7b014b95c [cast-opt] Rename CastOptimizer member vars to match the rest of the CastOptimizer.
Done using Xcode's refactoring engine.
2019-04-12 11:09:29 -07:00
Joe Shajrawi
de0287d96c [SILOptimizer] Constant Folding - Style modifications based on MichaelG’s review 2019-04-02 11:32:59 -07:00
Joe Shajrawi
1d7f98f3e3 [SILOptimizer] Add ‘llvm.cttz.*’ Intrinsic support to Constant Folding
rdar://problem/29522851
2019-04-01 16:09:27 -07:00
Ravi Kandhadai
04770f6124 [SIL Diagnostics] Fix undefined behavior due to bit shifting in ConstantFolding.cpp
<rdar://48605307>
2019-03-05 16:09:01 -08:00
Parker Schuh
5160da6a2e FloatLiteralExpr now is lowered directly into SIL.
For context, String, Nil, Bool, and Int already behave this way.

Note: Swift can compile against 80 or 64 bit floats as the builtin
literal type. Thus, it was necessary to capture this bit somehow in the
FloatLiteralExpr. This was done as another Type field capturing this
info.
2019-03-01 09:01:30 -08:00
Parker Schuh
b12fcb50db IntegerLiteralExpr now is lowered directly into SIL.
For context, String, Nil, and Bool already behave this way.

Note: Before it used to construct (call, ... (integer_literal)), and the
call would be made explicit / implicit based on if you did eg: Int(3) or
just 3. This however did not translate to the new world so this PR adds
a IsExplicitConversion bit to NumberLiteralExpr. Some side results of
all this are that some warnings changed a little and some instructions are
emitted in a different order.
2019-02-14 11:54:16 -08: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
Michael Gottesman
21e51edfad [cast-opt] Allow users to pass in a SILBuilderContext to the CastOptimizer.
NOTE: I changed all places that the CastOptimizer is created to just pass in
nullptr for now so this is NFC.

----

Right now the interface of the CastOptimizer is muddled and confused. Sometimes
it is returning a value that should be used by the caller, other times it is
returning an instruction that is meant to be reprocessed by the caller.

This series of patches is attempting to clean this up by switching to the
following model:

1. If we are optimizing a cast of a value, we return a SILValue. If the cast
fails, we return an empty SILValue().

2. If we are optimizing a cast of an address, we return a boolean value to show
success/failure and require the user to use the SILBuilderContext to get the
cast if they need to.
2019-02-04 12:59:44 -08:00
Michael Gottesman
a5b47e127d [cast-opt] Add a new callback: ReplaceValueUsesAction.
This is the first in a series of patches to update the cast optimizer for
ownership and multiple value instructions.

This specific patch is NFC.
2019-02-04 11:26:46 -08:00
Adrian Prantl
ff63eaea6f Remove \brief commands from doxygen comments.
We've been running doxygen with the autobrief option for a couple of
years now. This makes the \brief markers into our comments
redundant. Since they are a visual distraction and we don't want to
encourage more \brief markers in new code either, this patch removes
them all.

Patch produced by

      for i in $(git grep -l '\\brief'); do perl -pi -e 's/\\brief //g' $i & done
2018-12-04 15:45:04 -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
John McCall
abdba1d3f4 Change the integer-literal type from Int2048 to IntLiteral.
Part of SR-290.
2018-10-31 23:14:58 -04:00
John McCall
cf511445e2 Basic support for Builtin.IntegerLiteral. 2018-10-31 18:42:34 -04:00
Erik Eckstein
12b6c0a7a7 SIL Optimizer: fix a crash in constant folding.
When the folded instructions are in an unreachable CFG loop, there may be loops in the use-def chain (there is no defined dominance order).
We have to handle this special case.

rdar://problem/43530134
2018-08-23 16:58:18 -07:00
Michael Gottesman
b72304415d [passmanager] Change the optimizer to use SILOptFunctionBuilder.
I am going to add the code in a bit that does the notifications. I tried to pass
down the builder instead of the pass manager. I also tried not to change the
formatting.

rdar://42301529
2018-08-05 21:21:55 -07:00
Mingsheng Hong
75d9540003 Fixed a bug in const folding, where an inst that's not of type
SingleValueInstruction gets added to the worklist, causing cast assert at https://github.com/apple/swift/blame/master/lib/SILOptimizer/Utils/ConstantFolding.cpp#L1585.

One such example inst is the following (in the tensorflow branch), which produces a SILValue of type
MultipleValueInstructionResult, so ValueBase::getDefiningInstruction() still
returns a valid inst for it, even though that graph_op inst is not a SingleValueInstruction.

```
%94 = graph_op "Fill,i,i"(%73 : $TensorHandle<Int32>, %85 : $TensorHandle<Float>) {T: $Float, index_type: $Int32, __device: "/device:CPU:0"} : $TensorHandle<Float>
```

The same fix has been merged into the tensorflow branch: https://github.com/apple/swift/pull/18272
2018-07-27 11:34:07 -07:00
Jordan Rose
cefb0b62ba Replace old DEBUG macro with new LLVM_DEBUG
...using a sed command provided by Vedant:

$ find . -name \*.cpp -print -exec sed -i "" -E "s/ DEBUG\(/ LLVM_DEBUG(/g" {} \;
2018-07-20 14:37:26 -07:00
Ravi Kandhadai
193407bf23 [SIL Diagnostics] Warn when assigning an integer literal to a
variable of floating-point type results in loss of precision.
<rdar://15224041>
2018-06-21 10:56:19 -07:00
Ravi Kandhadai
addae9bae4 [SIL Diagnostics] Add warnings for imprecision during assignment of
floating-point literals to variables of floating-point type.
2018-06-18 12:02:23 -07:00
Ravi Kandhadai
9846342444 [SIL Diagnostics & Tests] Re-add diagnostics for detecting invalid conversions from
floating point literals to integers (<rdar://39730762>).

Add test cases for checking the correctness of the diagnostics.
Contains tests specific to x86 and non-x86 architectures.
2018-05-15 18:08:08 -07:00
Ravi Kandhadai
95ff425389 Revert "[Diagnostics & Tests] Add diagnostics for detecting invalid conversions form Floating point to integers"
This reverts commit 957dc37615.
Reason: Float80 doesn't exist on all non-x86 architectures.
2018-05-14 11:10:08 -07:00
Ravi Kandhadai
957dc37615 [Diagnostics & Tests] Add diagnostics for detecting invalid conversions from
floating point literals to integers (<rdar://39730762>).

Add test cases for checking the correctness of the diagnostics.
2018-05-08 15:30:04 -07:00
Erik Eckstein
41c2991f6c Move the constant folding logic into a separate utility which can be used by multiple passes.
NFC
2018-01-19 11:29:35 -08:00
eeckstein
b126b62256 Revert "Optimization changes to completely fold OptionSet literals" 2018-01-18 22:05:07 -08:00
Erik Eckstein
fc3d8f11d6 Move the constant folding logic into a separate utility which can be used by multiple passes.
NFC
2018-01-18 18:27:17 -08:00
Davide Italiano
43fec57011 [ConstantFolding] Make explicit we don't use the result of div. 2017-09-16 21:41:48 -07:00
Bob Wilson
c940d49f8a Stop using APInt methods removed in LLVM r296993 2017-03-06 11:10:33 -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
practicalswift
8efa5f587e [gardening] Remove "-*- C++ -*-" tag from .cpp files
Emacs assumes .h files are C files by default which is why the
tag "-*- C++ -*-" is needed.

.cpp files do not have this problem.
2016-01-23 12:09:32 +01:00
practicalswift
ca92efc8e6 Use consistent formatting of header comments.
Correct format:
```
//===--- Name of file - Description ----------------------------*- Lang -*-===//
```

Notes:
* Comment line should be exactly 80 chars.
* Padding: Pad with dashes after "Description" to reach 80 chars.
* "Name of file", "Description" and "Lang" are all optional.
* In case of missing "Lang": drop the "-*-" markers.
* In case of missing space: drop one, two or three dashes before "Name of file".
2016-01-04 23:00:53 +01:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
Andrew Trick
739b0e9c56 Reorganize SILOptimizer directories for better discoverability.
(libraries now)

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 15:14:23 -08:00