Commit Graph

281 Commits

Author SHA1 Message Date
Michael Kruse f33c125dd2 Fix DomTree preservation for generated subregions.
The generated dedicated subregion exit block was assumed to have the same
dominance relation as the original exit block. This is incorrect if the exit
block receives other edges than only from the subregion, which results in that
e.g. the subregion's entry block does not dominate the exit block.

llvm-svn: 261865
2016-02-25 14:08:48 +00:00
Michael Kruse f8266fad8d Tidy test case. NFC.
The test style guide defines that opt should get its input from stdin.
(instead by file argument to avoid that the file name appears in its
output)

CHECK-FORCED is not recognized by FileCheck; remove it.

llvm-svn: 261786
2016-02-24 22:08:02 +00:00
Roman Gareev 11001e1534 Annotation of SIMD loops
Use 'mark' nodes annotate a SIMD loop during ScheduleTransformation and skip
parallelism checks.

The buildbot shows the following compile/execution time changes:

  Compile time:
    Improvements    Δ     Previous  Current  σ
    …/gesummv      -6.06% 0.2640    0.2480   0.0055
    …/gemver       -4.46% 0.4480    0.4280   0.0044
    …/covariance   -4.31% 0.8360    0.8000   0.0065
    …/adi          -3.23% 0.9920    0.9600   0.0065
    …/doitgen      -2.53% 0.9480    0.9240   0.0090
    …/3mm          -2.33% 1.0320    1.0080   0.0087

  Execution time:
    Regressions     Δ     Previous  Current  σ
    …/viterbi       1.70% 5.1840    5.2720   0.0074
    …/smallpt       1.06% 12.4920   12.6240  0.0040

Reviewed-by: Tobias Grosser <tobias@grosser.es>

Differential Revision: http://reviews.llvm.org/D14491

llvm-svn: 261620
2016-02-23 09:00:13 +00:00
Johannes Doerfert 85c06c80d1 Add test case for [FIX] commit r261474
llvm-svn: 261501
2016-02-21 21:53:39 +00:00
Johannes Doerfert 91bb5bc862 Use regular expressions instead of temporary names for IR test [NFC]
llvm-svn: 261488
2016-02-21 18:59:35 +00:00
Johannes Doerfert 4d9bb8d594 Allow all combinations of types and subscripts for memory accesses
To support non-aligned accesses we introduce a virtual element size
  for arrays that divides each access function used for this array. The
  adjustment of the access function based on the element size of the
  array was therefore moved after this virtual element size was
  determined, thus after all accesses have been created.

Differential Revision: http://reviews.llvm.org/D17246

llvm-svn: 261226
2016-02-18 16:50:12 +00:00
Johannes Doerfert 4cf1580f0c [FIX] Check the next base pointer for possible invariant loads
A load can only be invariant if its base pointer is invariant too. To
  this end, we check if the base pointer is defined inside the region or
  outside. In the former case we recursively check if we can (and
  therefore will) hoist the base pointer too. Only if that happends we
  can hoist the load.

llvm-svn: 260886
2016-02-15 12:42:05 +00:00
Johannes Doerfert f69162486b Revert "[FIX] Hoist accesses if AA stated they are invariant"
This reverts commit 98efa006c96ac981c00d2e386ec1102bce9f549a.

  The fix was broken since we do not use AA in the ScopDetection anymore to
  check for invariant accesses.

llvm-svn: 260884
2016-02-15 12:21:11 +00:00
Johannes Doerfert 2353e39e1f [FIX] Hoist accesses if AA stated they are invariant
Before this patch it could happen that we did not hoist a load that
  was a base pointer of another load even though AA already declared the
  first one as invariant (during ScopDetection). If this case arises we
  will now skipt the "can be overwriten" check because in this case the
  over-approximating nature causes us to generate broken code.

llvm-svn: 260862
2016-02-14 23:37:14 +00:00
Johannes Doerfert 965edde695 Separate more constant factors of parameters
So far we separated constant factors from multiplications, however,
  only when they are at the outermost level of a parameter SCEV. Now,
  we also separate constant factors from the parameter SCEV if the
  outermost expression is a SCEVAddRecExpr. With the changes to the
  SCEVAffinator we can now improve the extractConstantFactor(...)
  function at will without worrying about any other code part. Thus,
  if needed we can implement a more comprehensive
  extractConstantFactor(...) function that will traverse the SCEV
  instead of looking only at the outermost level.

  Four test cases were affected. One did not change much and the other
  three were simplified.

llvm-svn: 260859
2016-02-14 22:30:56 +00:00
Johannes Doerfert 96e5471139 Separate invariant equivalence classes by type
We now distinguish invariant loads to the same memory location if they
  have different types. This will cause us to pre-load an invariant
  location once for each type that is used to access it. However, we can
  thereby avoid invalid casting, especially if an array is accessed
  though different typed/sized invariant loads.

  This basically reverts the changes in r260023 but keeps the test
  cases.

llvm-svn: 260045
2016-02-07 17:30:13 +00:00
Tobias Grosser 8ebdc2dd53 Make memory accesses with different element types optional
We also disable this feature by default, as there are still some issues in
combination with invariant load hoisting that slipped through my initial
testing.

llvm-svn: 260025
2016-02-07 08:48:57 +00:00
Tobias Grosser 46bafbd0fe Do not yet consider loads with non-canonical element size for load hoisting.
Invariant load hoisting of memory accesses with non-canonical element
types lacks support for equivalence classes that contain elements of
different width/size. This support should be added, but to get our buildbots
back to green, we disable load hoisting for memory accesses with non-canonical
element size for now.

llvm-svn: 260023
2016-02-07 08:11:36 +00:00
Tobias Grosser 107cd5f5f6 IslNodeBuilder: Invariant load hoisting of elements with differing sizes
Always use access-instruction pointer type to load the invariant values.
Otherwise mismatches between ScopArrayInfo element type and memory access
element type will result in invalid casts. These type mismatches are after
r259784 a lot more common and also arise with types of different size, which
have not been handled before.

Interestingly, this change actually simplifies the code, as we now have only
one code path that is always taken, rather then a standard code path for the
common case and a "fixup" code path that replaces the standard code path in
case of mismatching types.

llvm-svn: 260009
2016-02-06 21:23:39 +00:00
Michael Kruse 2e02d560aa Follow uses to create value MemoryAccesses
The previously implemented approach is to follow value definitions and
create write accesses ("push defs") while searching for uses. This
requires the same relatively validity- and requirement conditions to be
replicated at multiple locations (PHI instructions, other instructions,
uses by PHIs).

We replace this by iterating over the uses in a SCoP ("pull in
requirements"), and add writes only when at least one read has been
added. It turns out to be simpler code because each use is only iterated
over once and writes are added for the first access that reads it. We
need another iteration to identify escaping values (uses not in the
SCoP), which also makes the difference between such accesses more
obvious. As a side-effect, the order of scalar MemoryAccess can change.

Differential Revision: http://reviews.llvm.org/D15706

llvm-svn: 259987
2016-02-06 09:19:40 +00:00
Tobias Grosser d840fc7277 Support accesses with differently sized types to the same array
This allows code such as:

void multiple_types(char *Short, char *Float, char *Double) {
  for (long i = 0; i < 100; i++) {
    Short[i] = *(short *)&Short[2 * i];
    Float[i] = *(float *)&Float[4 * i];
    Double[i] = *(double *)&Double[8 * i];
  }
}

To model such code we use as canonical element type of the modeled array the
smallest element type of all original array accesses, if type allocation sizes
are multiples of each other. Otherwise, we use a newly created iN type, where N
is the gcd of the allocation size of the types used in the accesses to this
array. Accesses with types larger as the canonical element type are modeled as
multiple accesses with the smaller type.

For example the second load access is modeled as:

  { Stmt_bb2[i0] -> MemRef_Float[o0] : 4i0 <= o0 <= 3 + 4i0 }

To support code-generating these memory accesses, we introduce a new method
getAccessAddressFunction that assigns each statement instance a single memory
location, the address we load from/store to. Currently we obtain this address by
taking the lexmin of the access function. We may consider keeping track of the
memory location more explicitly in the future.

We currently do _not_ handle multi-dimensional arrays and also keep the
restriction of not supporting accesses where the offset expression is not a
multiple of the access element type size. This patch adds tests that ensure
we correctly invalidate a scop in case these accesses are found. Both types of
accesses can be handled using the very same model, but are left to be added in
the future.

We also move the initialization of the scop-context into the constructor to
ensure it is already available when invalidating the scop.

Finally, we add this as a new item to the 2.9 release notes

Reviewers: jdoerfert, Meinersbur

Differential Revision: http://reviews.llvm.org/D16878

llvm-svn: 259784
2016-02-04 13:18:42 +00:00
Wei Mi eb14ac5396 Polly tests update contributed by Tobias Grosser for SCEV patch in r259736.
llvm-svn: 259737
2016-02-04 01:34:28 +00:00
Tobias Grosser ba043143a9 test: make test case more robust against removal of unrelated instructions
llvm-svn: 259693
2016-02-03 21:10:11 +00:00
Tobias Grosser e2c31210b2 Revert "Support loads with differently sized types from a single array"
This reverts commit (@259587). It needs some further discussions.

llvm-svn: 259629
2016-02-03 05:53:27 +00:00
Tobias Grosser 5d3fc1ea43 Support loads with differently sized types from a single array
We support now code such as:

void multiple_types(char *Short, char *Float, char *Double) {
  for (long i = 0; i < 100; i++) {
    Short[i] = *(short *)&Short[2 * i];
    Float[i] = *(float *)&Float[4 * i];
    Double[i] = *(double *)&Double[8 * i];
  }
}

To support such code we use as element type of the modeled array the smallest
element type of all original array accesses. Accesses with larger types are
modeled as multiple accesses with the smaller type.

For example the second load access is modeled as:

  { Stmt_bb2[i0] -> MemRef_Float[o0] : 4i0 <= o0 <= 3 + 4i0 }

To support jscop-rewritable memory accesses we need each statement instance to
only be assigned a single memory location, which will be the address at which
we load the value. Currently we obtain this address by taking the lexmin of
the access function. We may consider keeping track of the memory location more
explicitly in the future.

llvm-svn: 259587
2016-02-02 22:05:29 +00:00
Michael Kruse fd46308de4 ScopInfo: Never add read accesses for synthesizable values
Before adding a MK_Value READ MemoryAccess, check whether the read is
necessary or synthesizable. Synthesizable values are later generated by
the SCEVExpander and therefore do not need to be transferred
explicitly. This can happen because the check for synthesizability has
presumbly been forgotten in the case where a phi's incoming value has
been defined in a different statement.

Differential Revision: http://reviews.llvm.org/D15687

llvm-svn: 258998
2016-01-27 22:51:56 +00:00
Michael Kruse ee6a4fc680 Unique phi write accesses
Ensure that there is at most one phi write access per PHINode and
ScopStmt. In particular, this would be possible for non-affine
subregions with multiple exiting blocks. We replace multiple MAY_WRITE
accesses by one MUST_WRITE access. The written value is constructed
using a PHINode of all exiting blocks. The interpretation of the PHI
WRITE's "accessed value" changed from the incoming value to the PHI like
for PHI READs since there is no unique incoming value.

Because region simplification shuffles around PHI nodes -- particularly
with exit node PHIs -- the PHINodes at analysis time does not always
exist anymore in the code generation pass. We instead remember the
incoming block/value pair in the MemoryAccess.

Differential Revision: http://reviews.llvm.org/D15681

llvm-svn: 258809
2016-01-26 13:33:27 +00:00
Tobias Grosser f2cdd144e5 BlockGenerators: Replace getNewScalarValue with getNewValue
Both functions implement the same functionality, with the difference that
getNewScalarValue assumes that globals and out-of-scop scalars can be directly
reused without loading them from their corresponding stack slot. This is correct
for sequential code generation, but causes issues with outlining code e.g. for
OpenMP code generation. getNewValue handles such cases correctly.

Hence, we can replace getNewScalarValue with getNewValue. This is not only more
future proof, but also eliminates a bunch of code.

The only functionality that was available in getNewScalarValue that is lost
is the on-demand creation of scalar values. However, this is not necessary any
more as scalars are always loaded at the beginning of each basic block and will
consequently always be available when scalar stores are generated. As this was
not the case in older versions of Polly, it seems the on-demand loading is just
some older code that has not yet been removed.

Finally, generateScalarLoads also generated loads for values that are loop
invariant, available in GlobalMap and which are preferred over the ones loaded
in generateScalarLoads. Hence, we can just skip the code generation of such
scalar values, avoiding the generation of dead code.

Differential Revision: http://reviews.llvm.org/D16522

llvm-svn: 258799
2016-01-26 10:01:35 +00:00
Tobias Grosser 232905089e test: Name instructions in a test case [NFC]
llvm-svn: 258662
2016-01-24 17:51:37 +00:00
Johannes Doerfert 370cf00c9f Make sure we preserve alignment information after hoisting invariant load
In Polly, after hoisting loop invariant loads outside loop, the alignment
information for hoisted loads are missing, this patch restore them.

Contributed-by: Lawrence Hu <lawrence@codeaurora.org>

Differential Revision: http://reviews.llvm.org/D16160

llvm-svn: 258105
2016-01-19 00:17:21 +00:00
Michael Kruse 959a8dc39f Update to ISL 0.16.1
llvm-svn: 257898
2016-01-15 15:54:45 +00:00
Tobias Grosser a69d4f0d83 VectorBlockGenerator: Generate scalar loads for vector statements
When generating scalar loads/stores separately the vector code has not been
updated. This commit adds code to generate scalar loads for vector code as well
as code to assert in case scalar stores are encountered within a vector loop.

llvm-svn: 255714
2015-12-15 23:49:58 +00:00
Tobias Grosser 0921477248 ScopInfo: Look up first (and only) array access
When rewriting the access functions of load/store statements, we are only
interested in the actual array memory location. The current code just took
the very first memory access, which could be a scalar or an array access. As
a result, we failed to update access functions even though this was requested
via .jscop.

llvm-svn: 255713
2015-12-15 23:49:53 +00:00
Tobias Grosser 2d3d4ec860 executeScopConditionally: Introduce special exiting block
When introducing separate control flow for the original and optimized code we
introduce now a special 'ExitingBlock':

      \   /
    EnteringBB
        |
    SplitBlock---------\
   _____|_____         |
  /  EntryBB  \    StartBlock
  |  (region) |        |
  \_ExitingBB_/   ExitingBlock
        |              |
    MergeBlock---------/
        |
      ExitBB
      /    \

This 'ExitingBlock' contains code such as the final_reloads for scalars, which
previously were just added to whichever statement/loop_exit/branch-merge block
had been generated last. Having an explicit basic block makes it easier to
find these constructs when looking at the CFG.

llvm-svn: 255107
2015-12-09 11:38:22 +00:00
Tobias Grosser 87a44d29a2 test: Fix misspelled test line
llvm-svn: 255106
2015-12-09 11:38:08 +00:00
Tobias Grosser 020fa09a3c Remove -polly-code-generator=isl from many test cases
This is the default since a long time. Setting it again does not add value
in any of these test cases.

llvm-svn: 253800
2015-11-21 23:05:48 +00:00
Johannes Doerfert a4b77c079b [FIX] Bail if access function is not divisible by element size.
llvm-svn: 252942
2015-11-12 20:15:32 +00:00
Tobias Grosser bc29e0b27c RegionGenerator: Only introduce subregion.ivs for loops fully within a subregion
IVs of loops for which the loop header is in the subregion, but not the entire
loop may be incremented outside of the subregion and can consequently not be
kept private to the subregion. Instead, they need to and are modeled as virtual
loops in the iteration domains. As this is the case, generating new subregion
induction variables for such loops is not needed and indeed wrong as they would
hide the virtual induction variables modeled in the scop.

This fixes a miscompile in MultiSource/Benchmarks/Ptrdist/bc and
MultiSource/Benchmarks/nbench/. Thanks Michael and Johannes for their
investiagations and helpful observations regarding this bug.

llvm-svn: 252860
2015-11-12 07:34:09 +00:00
Johannes Doerfert fdbf201fc9 [FIX] Do not generate code for parameters referencing dead values
Check if a value that is referenced by a parameter is dead and do not
generate code for the parameter in such a case.

llvm-svn: 252813
2015-11-11 22:40:51 +00:00
Johannes Doerfert dcfedf3505 [FIX] Cast pre-loaded values correctly or reload them with adjusted type.
Especially for structs, the SAI object of a base pointer does not
describe all the types that the user might expect when he loads from
that base pointer. While we will still cast integers and pointers we
will now reload the value with the correct type if floating point and
non-floating point values are involved. However, there are now TODOs
where we use bitcasts instead of a proper conversion or reloading.

This fixes bug 25479.

llvm-svn: 252706
2015-11-11 06:20:25 +00:00
Johannes Doerfert fc4bfc465a [FIX] Create empty invariant equivalence classes
We now create all invariant equivalence classes for required invariant loads
  instead of creating them on-demand. This way we can check if a parameter
  references an invariant load that is actually not executed and was therefor
  not materialized. If that happens the parameter is not materialized either.

This fixes bug 25469.

llvm-svn: 252701
2015-11-11 04:30:07 +00:00
Michael Kruse c993739e0d Fix non-affine generated entering node not being recognized as dominating
Scalar reloads in the generated entering block were not recognized as
dominating the subregions locks when there were multiple entering
nodes. This resulted in values defined in there not being copied.

As a fix, we unconditionally add the BBMap of the generated entering
node to the generated entry. This fixes part of llvm.org/PR25439.

This reverts 252449 and reapplies r252445. Its test was failing
indeterministically due to r252375 which was reverted in r252522.

llvm-svn: 252540
2015-11-09 23:33:40 +00:00
Michael Kruse d6fb6f1b0c Fix dominance when subregion exit is outside scop
The dominance of the generated non-affine subregion block was based on
the scop's merge block, therefore resulted in an invalid DominanceTree.
It resulted in some values as assumed to be unusable in the actual
generated exit block.

We detect the case that the exit block has been moved and decide
dominance using the BB at the original exit. If we create another exit
node, that exit nodes is dominated by the one generated from where the
original exit resides. This fixes llvm.org/PR25438 and part of
llvm.org/PR25439.

llvm-svn: 252526
2015-11-09 23:07:38 +00:00
Michael Kruse ebffcbeefa Revert r252375 "Fix non-affine region dominance of implicitely stored values"
It introduced indeterminism as it was iterating over an address-indexed
hashtable. The corresponding bug PR25438 will be fixed in a successive
commit.

llvm-svn: 252522
2015-11-09 22:37:29 +00:00
Johannes Doerfert 7a6e292d86 [FIX] Use same alloca for invariant loads and the scalar users
llvm-svn: 252451
2015-11-09 06:28:45 +00:00
Johannes Doerfert 544b23a1ef Revert "Fix non-affine generated entering node not being recognized as dominating"
This reverts commit 9775824b265e574fc541e975d64d3e270243b59d due to a
failing unit test.

Please check and correct the unit test and commit again.

llvm-svn: 252449
2015-11-09 06:04:05 +00:00
Michael Kruse fd9c89e84b Fix non-affine generated entering node not being recognized as dominating
Scalar reloads in the generated entering block were not recognized as
dominating the subregions locks when there were multiple entering
nodes. This resulted in values defined in there not being copied.

As a fix, we unconditionally add the BBMap of the generated entering
node to the generated entry. This fixes part of llvm.org/PR25439.

llvm-svn: 252445
2015-11-09 05:00:30 +00:00
Johannes Doerfert 188542fda9 [FIX] Initialize incoming scalar memory locations for PHIs
llvm-svn: 252437
2015-11-09 00:21:21 +00:00
Johannes Doerfert 3797707695 [FIX] Use unreachable to indicate dead code and repair dominance
When we bail out early we make the partially build new code path
  practically dead, though it was not unreachable. To remove dominance
  problems we now make it not only dead but also prevent the control
  flow to join with the original code path, thus allow to use original
  values after the SCoP without any PHI nodes.

This fixes bug 25447.

llvm-svn: 252420
2015-11-08 17:57:41 +00:00
Johannes Doerfert c4898504ea [FIX] Bail out if there is a dependence cycle between invariant loads
While the program cannot cause a dependence cycle between invariant
  loads, additional constraints (e.g., to ensure finite loops) can
  introduce them. It is hard to detect them in the SCoP description,
  thus we will only check for them at code generation time. If such a
  recursion is detected we will bail out the code generation and place a
  "false" runtime check to guarantee the original code is used.

  This fixes bug 25443.

llvm-svn: 252412
2015-11-07 19:46:04 +00:00
Michael Kruse 0651480b97 Fix non-affine region dominance of implicitely stored values
After loop versioning, a dominance check of a non-affine subregion's
exit node causes the dominance check to always fail on any block in the
subregion if it shares the same exit block with the scop. The
subregion's exit block has become polly_merge_new_and_old, which also
receives the control flow of the generated code. This would cause that
any value for implicit stores is assumed to be not from the scop.

We check dominance with the generated exit node instead.

This fixes llvm.org/PR25438

llvm-svn: 252375
2015-11-07 00:36:50 +00:00
Tobias Grosser 712229ec59 Add missing '%loadPolly' to test case
llvm-svn: 252302
2015-11-06 14:03:35 +00:00
Michael Kruse ddb6528ba6 Fix reuse of non-dominating synthesized value in subregion exit
We were adding all generated values in non-affine subregions to be used
for the subregions generated exit block. The thought was that only
values that are dominating the original exit block can be used there.
But it is possible for synthesizable values to be expanded in any
block. If the same values is also used for implicit writes, it would
try to reuse already synthesized values even if not dominating the exit
block.

The fix is to only add values to the list of values usable in the exit
block only if it is dominating the exit block. This fixes
llvm.org/PR25412.

llvm-svn: 252301
2015-11-06 13:51:24 +00:00
Tobias Grosser 6578f001bf Adjust debug metadata to LLVM changes in 252219
llvm-svn: 252273
2015-11-06 06:27:39 +00:00
Tobias Grosser f1bfd75221 ScopInfo: Allocate globally unique memory access identifiers
Before this commit memory reference identifiers have only been unique per
basic block, but not per (non-affine) ScopStmt. This commit now uses the
MemoryAccess base pointer to uniquely identify each Memory access.

llvm-svn: 252200
2015-11-05 20:15:37 +00:00