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