diff options
Diffstat (limited to 'polly/lib/Analysis')
| -rw-r--r-- | polly/lib/Analysis/ScopInfo.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index a1643f8b01a..88206f04252 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -94,6 +94,12 @@ static int const MaxDisjunctsInDomain = 20; // number of disjunct when adding non-convex sets to the context. static int const MaxDisjunctsInContext = 4; +// The maximal number of dimensions we allow during invariant load construction. +// More complex access ranges will result in very high compile time and are also +// unlikely to result in good code. This value is very high and should only +// trigger for corner cases (e.g., the "dct_luma" function in h264, SPEC2006). +static int const MaxDimensionsInAccessRange = 9; + static cl::opt<int> OptComputeOut("polly-analysis-computeout", cl::desc("Bound the scop analysis by a maximal amount of " @@ -4024,6 +4030,35 @@ void Scop::addInvariantLoads(ScopStmt &Stmt, InvariantAccessesTy &InvMAs) { isl_set_free(DomainCtx); } +/// Check if an access range is too complex. +/// +/// An access range is too complex, if it contains either many disjuncts or +/// very complex expressions. As a simple heuristic, we assume if a set to +/// be too complex if the sum of existentially quantified dimensions and +/// set dimensions is larger than a threshold. This reliably detects both +/// sets with many disjuncts as well as sets with many divisions as they +/// arise in h264. +/// +/// @param AccessRange The range to check for complexity. +/// +/// @returns True if the access range is too complex. +static bool isAccessRangeTooComplex(isl::set AccessRange) { + unsigned NumTotalDims = 0; + + auto CountDimensions = [&NumTotalDims](isl::basic_set BSet) -> isl::stat { + NumTotalDims += BSet.dim(isl::dim::div); + NumTotalDims += BSet.dim(isl::dim::set); + return isl::stat::ok; + }; + + AccessRange.foreach_basic_set(CountDimensions); + + if (NumTotalDims > MaxDimensionsInAccessRange) + return true; + + return false; +} + isl::set Scop::getNonHoistableCtx(MemoryAccess *Access, isl::union_map Writes) { // TODO: Loads that are not loop carried, hence are in a statement with // zero iterators, are by construction invariant, though we @@ -4072,6 +4107,9 @@ isl::set Scop::getNonHoistableCtx(MemoryAccess *Access, isl::union_map Writes) { SafeToLoad = AccessRelation.range(); } + if (isAccessRangeTooComplex(AccessRelation.range())) + return nullptr; + isl::union_map Written = Writes.intersect_range(SafeToLoad); isl::set WrittenCtx = Written.params(); bool IsWritten = !WrittenCtx.is_empty(); |

