Check for feasible runtime check context early

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
This commit is contained in:
Johannes Doerfert 2015-08-20 05:58:56 +00:00
parent 10fe42099c
commit 43788c5783
4 changed files with 46 additions and 6 deletions

View File

@ -1045,6 +1045,17 @@ public:
/// @return The assumed context of this Scop.
__isl_give isl_set *getAssumedContext() const;
/// @brief Get the runtime check context for this Scop.
///
/// The runtime check context contains all constraints that have to
/// hold at runtime for the optimized version to be executed.
///
/// @return The runtime check context of this Scop.
__isl_give isl_set *getRuntimeCheckContext() const;
/// @brief Return true if the runtime check context is feasible.
bool hasFeasibleRuntimeCheckContext() const;
/// @brief Add assumptions to assumed context.
///
/// The assumptions added will be assumed to hold during the execution of the

View File

@ -1593,6 +1593,18 @@ __isl_give isl_set *Scop::getAssumedContext() const {
return isl_set_copy(AssumedContext);
}
__isl_give isl_set *Scop::getRuntimeCheckContext() const {
isl_set *RuntimeCheckContext = getAssumedContext();
return RuntimeCheckContext;
}
bool Scop::hasFeasibleRuntimeCheckContext() const {
isl_set *RuntimeCheckContext = getRuntimeCheckContext();
bool IsFeasible = !isl_set_is_empty(RuntimeCheckContext);
isl_set_free(RuntimeCheckContext);
return IsFeasible;
}
void Scop::addAssumption(__isl_take isl_set *Set) {
AssumedContext = isl_set_intersect(AssumedContext, Set);
AssumedContext = isl_set_coalesce(AssumedContext);
@ -2021,6 +2033,12 @@ bool ScopInfo::runOnRegion(Region *R, RGPassManager &RGM) {
DEBUG(scop->print(dbgs()));
if (!scop->hasFeasibleRuntimeCheckContext()) {
delete scop;
scop = nullptr;
return false;
}
if (!PollyUseRuntimeAliasChecks) {
// Statistics.
++ScopFound;

View File

@ -335,9 +335,10 @@ buildCondition(__isl_keep isl_ast_build *Build, const Scop::MinMaxAccessTy *It0,
void IslAst::buildRunCondition(__isl_keep isl_ast_build *Build) {
// The conditions that need to be checked at run-time for this scop are
// available as an isl_set in the AssumedContext from which we can directly
// derive a run-time condition.
RunCondition = isl_ast_build_expr_from_set(Build, S->getAssumedContext());
// available as an isl_set in the runtime check context from which we can
// directly derive a run-time condition.
RunCondition =
isl_ast_build_expr_from_set(Build, S->getRuntimeCheckContext());
// Create the alias checks from the minimal/maximal accesses in each alias
// group which consists of read only and non read only (read write) accesses.

View File

@ -1,8 +1,18 @@
; RUN: opt %loadPolly -S -polly-opt-isl -polly-codegen < %s | FileCheck %s
; RUN: opt %loadPolly -analyze -polly-detect < %s | FileCheck %s --check-prefix=DETECT
; RUN: opt %loadPolly -analyze -polly-scops < %s | FileCheck %s --check-prefix=INFO
; RUN: opt %loadPolly -analyze -polly-ast < %s | FileCheck %s
;
; This test used to crash the scalar code generation.
; This test used to crash the scalar code generation, now we will bail out after
; ScopInfo and destory the ScoP as the runtime context is empty.
;
; CHECK: polly.start
; DETECT: Valid Region for Scop
;
; INFO-NOT: Context:
; INFO-NOT: Assumed Context:
;
; CHECK-NOT: isl ast
; CHECK-NOT: if (
; CHECK-NOT: original code
;
@endposition = external global i32, align 4
@Bit = external global [0 x i32], align 4