Commit Graph

36 Commits

Author SHA1 Message Date
Michael Gottesman
dd6439d31e [ownership] Change the stdlib to serialize code in ossa form on Darwin.
There is some sort of ASAN issue that this exposes on Linux, so I am going to do
this on Darwin and then debug the Linux issue using ASAN over the weekend/next
week.
2021-02-12 23:20:17 -08:00
Daniel Rodríguez Troitiño
99e98e6470 [android] Remove XFAIL for tests that started passing.
These tests were disabled in #33500 (a0333a4e37) and #30390
(6ac04c6079) because the optimizer did not seem to be working in
Android ARMv7.

At some moment between October 21st and October 30th something unbroke
the tests. I have looked into the changes in the SILOptimizer directory,
but I cannot pinpoint it to any of them in particular. It might be also
changes introduced in LLVM.
2020-11-02 18:00:22 -08:00
Daniel Rodríguez Troitiño
6ac04c6079 [android][armv7] Mark let_properties_opts.swift as XFAIL.
Looks like Android ARMv7 is not inline storeBytes so the test were
failing. Mark the test as XFAIL and open a bug in the tracker to keep
the CI green for the moment.
2020-03-15 19:13:37 -07:00
Ben Langmuir
f1f7e66174 Attempt to prevent CI failure with debug stdlib
rdar://60379473
2020-03-12 13:24:47 -07:00
Andrew Trick
c34625779b Disable LetPropertiesOpt on struct 'let's.
This pass makes assumptions about the visibility of a type's memory
based on the visibility of its properties. This is the wrong way to
think about memory visibility.

Fixes <rdar://57564377> Struct component with 'let', unexpected
behavior

This pass wants assume that the contents of a property is known based
on whether the property is declared as a 'let' and the visibility of
the initializers that access the property. For example:

```
public struct X<T> {
  public let hidden: T

  init(t: T) { self.hidden = t }
}
```

The pass currently assumes that `X` only takes on values that are
assigned by the invocations of `X.init`, which is only visible in `X`s
module. This is wrong if the layout of `Impl` is exposed to other
modules. A struct's memory may be initialized by any module with
access to the struct's layout.

In fact, this assumption is wrong even if the struct, and it's let
property cannot be accessed externally by name. In this next example,
external modules cannot access `Impl` or `Impl.hidden` by name, but
can still access the memory.

```
internal struct Impl<T> {
  let hidden: T

  init(t: T) { self.hidden = t }
}

public struct Wrapper<T> {
  var impl: Impl<T>

  public var property: T {
    get {
      return impl.hidden
    }
  }
}
```

As long as `Wrapper`s layout is exposed to other modules, the contents
of `Wrapper`, `Impl`, and `hidden' can all be initialized in another
module

```
// Legal as long Wrapper's home module is *not* built with library evolution
// (or if Wrapper is declared `@frozen`).
func inExternalModule(buffer: UnsafeRawPointer) -> Wrapper<Int64> {
  return buffer.load(as: Wrapper<Int64>.self)
}
```

If library evolution is enabled and a `public` struct is not declared
`@frozen` then external modules cannot assume its layout, and therefore
cannot initialize the struct memory. In that case, it is possible to optimize
`X.hidden` and `Impl.hidden` as if the properties are only initialized inside
their home module.

The right way to view a type's memory visibility is to consider whether
external modules have access to the layout of the type. If not, then the
property can still be optimized As long as a struct is never enclosed in a
public effectively-`@frozen` type. However, finding all places where a struct
is explicitly created is still insufficient. Instead, the optimization needs
to find all uses of enclosing types and determine if every use has a known
constant initialization, or is simply copied from another value. If an
escaping unsafe pointer to any enclosing type is created, then the
optimization is not valid.

When viewed this way, the fact that a property is declared 'let' is mostly
irrelevant to this optimization--it can be expanded to handle non-'let'
properties. The more salient feature is whether the propery has a public
setter.

For now, this optimization only recognizes class properties because class
properties are only accessibly via a ref_element_addr instruction. This is a
side effect of the fact that accessing a class property requires a "formal
access". This means that begin_access marker must be emitted directly on the
address produced by a ref_element_addr. Struct properties are not handled, as
explained above, because they can be indirectly accessed via addresses of
outer types.
2020-03-09 16:20:01 -07:00
Erik Eckstein
39bb14b094 change mangling prefix from $S to $s
This is the final ABI mangling prefix

rdar://problem/38471478
2018-09-19 13:55:11 -07:00
Erik Eckstein
6ae0b22a1a SILOptimizer: handle copies in LetPropertiesOpt.
When the initializer of a property is analyzed we now don't bail if such a property is copied from another instance of a struct/class.

This fixes a strange performance regression with constant let properties in structs which conform to an unrelated protocol.

SR-7713
rdar://problem/40332203
2018-09-04 11:22:21 -07:00
Michael Gottesman
cb80f65f1e Remove plus_zero_test,plus_one_test from lit tests since they are no longer needed.
I am going to leave in the infrastructure around this just in case. But there is
no reason to keep this in the tests themselves. I can always just revert this
and I don't think merge conflicts are likely due to previous work I did around
the tooling for this.
2018-03-21 20:49:52 -07:00
Michael Gottesman
e567bc9028 [+0-all-args] Enable +0 normal arguments.
rdar://34222540
2018-03-19 20:25:31 -07:00
Michael Gottesman
b00966e247 [+0-all-args] Add more module_names to tests to enable running their plus_zero variants.
rdar://34222540
2018-03-13 19:47:50 -07:00
Michael Gottesman
8dd5ea9b60 [+0-all-args] Add a space after REQUIRES: plus_one_runtime to eliminate avoidable merge conflicts when editing other parts of the file.
This helps my tooling for enabling +0.
2018-03-11 16:19:09 -07:00
Andrew Trick
defc710f8b [exclusivity] Teach LetPropertiesOpt how to handle begin_access. 2018-03-11 14:20:39 -07:00
Michael Gottesman
e6e55df5ea [+0-all-args] Mark all tests that will need updates for +0 as requiring a plus_one_runtime. 2018-03-10 02:37:51 -08:00
Erik Eckstein
cd3d50a5d9 ABI: Change the mangling prefix from _T0 to $S 2018-01-06 13:55:59 -08:00
Pavel Yaskevich
f90d943a29 [Mangling/ABI] NFC: Fix SILOptimizer tests to reflect label mangling changes 2017-12-18 15:45:50 -08:00
Roman Levenstein
53754a7a69 Add a new simple utility optimization pass for serialization of SILModules 2017-10-13 23:19:19 -07:00
Erik Eckstein
c4a11f4c92 tests: remove the now unused option -new-mangling-for-tests 2017-03-22 11:28:43 -07:00
Slava Pestov
4fa2ad8f55 SIL: Allocating entry points of designated initializers are [fragile]
The allocating entry point allocates an instance and calls the
initializing entry point. This should always be safe to inline
into resilient callers.
2017-03-12 23:14:51 -07:00
Erik Eckstein
1d3724666f tests: convert about 400 tests to the new mangling by using the -new-mangling-for-tests option
When the new mangling is enabled permanently, the option can be removed from the RUN command lines again.
2017-01-24 15:27:45 -08:00
Dmitri Gribenko
d175b3b66d Migrate FileCheck to %FileCheck in tests 2016-08-10 23:52:02 -07:00
Jordan Rose
e4118f19c8 Port tests to 'fileprivate'.
Similar to apple/swift#3753.

Groundwork for SE-0025 ('private' and 'fileprivate').
No intended functionality change.
2016-07-25 20:20:58 -07:00
Xin Tong
fb3eb0b646 Simplify function signature optimzation.
Several functionalities have been added to FSO over time and the logic has become
muddled.

We were always looking at a static image of the SIL and try to reason about what kind of
function signature related optimizations we can do.

This can easily lead to muddled logic. e.g. we need to consider 2 different function
signature optimizations together instead of independently.

Split 1 single function to do all sorts of different analyses in FSO into several
small transformations, each of which does a specific job. After every analysis, we produce
a new function and eventually we collapse all intermediate thunks to in a single thunk.

With this change, it will be easier to implement function signature optimization as now
we can do them independently now.

Small modifications to the test cases.
2016-05-25 11:12:27 -07:00
Xin Tong
51b1c0bc68 Implement retain, release code motion.
Iterative data flow retain sinking and release hoisting.

This allows us to sink retains and hoist releases across harmless loops. which is
an improvement on the SILCodeMotion retain sinking and release hoisting.

It also separates the duty of moving retain and release with the duty of eliminating them
in ASO.

This should eventually replace RR code motion in SILcodemotion and insertion point
in ARCsequence opts (ASO).

This is the performance difference i get with retain sinking and release hoisting.
After disabling retain release code motion in ASO and SILCodeMotion. we can start to take
those code out once this lands.

I see that we go from 24.5% of time spent in SILOptimizations w.r.t. the whole stdlib compilation
to 25.1%.

Improvement is better (i.e. retain sinking and hoisting releases result in performance gain).

<details open>
  <summary>Regression (7)</summary>

TEST                                                    | OLD_MIN | NEW_MIN | DELTA (%) | SPEEDUP
---                                                     | ---     | ---     | ---       | ---
SetIsSubsetOf                                           | 441     | 510     | +15.7%    | **0.86x**
SetIntersect                                            | 1041    | 1197    | +15.0%    | **0.87x**
BenchLangCallingCFunction                               | 184     | 211     | +14.7%    | **0.87x**
Sim2DArray                                              | 326     | 372     | +14.1%    | **0.88x**
SetIsSubsetOf_OfObjects                                 | 498     | 567     | +13.9%    | **0.88x**
GeekbenchGEMM                                           | 945     | 1022    | +8.2%     | **0.92x**
COWTree                                                 | 3839    | 4181    | +8.9%     | **0.92x(?)**

</details>

<details >
  <summary>Improvement (31)</summary>

TEST                                                    | OLD_MIN | NEW_MIN | DELTA (%) | SPEEDUP
---                                                     | ---     | ---     | ---       | ---
ObjectiveCBridgeFromNSDictionaryAnyObjectToString       | 174526  | 165392  | -5.2%     | **1.06x**
RGBHistogram                                            | 3128    | 2957    | -5.5%     | **1.06x**
ObjectiveCBridgeToNSDictionary                          | 16510   | 15494   | -6.2%     | **1.07x**
LuhnAlgoLazy                                            | 2294    | 2120    | -7.6%     | **1.08x**
DictionarySwapOfObjects                                 | 6477    | 5994    | -7.5%     | **1.08x**
StringRemoveDupes                                       | 1610    | 1485    | -7.8%     | **1.08x**
ObjectiveCBridgeFromNSSetAnyObjectToString              | 159358  | 147824  | -7.2%     | **1.08x**
ObjectiveCBridgeToNSSet                                 | 16191   | 14924   | -7.8%     | **1.08x**
DictionaryHashableClass                                 | 1839    | 1704    | -7.3%     | **1.08x**
DictionaryLiteral                                       | 2906    | 2678    | -7.8%     | **1.09x(?)**
StringUtilsUnderscoreCase                               | 10031   | 9187    | -8.4%     | **1.09x**
LuhnAlgoEager                                           | 2320    | 2113    | -8.9%     | **1.10x**
ObjectiveCBridgeFromNSSetAnyObjectToStringForced        | 99553   | 90348   | -9.2%     | **1.10x**
RIPEMD                                                  | 3327    | 3009    | -9.6%     | **1.11x**
Combos                                                  | 595     | 538     | -9.6%     | **1.11x**
Roman                                                   | 10      | 9       | -10.0%    | **1.11x**
StringUtilsCamelCase                                    | 10783   | 9646    | -10.5%    | **1.12x**
SetIntersect_OfObjects                                  | 2511    | 2182    | -13.1%    | **1.15x**
SwiftStructuresTrie                                     | 28331   | 24339   | -14.1%    | **1.16x**
Dictionary2OfObjects                                    | 3748    | 3115    | -16.9%    | **1.20x**
DictionaryOfObjects                                     | 2473    | 2050    | -17.1%    | **1.21x**
Dictionary                                              | 894     | 737     | -17.6%    | **1.21x**
Dictionary2                                             | 2268    | 1859    | -18.0%    | **1.22x**
StringIteration                                         | 8027    | 6344    | -21.0%    | **1.27x**
Phonebook                                               | 8207    | 6436    | -21.6%    | **1.28x**
BenchLangArray                                          | 119     | 91      | -23.5%    | **1.31x**
LinkedList                                              | 8267    | 6297    | -23.8%    | **1.31x**
StrToInt                                                | 5585    | 4180    | -25.2%    | **1.34x**
Dictionary3OfObjects                                    | 1122    | 831     | -25.9%    | **1.35x**
Dictionary3                                             | 731     | 515     | -29.6%    | **1.42x**
SuperChars                                              | 513353  | 258735  | -49.6%    | **1.98x**
2016-04-18 15:39:17 -07:00
Manav Gabhawala
7928140f79 [SE-0046] Implements consistent function parameter labels by discarding extraneous parameter names and adding _ where necessary 2016-04-06 20:21:58 -04:00
Chris Lattner
5b7e030810 Merge pull request #1952 from practicalswift/gardening-20160330
[gardening] Remove unused code, fix typos and improve file header formatting
2016-03-30 10:24:05 -07:00
practicalswift
bbef13a050 [gardening] Fix recently introduced typo: "attribtue" → "attribute"
[gardening] Fix recently introduced typo: "delinated" → "delineated"

[gardening] Fix recently introduced typo: "abstactions" → "abstractions"

[gardening] Fix recently introduced typo: "cannoted" → "cannot"

[gardening] Fix recently introduced typo: "accomodate" → "accommodate"

[gardening] Fix recently introduced typo: "bulding" → "building"

[gardening] Fix recently introduced typo: "abstactions" → "abstractions"

[gardening] Fix recently introduced typo: "intiializers" → "initializers"
2016-03-30 18:20:53 +02:00
Xin Tong
f95d9b3c92 Change FSO heuristic.
FSO functions that have high potential but does not have caller inside
current module.

The thunk can then be inlined into the module calling the function and
the function would get the benefit of FSO.

The heuristic for selecting such function is
1. Have no indirect caller. This would introduce a thunk.
2. Have potential to give better performance. i.e. function argument can
be O2G.

Regression
TEST                                                    | OLD_MIN | NEW_MIN | DELTA (%) | SPEEDUP
---                                                     | ---     | ---     | ---       | ---
BenchLangCallingCFunction                               | 184     | 211     | +14.7%    | **0.87x**
Calculator                                              | 55      | 59      | +7.3%     | **0.93x**
DeadArray                                               | 687     | 741     | +7.9%     | **0.93x**
MonteCarloPi                                            | 39275   | 41669   | +6.1%     | **0.94x**

Improvement
TEST                                                    | OLD_MIN | NEW_MIN | DELTA (%) | SPEEDUP
---                                                     | ---     | ---     | ---       | ---
LuhnAlgoLazy                                            | 2478    | 2327    | -6.1%     | **1.06x**
OpenClose                                               | 54      | 51      | -5.6%     | **1.06x**
SortLettersInPlace                                      | 1016    | 946     | -6.9%     | **1.07x**
ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced | 149993  | 139755  | -6.8%     | **1.07x**
Phonebook                                               | 9666    | 8992    | -7.0%     | **1.07x**
ObjectiveCBridgeFromNSDictionaryAnyObjectToString       | 222713  | 206538  | -7.3%     | **1.08x**
LuhnAlgoEager                                           | 2393    | 2226    | -7.0%     | **1.08x**
Dictionary                                              | 1307    | 1196    | -8.5%     | **1.09x**
JSONHelperDeserialize                                   | 3808    | 3492    | -8.3%     | **1.09x**
StdlibSort                                              | 7310    | 4084    | -44.1%    | **1.79x**

I see 0.15% increase in code size for Benchmark_O.

Thanks @gottesmm for suggesting this opportunity.

rdar://25345056
2016-03-29 23:04:36 -07:00
practicalswift
f18e5e935c [gardening] Fix recently introduced typo: "intialize" → "initialize" 2016-03-28 21:52:02 +02:00
Roman Levenstein
5893fc2694 [let-properties-opt] Re-factor and simplify the code. Improve correctness.
Based on the review of my previous commit, I did some re-factorings.
The code is now simpler and handles more cases. More tests were added.

The overall idea of this rewrite is that the pass basically tries to check if it can
see all possible writes (i.e. initializations) into a given let property. Only if it can be proven
that the pass sees all possible writes and all those initializations are producing
the same constant, statically known value, the pass propagates this constant value
into uses of a property.

SR-1026 and rdar://25303106
2016-03-25 15:13:10 -07:00
practicalswift
d00a5ef814 [gardening] Weekly gardening: typos, duplicate includes, header formatting, etc. 2016-03-24 22:41:10 +01:00
Roman Levenstein
3448b7c0f4 [let-properies-opt] Fix a bug which where a let property was wrongly considered to have a constant value.
The optimization pass was inspecting only init methods to determine if a given let property is defined
in the same way by all initializers. But this is not enough in certain cases, e.g. when some of the
initializers were inlined into the application code and the body of the inlined SIL function representing
such an initializer was removed afterwards by the dead function elimination pass. In such situations,
the Let Properties Optimization pass was assuming that there is only one initializer and considered the
constant let property value defined there as the only possible value of this let property. Therefore it
propagated it into let-property uses, which resulted in an incorrect code.

The right thing to do is to analyze all assignments to a given let property whether they are inside initializer
SIL functions or not. This makes sure that all possible values of a let property are analyzed and compared.
The propagation of a constant let property value can only happen if all found possible values are all the same.

Fixes SR-1026 and rdar://25303106
2016-03-23 22:29:56 -07:00
Roman Levenstein
ae53c1c219 Fix a bug in LetPropertiesOptPass
The optimization should not proceed if there is more than one assignment to a let property inside an initializer.
In this case, the value of the let property is considered unknown.
2016-02-28 18:43:02 -08:00
Daniel Duan
2bc78b8c09 [stdlib] update for 'inout' adjustment (SE-0031) 2016-02-26 12:02:29 -08:00
practicalswift
8ab8847684 Fix typos. 2015-12-16 22:09:32 +01:00
practicalswift
b5180e610d Fix typo: intialize → initialize 2015-12-14 00:11:59 +01:00
Andrew Trick
bd35b4789c Move test/SILOptimizer files to reflect lib/SILOptimizer. 2015-12-11 15:53:22 -08:00