At some point we build loop trip counts using this method. It was replaced by
a simpler trick that works only for affine (e.g., not modulo) constraints and
relies on the removal of unbounded parts. In order to allow modulo constrains
again we go back to the former, more accurate method.
llvm-svn: 247540
Summary:
TempScop is basically a holder for AccFuncMap, the dictionary from BasicBlocks to IRAccess lists. We move the list into polly::Scop and remove the polly::TempScop class.
There is one small change in behavior: If ScopInfo finds that its AssumedContext is impossible, it bails out by deleting the Scop object. The TempScop::print (invoked with opt -polly-scops -analyze) cannot print the AccFuncMap anymore as it would with a separate TempScop.
Differential Revision: http://reviews.llvm.org/D12803
llvm-svn: 247480
Hoist runtime checks in the loop nest if they guard an "error" like event.
Such events are recognized as blocks with an unreachable terminator or a call
to the ubsan function that deals with out of bound accesses. Other "error"
events can be added easily.
We will ignore these blocks when we detect/model/optmize and code generate SCoPs
but we will make sure that they would not have been executed using the assumption
framework.
llvm-svn: 247310
As we do not rely on ScalarEvolution any more we do not need to get
the backedge taken count. Additionally, our domain generation handles
everything that is affine and has one latch and our ScopDetection will
over-approximate everything else.
This change will therefor allow loops with:
- one latch
- exiting conditions that are affine
Additionally, it will not check for structured control flow anymore.
Hence, loops and conditionals are not necessarily single entry single
exit regions any more.
Differential Version: http://reviews.llvm.org/D12758
llvm-svn: 247289
The TempScopInfo (-polly-analyze-ir) pass is removed and its work taken
over by ScopInfo (-polly-scops). Several tests depend on
-polly-analyze-ir and use -polly-scops instead which for the moment
prints the output of both passes. This again is not expected by some
other tests, especially those with negative searches, which have been
adapted.
Differential Version: http://reviews.llvm.org/D12694
llvm-svn: 247288
This patch replaces the last legacy part of the domain generation, namely the
ScalarEvolution part that was used to obtain loop bounds. We now iterate over
the loops in the region and propagate the back edge condition to the header
blocks. Afterwards we propagate the new information once through the whole
region. In this process we simply ignore unbounded parts of the domain and
thereby assume the absence of infinite loops.
+ This patch already identified a couple of broken unit tests we had for
years.
+ We allow more loops already and the step to multiple exit and multiple back
edges is minimal.
+ It allows to model the overflow checks properly as we actually visit
every block in the SCoP and know where which condition is evaluated.
- It is currently not compatible with modulo constraints in the
domain.
Differential Revision: http://reviews.llvm.org/D12499
llvm-svn: 247279
This prepares for a series of patches that merges TempScopInfo into ScopInfo to
reduce Polly's code complexity. Only ScopInfo.{cpp|h} will be left thereafter.
Moving the code of TempScopInfo in one commit makes the mains diffs simpler to
understand.
In detail, merging the following classes is planned:
TempScopInfo into ScopInfo
TempScop into Scop
IRAccess into MemoryAccess
Only moving code, no functional changes intended.
Differential Version: http://reviews.llvm.org/D12693
llvm-svn: 247274
While we do not need to model PHI nodes in the region exit (as it is not part
of the SCoP), we need to prepare for the case that the exit block is split in
code generation to create a single exiting block. If this will happen, hence
if the region did not have a single exiting block before, we will model the
operands of the PHI nodes as escaping scalars in the SCoP.
Differential Revision: http://reviews.llvm.org/D12051
llvm-svn: 247078
Originally, we disallowed the import of multi-dimensional access functions due
to our code generation not supporting the generation of new address expressions
for multi-dimensional memory accesses. When building our run-time alias check
infrastructure we added code generation support for multi-dimensional address
calculations. Hence, we can now savely allow the import of new
multi-dimensional access functions.
llvm-svn: 246917
By just removing dimensions (and the constraints they are involved in) we
may loose information about the dimensions we do not remove. By instead
using project_out, we are sure all constraints on the outer dimensions are
preserved.
No test case, as this error condition is very unlikely to be triggered by
isl's current code. We still 'fix' this, as isl gives little guarantees
regarding the behavior of remove_divs.
llvm-svn: 246567
Code generation currently does not expect unbounded loops. When
using ISL to compute the loop trip count, if we find that the
iteration domain remains unbounded, we invalidate the Scop by
creating an infeasible context.
Contributed-by: Matthew Simpson <mssimpso@codeaurora.org>
This fixes PR24634.
Differential Revision: http://reviews.llvm.org/D12493
llvm-svn: 246477
Instead of building domains with MaxLoopDepth dimensions, we now build
the domains such that they have the right amount of dimensions all the
time.
llvm-svn: 246443
In order to compute domain conditions for conditionals we will now
traverse the region in the ScopInfo once and build the domains for
each block in the region. The SCoP statements can then use these
constraints when they build their domain.
The reason behind this change is twofold:
1) This removes a big chunk of preprocessing logic from the
TempScopInfo, namely the Conditionals we used to build there.
Additionally to moving this logic it is also simplified. Instead
of walking the dominance tree up for each basic block in the
region (as we did before), we now traverse the region only
once in order to collect the domain conditions.
2) This is the first step towards the isl based domain creation.
The second step will traverse the region similar to this step,
however it will propagate back edge conditions. Once both are in
place this conditional handling will allow multiple exit loops
additional logic.
Reviewers: grosser
Differential Revision: http://reviews.llvm.org/D12428
llvm-svn: 246398
Use ISL to compute the loop trip count when scalar evolution is unable to do
so.
Contributed-by: Matthew Simpson <mssimpso@codeaurora.org>
Differential Revision: http://reviews.llvm.org/D9444
llvm-svn: 246142
Originally, we intersected the iteration space with the AssumedContext before
computing the minimal/maximal memory offset in our run-time alias checks. With
this patch we drop this intersection as the AssumedContext can - for larger or
more complex scops - become very complicated (contain many disjuncts). When
intersecting an object with many disjuncts with other objects, the number of
disjuncts in these other objects also increases quickly. As a result, the
compile time is unnecessarily increased. This patch now drops the intersection
with the assumed context to ensure we do not pay unnecessary compile time
costs.
With this patch we see -3.17% reduction in compile time for 3mm with default
flags and -17.87% when compiling 3mm with -DPOLYBENCH_USE_C99_PROTO flag. We
did not observe any regressions in LNT.
Contributed-by: Pratik Bhatu <cs12b1010@iith.ac.in>
Reviewers: grosser
Differential Revision: http://reviews.llvm.org/D12198
llvm-svn: 245617
To avoid multiple exits and the resulting complicated conditions when
creating a SCoP we now use the single hasFeasibleRuntimeContext()
check to decide if a SCoP should be dismissed right after
construction. If building runtime checks failed the assumed context is
made infeasible, hence the optimized version will never be executed
and the SCoP can be dismissed.
llvm-svn: 245593
If nothing is executed we can bail out early. Otherwise we can use the
constraints that ensure at least one statement is executed for
simplification.
llvm-svn: 245585
We will record if a SAI is the base of another SAI or derived from it.
This will allow to reason about indirect base pointers later on and
allows a clearer picture of indirection also in the SCoP dump.
llvm-svn: 245584
Instead of generating code for an empty assumed context we bail out
early. As the number of assumptions we generate increases this becomes
more and more important. Additionally, this change will allow us to
hide internal contexts that are only used in runtime checks e.g., a
boundary context with constraints not suited for simplifications.
llvm-svn: 245540
The new field in the MemoryAccess allows us to track a value related
to that access:
- For real memory accesses the value is the loaded result or the
stored value.
- For straigt line scalar accesses it is the access instruction
itself.
- For PHI operand accesses it is the operand value.
We use this value to simplify code which deduced information about the value
later in the Polly pipeline and was known to be error prone.
Reviewers: grosser, Meinsersbur
Subscribers: #polly
Differential Revision: http://reviews.llvm.org/D12062
llvm-svn: 245213
This option allows the user to provide additional information about parameter
values as an isl_set. To specify that N has the value 1024, we can provide
the context -polly-context='[N] -> {: N = 1024}'.
llvm-svn: 245175
This modifies the order in which Polly passes are executed.
Assuming a function has two scops (A and B), the order before was:
FunctionPassManager
ScopDetection
IndependentBlocks
TempScopInfo for A and B
RegionPassManager
ScopInfo for A
DependenceInfo for A
IslScheduleOptimizer for A
IslAstInfo for A
CodeGeneration for A
ScopInfo for B
DependenceInfo for B
IslScheduleOptimizer for B
IslAstInfo for B
CodeGeneration for B
After this patch:
FunctionPassManager
ScopDetection
IndependentBlocks
RegionPassManager
TempScopInfo for A
ScopInfo for A
DependenceInfo for A
IslScheduleOptimizer for A
IslAstInfo for A
CodeGeneration for A
TempScopInfo for B
ScopInfo for B
DependenceInfo for B
IslScheduleOptimizer for B
IslAstInfo for B
CodeGeneration for B
TempScopInfo for B might store information and references to the IR
that CodeGeneration for A might modify. Changing the order ensures that
the IR is not modified from the analysis of a region until code
generation.
Reviewers: grosser
Differential Revision: http://reviews.llvm.org/D12014
llvm-svn: 245091
This change has three major advantages:
- The ScopInfo becomes smaller.
- It allows to use the SCEVAffinator from outside the ScopInfo.
- A member object allows state which in turn allows e.g., caching.
Differential Revision: http://reviews.llvm.org/D9099
llvm-svn: 244730
Summary: The extracted function buildBBScopStmt will be needed later to be invoked individually on the region's exit block.
Reviewers: grosser, jdoerfert
Subscribers: jdoerfert, llvm-commits, pollydev
Projects: #polly
Differential Revision: http://reviews.llvm.org/D11878
llvm-svn: 244443
We use the branch instruction as the location at which a PHI-node write takes
place, instead of the PHI-node itself. This allows us to identify the
basic-block in a region statement which is on the incoming edge of the PHI-node
and for which the write access was originally introduced. As a result we can,
during code generation, avoid generating PHI-node write accesses for basic
blocks that do not preceed the PHI node without having to look at the IR
again.
This change fixes a bug which was introduced in r243420, when we started to
explicitly model PHI-node reads and writes, but dropped some additional checks
that where still necessary during code generation to not emit PHI-node writes
for basic-blocks that are not on incoming edges of the original PHI node.
Compared to the code before r243420 the new code does not need to inspect the IR
any more and we also do not generate multiple redundant writes.
llvm-svn: 243852
It is common practice to keep constructors lightweight. The reasons
include:
- The vtable during the constructor's execution is set to the static
type of the object, not to the vtable of the derived class. That is,
method calls behave differently in constructors and ordinary methods.
This way it is possible to call unimplemented methods of abstract
classes, which usually results in a segmentation fault.
- If an exception is thrown in the constructor, the destructor is not
called, potentially leaking memory.
- Code in constructors cannot be called in a regular way, e.g. from
non-constructor methods of derived classes.
- Because it is common practice, people may not expect the constructor
to do more than initializing data and skip them when looking for bugs.
Not all of these are applicable to LLVM (e.g. exceptions are disabled).
This patch refactors out the computational work in the constructors of
Scop and IslAst into regular init functions and introduces static
create-functions as replacement.
Differential revision: http://reviews.llvm.org/D11491
Reviewers: grosser, jdoerfert
llvm-svn: 243677
Summary:
When translating PHI nodes into memory dependences during code generation we
require two kinds of memory. 'Normal memory' as for all scalar dependences and
'PHI node memory' to store the incoming values of the PHI node. With this
patch we now mark and track these two kinds of memories, which we previously
incorrectly marked as a single memory object.
Being aware of PHI node storage makes code generation easier, as we do not need
to guess what kind of storage a scalar reference requires. This simplifies the
code nicely.
Reviewers: jdoerfert
Subscribers: pollydev, llvm-commits
Differential Revision: http://reviews.llvm.org/D11554
llvm-svn: 243420
As specified in PR23888, run-time alias check generation is expensive
in terms of compile-time. This reduces the compile time by computing
minimal/maximal access only once for each base pointer
Contributed-by: Pratik Bhatu <cs12b1010@iith.ac.in>
llvm-svn: 243024
Instead of flat schedules, we now use so-called schedule trees to represent the
execution order of the statements in a SCoP. Schedule trees make it a lot easier
to analyze, understand and modify properties of a schedule, as specific nodes
in the tree can be choosen and possibly replaced.
This patch does not yet fully move our DependenceInfo pass to schedule trees,
as some additional performance analysis is needed here. (In general schedule
trees should be faster in compile-time, as the more structured representation
is generally easier to analyze and work with). We also can not yet perform the
reduction analysis on schedule trees.
For more information regarding schedule trees, please see Section 6 of
https://lirias.kuleuven.be/handle/123456789/497238
llvm-svn: 242130
Named isl sets can generally have any name if they remain within Polly, but only
certain strings can be parsed by isl. The new names we create ensure that we
can always copy-past isl strings from Polly to other isl tools, e.g. for
debugging.
llvm-svn: 241787
In case we have modulo operations in the access function (supported since
r240518), the assumptions generated to ensure array accesses remain within
bounds can contain existentially quantified dimensions which results in more
complex and more difficult to handle integer sets. As a result LNT's linpack
benchmark started to fail due to excessive compile time.
We now just drop the existentially quantified dimensions. This should be
generally save, but may result in less precise assumptions which may
consequently make us fall back to the original (unoptimized) code more often. In
practice, these cases probably do not appear to often.
I had difficulties to extract a good test case, but fortunately our LNT bots
cover this one well.
llvm-svn: 240775
Remainder operations with constant divisor can be modeled as quasi-affine
expression. This patch adds support for detecting and modeling them. We also
add a test that ensures they are correctly code generated.
This patch was extracted from a larger patch contributed by Johannes Doerfert
in http://reviews.llvm.org/D5293
llvm-svn: 240518
David Blaikie:
"find returns an iterator by value, so it's just added complexity/strangeness to
then use reference lifetime extension to give it the same semantics as if you'd
used a value type instead of a reference type."
llvm-svn: 238294
David Blaike suggested this as an alternative to the use of owningptr(s) for our
memory management, as value semantics allow to avoid the additional interface
complexity caused by owningptr while still providing similar memory consistency
guarantees. We could also have used a std::vector, but the use of std::vector
would yield possibly changing pointers which currently causes problems as for
example the memory accesses carry pointers to their parent statements. Such
pointers should not change.
Reviewer: jblaikie, jdoerfert
Differential Revision: http://reviews.llvm.org/D10041
llvm-svn: 238290
To reduce compile time and to allow more and better quality SCoPs in
the long run we introduced scalar dependences and PHI-modeling. This
patch will now allow us to generate code if one or both of those
options are set. While the principle of demoting scalars as well as
PHIs to memory in order to communicate their value stays the same,
this allows to delay the demotion till the very end (the actual code
generation). Consequently:
- We __almost__ do not modify the code if we do not generate code
for an optimized SCoP in the end. Thus, the early exit as well as
the unprofitable option will now actually preven us from
introducing regressions in case we will probably not get better
code.
- Polly can be used as a "pure" analyzer tool as long as the code
generator is set to none.
- The original SCoP is almost not touched when the optimized version
is placed next to it. Runtime regressions if the runtime checks
chooses the original are not to be expected and later
optimizations do not need to revert the demotion for that part.
- We will generate direct accesses to the demoted values, thus there
are no "trivial GEPs" that select the first element of a scalar we
demoted and treated as an array.
Differential Revision: http://reviews.llvm.org/D7513
llvm-svn: 238070
Instead of explicitly building constraints and adding them to our maps we
now use functions like map_order_le to add the relevant information to the
maps.
llvm-svn: 237934
Being here, we extend the interface to return the element type and not a pointer
to the element type. We also provide a function to get the size (in bytes) of
the elements stored in this array.
We currently still store the element size as an innermost dimension in
ScopArrayInfo, which is somehow inconsistent and should be addressed in future
patches.
llvm-svn: 237779
This reference ID is handy for use cases where we need to identify individual
memory accesses (e.g. to modify their access functions).
This is a reworked version of a patch originally developed by Yabin Hu as part
of his summer of code project.
llvm-svn: 237431
Upcoming revisions of isl require us to include header files explicitly, which
have previously been already transitively included. Before we add them, we sort
the existing includes.
Thanks to Chandler for sort_includes.py. A simple, but very convenient script.
llvm-svn: 236930
This patch also changes the implementation of the ArrayInfoMap to a MapVector
which will ensure that iterating over the list of ArrayInfo objects gives
predictable results. The single loop that currently enumerates the ArrayInfo
objects only frees the individual objectes, hence a possibly changing
iteration order does not affect the outcome. The added robustness is for
future users of this interface.
llvm-svn: 236583
In Polly we used both the term 'scattering' and the term 'schedule' to describe
the execution order of a statement without actually distinguishing between them.
We now uniformly use the term 'schedule' for the execution order. This
corresponds to the terminology of isl.
History: CLooG introduced the term scattering as the generated code can be used
as a sequential execution order (schedule) or as a parallel dimension
enumerating different threads of execution (placement). In Polly and/or isl the
term placement was never used, but we uniformly refer to an execution order as a
schedule and only later introduce parallelism. When doing so we do not talk
about about specific placement dimensions.
llvm-svn: 235380
This will allow the ScopInfo to build the polyhedral representation for
non-affine regions that contain loops. Such loops are basically not visible
in the SCoP representation. Accesses that are variant in such loops are
therefor represented as non-affine accesses.
Differential Revision: http://reviews.llvm.org/D8153
llvm-svn: 234713
This allows us to delinerize code such as:
A[][n]
for (i
for (j
A[i][n-j-1] = ...
which would previously have been delinearize to an access A[i+1][-j-1].
To recover the correct access we apply the piecewise expression:
{ A[i][j] -> A[i-1][i+N]: i < 0; A[i][j] -> A[i][i]: i >= 0}
This approach generalizes to higher dimensions.
llvm-svn: 233566
This will strip the constant factor of a parameter befor we add it to
the SCoP. As a result the access functions are simplified, e.g., for
the attached test case.
llvm-svn: 233501
This allows us to model non-affine regions in the SCoP representation.
SCoP statements can now describe either basic blocks or non-affine
regions. In the latter case all accesses in the region are accumulated
for the statement and write accesses, except in the entry, have to be
marked as may-write.
Differential Revision: http://reviews.llvm.org/D7846
llvm-svn: 230329
Alias checks might become costly if there are divisions that complicate the
description of the accessed locations. By overaproximating them we get fairly
accurate results without the huge compile time cost.
llvm-svn: 229252
This allows us to skip ast and code generation if we did not optimize
a SCoP and will not generate parallel or alias annotations. The
initial heuristic to exit is simple but allows improvements later on.
All failing test cases have been modified to disable early exit, thus
to keep their coverage.
Differential Revision: http://reviews.llvm.org/D7254
llvm-svn: 228851
This change has two main purposes:
1) We do not use a static interface to hide an object we create and
destroy for every basic block we copy.
2) We allow the BlockGenerator to store information between calls to
the copyBB method. This will ease scalar/phi code generation
later on.
While a lot of method signatures were changed this should not cause
any real behaviour change.
Differential Revision: http://reviews.llvm.org/D7467
llvm-svn: 228443
This allows us to model PHI nodes in the polyhedral description
without demoting them. The modeling however will result in the
same accesses as the demotion would have introduced.
Differential Revision: http://reviews.llvm.org/D7415
llvm-svn: 228433
The max loop depth was incorrectly computed for scops that contain a
block from a loop but do not contain the entire loop. We need to
check that the full loop is contained in the region when computing
the max loop depth.
These scops occur when a region containing an inner loop is expanded
to include some blocks from the outer loop, but it cannot be fully
expanded to contain the outer loop because the region containing the
outer loop is invalid.
Differential Revision: http://reviews.llvm.org/D6913
llvm-svn: 225812
This support is still incomplete and consequently hidden behind a switch that
needs to be enabled. One problem is ATM that we incorrectly interpret very large
unsigned values as negative values even if used in an unsigned comparision.
llvm-svn: 225480