Commit Graph

28 Commits

Author SHA1 Message Date
Michael Kruse 60e2a321e5 [test] Remove non-JSPON comments in JSCOP file. NFC.
llvm-svn: 338185
2018-07-28 01:11:45 +00:00
Krzysztof Parzyszek fb3ed4f409 [Polly] Fix a testcase after LLVM commit r334318
ScalarEvolution has become slightly more intelligent, so obfuscate the
exit condition in the testcase some more to keep it working.

llvm-svn: 334327
2018-06-08 21:39:55 +00:00
Michael Kruse a43ba2d84f [ScopBuilder] Make -polly-stmt-granularity=scalar-indep the default.
Splitting basic blocks into multiple statements if there are now
additional scalar dependencies gives more freedom to the scheduler, but
more statements also means higher compile-time complexity. Switch to
finer statement granularity, the additional compile time should be
limited by the number of operations quota.

The regression tests are written for the -polly-stmt-granularity=bb
setting, therefore we add that flag to those tests that break with the
new default. Some of the tests only fail because the statements are
named differently due to a basic block resulting in multiple statements,
but which are removed during simplification of statements without
side-effects. Previous commits tried to reduce this effect, but it is
not completely avoidable.

Differential Revision: https://reviews.llvm.org/D42151

llvm-svn: 324169
2018-02-03 06:59:47 +00:00
Michael Kruse b6b65834a1 [Simplify] Mark (and sweep) based on latest access relation.
Previously we marked scalars based on the original access function. However,
when a scalar read access is redirected, the original definition
(or incoming values of a PHI) is not used anymore, and can be deleted
(unless referenced by use that has not been redirected).

llvm-svn: 316660
2017-10-26 12:34:36 +00:00
Michael Kruse 6d7a7896ce [ScopInfo] Use map for value def/PHI read accesses.
Before this patch, ScopInfo::getValueDef(SAI) used
getStmtFor(Instruction*) to find the MemoryAccess that writes a
MemoryKind::Value. In cases where the value is synthesizable within the
statement that defines, the instruction is not added to the statement's
instruction list, which means getStmtFor() won't return anything.

If the synthesiable instruction is not synthesiable in a different
statement (due to being defined in a loop that and ScalarEvolution
cannot derive its escape value), we still need a MemoryKind::Value
and a write to it that makes it available in the other statements.
Introduce a separate map for this purpose.

This fixes MultiSource/Benchmarks/MallocBench/cfrac where
-polly-simplify could not find the writing MemoryAccess for a use. The
write was not marked as required and consequently was removed.

Because this could in principle happen as well for PHI scalars,
add such a map for PHI reads as well.

llvm-svn: 313881
2017-09-21 14:23:11 +00:00
Michael Kruse 420c4863a9 [Simplify] Actually remove unsed instruction from region header.
Since r312249 instructions of a entry block of region statements are
not marked as root anymore and hence can theoretically be removed
if unused. Theoretically, because the instruction list was not changed.

Still, MemoryAccesses for unused instructions were removed. This lead
to a failed assertion in the code generator  when the MemoryAccess for
the still listed instruction was not found.

This hould fix the
Assertion failed: ArrayAccess && "No array access found for instruction!",
file ScopInfo.h, line 1494
compiler crashes.

llvm-svn: 312566
2017-09-05 19:44:39 +00:00
Philip Pfaffe c3bcdc2f1a [JSON] Make the failure to parse a jscop file a hard error
Summary:
Before, if we fail to parse a jscop file, this will be reported as an
error and importing is aborted. However, this isn't actually strong
enough, since although the import is aborted, the scop has already been
modified and is very likely broken. Instead, make this a hard failure
and throw an LLVM error. This new behaviour requires small changes to
the tests for the legacy pass, namely using `not` to verify the error.
Further, fixed the jscop file for the
base_pointer_load_is_inst_inside_invariant_1 testcase.

Reviewed By: Meinersbur

Split out of D36578.

llvm-svn: 310599
2017-08-10 14:53:25 +00:00
Michael Kruse bc88a78cb4 [Simplify] Rewrite redundant write detection algorithm.
The previous algorithm was to search a writes and the sours of its value
operand, and see whether the write just stores the same read value back,
which includes a search whether there is another write access between
them. This is O(n^2) in the max number of accesses in a statement
(+ the complexity of isl comparing the access functions).

The new algorithm is more similar to the one used for searching for
overwrites and coalescable writes. It scans over all accesses in order
of execution while tracking which array elements still have the same
value since it was read. This is O(n), not counting the complexity
within isl. It should be more reliable than trying to catch all
non-conforming cases in the previous approach. It is also less code.

We now also support if the write is a partial write of the read's
domain, and to some extent non-affine subregions.

Differential Revision: https://reviews.llvm.org/D36137

llvm-svn: 309734
2017-08-01 20:01:34 +00:00
Michael Kruse 693ef99935 [Simplify] Improve scalability.
With a lot of reads and writes to the same array in a statement,
some isl sets that capture the state between access can become
complex such that isl takes more considerable time and memory
for operations on them.

The problems identified were:

- is_subset() takes considerable time with many disjoints in the
  arguments. We limit the number of disjoints to 4, any additional
  information is thrown away.

- subtract() can lead to many disjoints. We instead assume that any
  array element is possibly accessed, which removes all disjoints.

- subtract_domain() may lead to considerable processing, even if all
  elements are are to be removed. Instead, we remove determine and
  remove the affected spaces manually. No behaviour is changed.

llvm-svn: 309728
2017-08-01 19:39:11 +00:00
Michael Kruse 57cc92b790 [Simplify] Remove all kinds of redundant scalar writes.
In addition to array and PHI writes, also allow scalar value writes.
The only kind of write not allowed are writes by functions
(including memcpy/memmove/memset).

llvm-svn: 309582
2017-07-31 17:04:55 +00:00
Michael Kruse ce9617f4fe [Simplify] Implement write accesses coalescing.
Write coalescing combines write accesses that

- Write the same llvm::Value.
- Write to the same array.
- Unless they do not write anything in a statement instance (partial
  writes), write to the same element.
- There is no other access between them that accesses the same element.

This is particularly useful after DeLICM, which leaves partial writes to
disjoint domains.

Differential Revision: https://reviews.llvm.org/D36010

llvm-svn: 309489
2017-07-29 16:21:16 +00:00
Michael Kruse 4335c3992a [test] Add test case for -polly-simplify. NFC.
llvm-svn: 309458
2017-07-29 00:06:06 +00:00
Michael Kruse 8e41d2baab [Simplify] Do not remove dependencies of phis within region stmts.
These were wrongly assumed to be phi nodes that require
MemoryKind::PHI accesses.

llvm-svn: 309454
2017-07-28 23:22:32 +00:00
Michael Kruse 6c8f91b908 [Simplify] Fix typo in statistics output. NFC.
llvm-svn: 309402
2017-07-28 16:57:51 +00:00
Michael Kruse 34a77780c5 [Simplify] Remove empty partial accesses first. NFC.
So follow-up cleanup do not need special handling for such accesses.

llvm-svn: 309401
2017-07-28 16:57:45 +00:00
Michael Kruse 8a8aca4299 [Simplify] Count PHINodes in simplifiable exit nodes as escaping use.
After region exit simplification, the incoming block of a phi node in
the SCoP region's exit block lands outside of the region. Since we
treat SCoPs as if this already happened, we need to account for that
when looking for outside uses of scalars (i.e. escaping scalars).

llvm-svn: 309271
2017-07-27 14:09:31 +00:00
Michael Kruse 95b39da8ae [Simplify] Fix invalid removal write for escaping values.
A PHI node's incoming block is the user of its operand, not the PHI's parent.

Assuming the PHINode's parent being the user lead to the removal of a
MemoryAccesses because its use was assumed to be inside of the SCoP.

llvm-svn: 309164
2017-07-26 19:58:15 +00:00
Michael Kruse b6317007b4 [ScopInfo] Fix assertion for PHIs not in a region stmts entry.
A PHI node within a region statement is legal, but does not have
a MemoryKind::PHI access.

llvm-svn: 308973
2017-07-25 13:28:39 +00:00
Michael Kruse ab8f0d57df [Simplify] Remove partial write accesses with empty domain.
If the access relation's domain is empty, the access will never be
executed. We can just remove it.

We only remove write accesses. Partial read accesses are not yet
supported and instructions in the statement might require the
llvm::Value holding the read's result to be defined.

llvm-svn: 308830
2017-07-22 20:33:09 +00:00
Michael Kruse 22058c3fbb [Simplify] Remove unused instructions and accesses.
Use a mark-and-sweep algorithm to find and remove unused instructions
and MemoryAccesses. This is useful in particular to remove scalar
writes that are never used anywhere. A scalar write in a loop induces
a write-after-write dependency that stops the loop iterations to be
rescheduled. Such writes can be a result of previous transformations
such as DeLICM and operand tree forwarding.

It adds a new class VirtualInstruction that represents an instruction in
a particular statement. At the moment an instruction can only belong to
the statement that represents a BasicBlock. In the future, instructions
can be in one of multiple statements representing a BasicBlock
(Nandini's work), in different statements than its BasicBlock would
indicate, and even multiple statements at once (by forwarding operand
trees). It also integrates nicely with the VirtualUse class.

ScopStmt::contains(Instruction*) currently uses the instruction's parent
BasicBlock to check whether it contains the instruction. It will need to
check the actual statement list when one of the aforementioned features
become possible.

Differential Revision: https://reviews.llvm.org/D35656

llvm-svn: 308626
2017-07-20 16:21:55 +00:00
Tobias Grosser bed2ca6eac [Simplify] Also remove redundant writes which originally came from PHI nodes
llvm-svn: 307660
2017-07-11 14:29:39 +00:00
Tobias Grosser e40c0fe3f8 [tests] Set -polly-import-jscop-dir=%S always
This simplifies the test cases.

llvm-svn: 307645
2017-07-11 10:39:01 +00:00
Tobias Grosser 6561f78b64 [Simplify] Add test case which we currently miss
llvm-svn: 307643
2017-07-11 10:30:45 +00:00
Michael Kruse ad7a1805be [Simplify] Use execution order of memory accesses.
Iterate through memory accesses in execution order (first all implicit reads,
then explicit accesses, then implicit writes).

In the test case this caused an implicit load to be handled as if it was loaded
after the write. That is, the value being written before it is available.

This fixes llvm.org/PR33323

llvm-svn: 304810
2017-06-06 17:46:42 +00:00
Michael Kruse fa7be88378 [Simplify] Remove identical write removal. NFC.
Removal of overwritten writes currently encompasses all the cases
of the identical write removal.

There is an observable behavioral change in that the last, instead
of the first, MemoryAccess is kept. This should not affect the
generated code, however.

Differential Revision: https://reviews.llvm.org/D33143

llvm-svn: 302987
2017-05-13 12:20:57 +00:00
Michael Kruse f263610b82 [Simplify] Remove writes that are overwritten.
Remove memory writes that are overwritten by later writes. This works
for StoreInsts:

      store double 21.0, double* %A
      store double 42.0, double* %A

scalar writes at the end of a statement and mixes of these.

Multiple writes can be the result of DeLICM, which might map multiple
writes to the same location when it knows that these do no conflict
(for instance because they write the same value). Such writes
interfere with pattern-matched optimization such as gemm and may not
get removed by other LLVM passes after code generation.

Differential Revision: https://reviews.llvm.org/D33142

llvm-svn: 302986
2017-05-13 11:49:34 +00:00
Michael Kruse 07e315e780 [Simplify] Remove identical scalar writes.
After DeLICM, it is possible to have two writes of the same value to
the same location in the same statement when it determined that those
writes do not conflict (write the same value).

Teach -polly-simplify to remove one of the writes. It interferes with
the pattern matching of matrix-multiplication kernels and also seem
to not be optimized away by LLVM.

The algorthm is simple, has O(n^2) behaviour (n = max number of
MemoryAccesses in a statement) and only matches the most obvious cases,
but seem to be enough to pattern-match Boost ublas gemm.

Not handled cases include:
- StoreInst instructions (a.k.a. explicit writes), since the value might
  be loaded or overwritten between the two stores.
- PHINode, especially LCSSA, when the PHI value matches with on other's.
- Partial writes (in preparation)

llvm-svn: 302805
2017-05-11 15:07:38 +00:00
Michael Kruse 0446d81e2d [Simplify] Add -polly-simplify pass.
This new pass removes unnecessary accesses and writes. It currently
supports 2 simplifications, but more are planned.

It removes write accesses that write a loaded value back to the location
it was loaded from. It is a typical artifact from DeLICM. Removing it
will get rid of bogus dependencies later in dependency analysis.

It also removes statements without side-effects. ScopInfo already
removes these, but the removal of unnecessary writes can result in
more side-effect free statements.

Differential Revision: https://reviews.llvm.org/D30820

llvm-svn: 297473
2017-03-10 16:05:24 +00:00