Commit Graph

250 Commits

Author SHA1 Message Date
Michael Kruse
0b56681d21 [ScopDetection] Fix use-after-free.
removeCachedResults deletes the DetectionContext from
DetectionContextMap such that any it cannot be used anymore.
Unfortunately invalid<ReportUnprofitable> and RejectLogs.insert still do
use it. Because the memory is part of a map and not returned to to the
OS immediatly, such that the observable effect was only a memory leak
due to reference counters not decreased when the second call to
removeCachedResults does not remove the DetectionContext because because
it already has been removed.

Fix by not removing the DetectionContext prematurely. The second call to
removeCachedResults will handle it anyway.

llvm-svn: 262235
2016-02-29 16:54:18 +00:00
Hongbin Zheng
8efb22ef25 Enable llvm's isa/cast/dyn_cast on MemAccInst.
Differential Revision: http://reviews.llvm.org/D17250

llvm-svn: 262100
2016-02-27 01:49:58 +00:00
Tobias Grosser
8fa3e4c3fb ScopDetect/Info: Add option to disable invariant load hoisting
This is helpful for test case reduction and other experiments.

llvm-svn: 262033
2016-02-26 16:43:35 +00:00
Michael Kruse
0ac2d3e217 ScopDetection: Fix mix-up of isLoad and isStore.
This was accidentally introduced in r258947.

Thanks to Hongbin Zheng for finding this.

Found-by: etherzhhb
llvm-svn: 262032
2016-02-26 16:40:35 +00:00
Hongbin Zheng
f3d6612c0a [MemAccInst] Introduce the '->' operator and remove the simple wrapper functions. NFC
llvm-svn: 261994
2016-02-26 09:47:11 +00:00
Johannes Doerfert
a792098047 Support calls with known ModRef function behaviour
Check the ModRefBehaviour of functions in order to decide whether or
  not a call instruction might be acceptable.

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

llvm-svn: 261866
2016-02-25 14:08:48 +00:00
Johannes Doerfert
8c83078449 Simplify code [NFC]
llvm-svn: 261864
2016-02-25 14:07:49 +00:00
Johannes Doerfert
9dd42ee7c1 Try to build alias checks even when non-affine accesses are allowed
From now on we bail only if a non-trivial alias group contains a non-affine
  access, not when we discover aliasing and non-affine accesses are allowed.

llvm-svn: 261863
2016-02-25 14:06:11 +00:00
Johannes Doerfert
cea6193b79 Support memory intrinsics
This patch adds support for memcpy, memset and memmove intrinsics. They are
  represented as one (memset) or two (memcpy, memmove) memory accesses in the
  polyhedral model. These accesses have an access range that describes the
  summarized effect of the intrinsic, i.e.,
    memset(&A[i], '$', N);
  is represented as a write access from A[i] to A[i+N].

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

llvm-svn: 261489
2016-02-21 19:13:19 +00:00
Tobias Grosser
a2ee003239 ScopDectect: Allow memory accesses with different element types by default (try 3)
First support for this feature was committed in r259784. Support for
loop invariant load hoisting with different types was added by
Johannes Doerfert in r260045 and r260886.

llvm-svn: 260965
2016-02-16 14:37:24 +00:00
Hongbin Zheng
226232044a [Refactor] Eliminate the global variable "InsnToMemAcc".
Eliminate the global variable "InsnToMemAcc" to make Scop/ScopInfo become
  more protable, such that we can safely use them in a CallGraphSCC pass.

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

llvm-svn: 260863
2016-02-15 00:20:58 +00:00
Tobias Grosser
5e27ec33ea Revert "[ScopDectect] Allow memory accesses with different element types by default"
This reverts commit https://llvm.org/svn/llvm-project/polly/trunk@260853

We unfortunately still have two bugs left which show only up with
-polly-process-unprofitable and which I forgot to test before committing.

llvm-svn: 260854
2016-02-14 19:59:29 +00:00
Tobias Grosser
5f105f9bdd [ScopDectect] Allow memory accesses with different element types by default
First support for this feature was committed in r259784. Support for
loop invariant load hoisting with different types was added by Johannes
Doerfert in r260045. This fixed the last known bug.

llvm-svn: 260853
2016-02-14 19:11:16 +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
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
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
70131d3416 Introduce MemAccInst helper class; NFC
MemAccInst wraps the common members of LoadInst and StoreInst. Also use
of this class in:
- ScopInfo::buildMemoryAccess
- BlockGenerator::generateLocationAccessed
- ScopInfo::addArrayAccess
- Scop::buildAliasGroups
- Replace every use of polly::getPointerOperand

Reviewers: jdoerfert, grosser

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

llvm-svn: 258947
2016-01-27 17:09:17 +00:00
Tobias Grosser
1c3a6d7808 ScopDetection: Do not detect regions with irreducible control as scops
Polly currently does not support irreducible control and it is probably not
worth supporting. This patch adds code that checks for irreducible control
and refuses regions containing irreducible control.

Polly traditionally had rather restrictive checks on the control flow structure
which would have refused irregular control, but within the last couple of months
most of the control flow restrictions have been removed. As part of this
generalization we accidentally allowed irregular control flow.

Contributed-by: Karthik Senthil and Ajith Pandel
llvm-svn: 258497
2016-01-22 09:44:37 +00:00
Tobias Grosser
c6424ae46c ScopDetection: Simplify std::distance(....) to BB->size()
Suggested by: Johannes Doerfert <doerfert@cs.uni-saarland.de>

llvm-svn: 256260
2015-12-22 17:38:59 +00:00
Tobias Grosser
c1a269bf0e Add option to assume single-loop scops with sufficient compute are profitable
If a loop has a sufficiently large amount of compute instruction in its loop
body, it is unlikely that our rewrite of the loop iterators introduces large
performance changes. As Polly can also apply beneficical optimizations (such
as parallelization) to such loop nests, we mark them as profitable.

This option is currently "disabled" by default, but can be used to run
experiments. If enabled by setting it e.g. to 40 instructions, we currently
see some compile-time increases on LNT without any significant run-time
changes.

llvm-svn: 256199
2015-12-21 21:00:43 +00:00
Tobias Grosser
5624d3c978 Adjust formatting to clang-format changes in 256149
llvm-svn: 256151
2015-12-21 12:38:56 +00:00
Tobias Grosser
97fc5bb7f7 ScopDetect: Extract profitability check into subfunction
.. and add some documentation. We also simplify the code by dropping an early
check that is also covered by the the later checks. This might have a small
compile time impact, but as the scops that are skipped are small we should
probably only add this back in the unlikely case that this has a notable
compile-time cost.

No functional change intended.

llvm-svn: 256149
2015-12-21 12:14:48 +00:00
Tobias Grosser
594882573e ScopInfo: Return immediately if scop is unprofitable and marked invalid
As we already log an error when calling invalid, scops unprofitable scops are in
any case marked invalid, but returning immediately safes (a tiny bit of) compile
time and is consistent with our use of 'invalid' in the remainder of the file.

Found by inspection.

llvm-svn: 256140
2015-12-21 09:09:44 +00:00
Tobias Grosser
bfaf1ae309 ScopInfo: Return in case we found an invalid array size
Without this return we still log the incorrect array size (and do not detect
this scop), but we would unnecessarily continue to verify that access functions
are affine. As we do not need to do this, we can return right ahead and
consequently safe compile time.

This issue was found by inspection.

llvm-svn: 256139
2015-12-21 09:09:39 +00:00
Michael Kruse
8fc2896ee0 Compile fix: Use "&&" operator instead of "and"
llvm-svn: 256124
2015-12-20 14:42:32 +00:00
Roman Gareev
8aa437503c Fix delinearization of fortran arrays
The patch fixes Bug 25759 produced by inappropriate handling of unsigned
maximum SCEV expressions by SCEVRemoveMax. Without a fix, we get an infinite
loop and a segmentation fault, if we try to process, for example,
'((-1 + (-1 * %b1)) umax {(-1 + (-1 * %yStart)),+,-1}<%.preheader>)'.
It also fixes a potential issue related to signed maximum SCEV expressions.

Tested-by: Roman Gareev <gareevroman@gmail.com>
Fixed-by: Tobias Grosser <tobias@grosser.es>

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

llvm-svn: 255922
2015-12-17 20:37:17 +00:00
Tobias Grosser
2f8e43d677 ScopInfo: Add support for delinearizing fortran arrays
gfortran (and fortran in general?) does not compute the address of an array
element directly from the array sizes (e.g., %s0, %s1), but takes first the
maximum of the sizes and 0 (e.g., max(0, %s0)) before multiplying the resulting
value with the per-dimension array subscript expressions. To successfully
delinearize index expressions as we see them in fortran, we first filter 'smax'
expressions out of the SCEV expression, use them to guess array size parameters
and only then continue with the existing delinearization.

llvm-svn: 253995
2015-11-24 17:06:38 +00:00
Tobias Grosser
d68ba42556 ScopInfo: Split hasAffineMemoryAccesses() into multiple functions [NFC]
This makes the overall code more readable.

llvm-svn: 253951
2015-11-24 05:00:36 +00:00
Johannes Doerfert
a2a74f09fc Do not enforce lcssa
At some point we enforced lcssa for the loop surrounding the entry block.
  This is not only questionable as it does not check any other loop but also
  not needed any more.

llvm-svn: 253789
2015-11-21 17:00:02 +00:00
Johannes Doerfert
48fe86f1ff Emit SCoP source location as remark during ScopInfo
This removes a similar feature from ScopDetection, though with
  -polly-report that feature present twice anyway.

llvm-svn: 252846
2015-11-12 02:32:32 +00:00
Tobias Grosser
b12b006c4b ScopDetection: Do not allow blocks to reference operands in error blocks
r252713 introduced a couple of regressions due to later basic blocks refering
to instructions defined in error blocks which have not yet been modeled.

This commit is currently just encoding limitations of our modeling and code
generation backends to ensure correctness. In theory, we should be able to
generate and optimize such regions, as everything that is dominated by an error
region is assumed to not be executed anyhow. We currently just lack the code
to make this happen in practice.

llvm-svn: 252725
2015-11-11 12:44:18 +00:00
Tobias Grosser
b76cd3cc56 ScopInfo: Pass domain constraints through error blocks
Previously, we just skipped error blocks during scop construction. With
this change we make sure we can construct domains for error blocks such that
these domains can be forwarded to subsequent basic blocks.

This change ensures that basic blocks that post-dominate and are dominated by
a basic block that branches to an error condition have the very same iteration
domain as the branching basic block. Before, this change we would construct
a domain that excludes all error conditions. Such domains could become _very_
complex and were undesirable to build.

Another solution would have been to drop these constraints using a
dominance/post-dominance check instead of modeling the error blocks. Such
a solution could also work in case of unreachable statements or infinite
loops in the scop. However, as we currently (to my believe incorrectly) model
unreachable basic blocks in the post-dominance tree, such a solution is not
yet feasible and requires first a change to LLVM's post-dominance tree
construction.

This commit addresses the most sever compile time issue reported in:
http://llvm.org/PR25458

llvm-svn: 252713
2015-11-11 08:42:20 +00:00
Tobias Grosser
f423c1200f Remove old and redundant options
We remove -polly-detect-unprofitable and -polly-no-early-exit. Both have been
superseeded by -polly-process-unprofitable and were only kept as aliases for
our buildbots to continue to work. As all buildbots have been moved to the new
options, we can now remove the old ones for good.

llvm-svn: 251787
2015-11-02 10:13:32 +00:00
Tobias Grosser
bf45e74254 ScopDetect: Bail out for non-simple memory accesses
Volatile or atomic memory accesses are currently not supported. Neither did
we think about any special handling needed nor do we support the unknown
instructions the alias set tracker turns them into sometimes. Before this
patch, us not supporting unkown instructions in an alias set caused the
following assertion failures:

Assertion `AG.size() > 1 && "Alias groups should contain at least two accesses"'
failed

llvm-svn: 251234
2015-10-25 13:48:40 +00:00
Tobias Grosser
907090c37c ScopDetection: Update DetectionContextMap accordingly
When verifying if a scop is still valid we rerun all analysis, but did not
update DetectionContextMap. This change ensures that information, e.g. about
non-affine regions, is correctly updated

llvm-svn: 251227
2015-10-25 10:55:35 +00:00
Tobias Grosser
51174cca30 ScopDetection: Do not crash if we find zero array size candidates for delinearization
llvm-svn: 251226
2015-10-25 08:40:44 +00:00
Tobias Grosser
5528dcdf25 ScopDetection: Always refuse multi-dimensional memory accesses with 'undef' in
the size expression.

We previously only checked if the size expression is 'undef', but allowed size
expressions of the form 'undef * undef' by accident. After this change we now
require size expressions to be affine which implies no 'undef' appears anywhere
in the expression.

llvm-svn: 251225
2015-10-25 08:40:38 +00:00
Johannes Doerfert
9c28bfa72c [FIX] Only constant integer branch conditions are always affine
There are several different kinds of constants that could occur in a
  branch condition, however we can only handle the most interesting one
  namely constant integers. To this end we have to treat others as
  non-affine.

  This fixes bug 25244.

llvm-svn: 250669
2015-10-18 22:56:42 +00:00
Johannes Doerfert
01978cfa0c Remove independent blocks pass
Polly can now be used as a analysis only tool as long as the code
  generation is disabled. However, we do not have an alternative to the
  independent blocks pass in place yet, though in the relevant cases
  this does not seem to impact the performance much. Nevertheless, a
  virtual alternative that allows the same transformations without
  changing the input region will follow shortly.

llvm-svn: 250652
2015-10-18 12:28:00 +00:00
Tobias Grosser
e2c8275346 ScopInfo: Allow simple 'AddRec * Parameter' products in delinearization
We also allow such products for cases where 'Parameter' is loaded within the
scop, but where we can dynamically verify that the value of 'Parameter' remains
unchanged during the execution of the scop.

This change relies on Polly's new RequiredILS tracking infrastructure recently
contributed by Johannes.

llvm-svn: 250019
2015-10-12 08:02:30 +00:00
Tobias Grosser
3ecb71696b Add back -polly-detect-unprofitable as alias of -polly-process-unprofitable
This flag was still used in our LNT server. We leave it until it has been
removed from LNT as well.

llvm-svn: 249973
2015-10-11 13:39:17 +00:00
Johannes Doerfert
9b1f9c8b61 Allow eager evaluated binary && and || conditions
The domain generation can handle lazy && and || by default but eager
  evaluated expressions were dismissed as non-affine. With this patch we
  will allow arbitrary combinations of and/or bit-operations in the
  conditions of branches.

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

llvm-svn: 249971
2015-10-11 13:21:03 +00:00
Johannes Doerfert
f363ed9804 [NFC] Move helper functions to ScopHelper
Helper functions in the BlockGenerators.h/cpp introduce dependences
  from the frontend to the backend of Polly. As they are used in
  ScopDetection, ScopInfo, etc. we move them to the ScopHelper file.

llvm-svn: 249919
2015-10-09 23:40:24 +00:00
Johannes Doerfert
c7ab83dfb7 Remove unused flag polly-allow-non-scev-backedge-taken-count
Drop an unused flag polly-allow-non-scev-backedge-taken-count and also
  its occurrences from the tests.

Contributed-by: Chris Jenneisch <chrisj@codeaurora.org>

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

llvm-svn: 249675
2015-10-08 10:05:48 +00:00
Johannes Doerfert
c06b7d67cd Expose the detection context to ScopDetection users
ScopDetection users are interested in the detection context and access
  these via different get-methods. However, not all information was
  exposed though the number of maps to hold it was increasing steadily.
  With this change only the detection contexts the rejection log and the
  ValidRegions set are mapped. The former is needed, the second could be
  integrated in the first and the ValidRegions set is only needed for the
  deterministic order of the regions.

llvm-svn: 249614
2015-10-07 20:46:06 +00:00
Johannes Doerfert
08d90a3cee Treat conditionally executed non-pure calls as errors
This replaces the support for user defined error functions by a
  heuristic that tries to determine if a call to a non-pure function
  should be considered "an error". If so the block is assumed not to be
  executed at runtime. While treating all non-pure function calls as
  errors will allow a lot more regions to be analyzed, it will also
  cause us to dismiss a lot again due to an infeasible runtime context.
  This patch tries to limit that effect. A non-pure function call is
  considered an error if it is executed only in conditionally with
  regards to a cheap but simple heuristic.

llvm-svn: 249611
2015-10-07 20:32:43 +00:00
Johannes Doerfert
09e3697f44 Allow invariant loads in the SCoP description
This patch allows invariant loads to be used in the SCoP description,
  e.g., as loop bounds, conditions or in memory access functions.

  First we collect "required invariant loads" during SCoP detection that
  would otherwise make an expression we care about non-affine. To this
  end a new level of abstraction was introduced before
  SCEVValidator::isAffineExpr() namely ScopDetection::isAffine() and
  ScopDetection::onlyValidRequiredInvariantLoads(). Here we can decide
  if we want a load inside the region to be optimistically assumed
  invariant or not. If we do, it will be marked as required and in the
  SCoP generation we bail if it is actually not invariant. If we don't
  it will be a non-affine expression as before. At the moment we
  optimistically assume all "hoistable" (namely non-loop-carried) loads
  to be invariant. This causes us to expand some SCoPs and dismiss them
  later but it also allows us to detect a lot we would dismiss directly
  if we would ask e.g., AliasAnalysis::canBasicBlockModify(). We also
  allow potential aliases between optimistically assumed invariant loads
  and other pointers as our runtime alias checks are sound in case the
  loads are actually invariant. Together with the invariant checks this
  combination allows to handle a lot more than LICM can.

  The code generation of the invariant loads had to be extended as we
  can now have dependences between parameters and invariant (hoisted)
  loads as well as the other way around, e.g.,
    test/Isl/CodeGen/invariant_load_parameters_cyclic_dependence.ll
  First, it is important to note that we cannot have real cycles but
  only dependences from a hoisted load to a parameter and from another
  parameter to that hoisted load (and so on). To handle such cases we
  materialize llvm::Values for parameters that are referred by a hoisted
  load on demand and then materialize the remaining parameters. Second,
  there are new kinds of dependences between hoisted loads caused by the
  constraints on their execution. If a hoisted load is conditionally
  executed it might depend on the value of another hoisted load. To deal
  with such situations we sort them already in the ScopInfo such that
  they can be generated in the order they are listed in the
  Scop::InvariantAccesses list (see compareInvariantAccesses). The
  dependences between hoisted loads caused by indirect accesses are
  handled the same way as before.

llvm-svn: 249607
2015-10-07 20:17:36 +00:00
Tobias Grosser
575aca8d43 Introduce -polly-process-unprofitable
This single option replaces -polly-detect-unprofitable and -polly-no-early-exit
and is supposed to be the only option that disables compile-time heuristics that
aim to bail out early on scops that are believed to not benefit from Polly
optimizations.

Suggested-by:  Johannes Doerfert
llvm-svn: 249426
2015-10-06 16:10:29 +00:00
Johannes Doerfert
f61df69423 [FIX] Count affine loops correctly
The "unprofitable" heuristic was broken and counted boxed loops
  even though we do not represent and optimize them.

llvm-svn: 249274
2015-10-04 14:56:08 +00:00