[polly] r283744 - [Support/DepInfo] Introduce IslMaxOperationsGuard and make DepInfo use it. NFC.

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 10 04:45:54 PDT 2016


Author: meinersbur
Date: Mon Oct 10 06:45:54 2016
New Revision: 283744

URL: http://llvm.org/viewvc/llvm-project?rev=283744&view=rev
Log:
[Support/DepInfo] Introduce IslMaxOperationsGuard and make DepInfo use it. NFC.

IslMaxOperationsGuard defines a scope where ISL may abort operations because if
it takes too many operations. Replace the call to the raw ISL interface by a
use of the guard.

IslMaxOperationsGuard provides a uniform way to define a maximal computation
time for a code region in C++ using RAII.

Modified:
    polly/trunk/include/polly/Support/GICHelper.h
    polly/trunk/lib/Analysis/DependenceInfo.cpp

Modified: polly/trunk/include/polly/Support/GICHelper.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/Support/GICHelper.h?rev=283744&r1=283743&r2=283744&view=diff
==============================================================================
--- polly/trunk/include/polly/Support/GICHelper.h (original)
+++ polly/trunk/include/polly/Support/GICHelper.h Mon Oct 10 06:45:54 2016
@@ -19,6 +19,7 @@
 #include "isl/aff.h"
 #include "isl/ctx.h"
 #include "isl/map.h"
+#include "isl/options.h"
 #include "isl/set.h"
 #include "isl/union_map.h"
 #include "isl/union_set.h"
@@ -425,6 +426,70 @@ isl_stat foreachPieceWithBreak(
     NonowningIslPtr<isl_pw_aff> PwAff,
     const std::function<isl_stat(IslPtr<isl_set>, IslPtr<isl_aff>)> &F);
 
+/// Scoped limit of ISL operations.
+///
+/// Limits the number of ISL operations during the lifetime of this object. The
+/// idea is to use this as an RAII guard for the scope where the code is aware
+/// that ISL can return errors even when all input is valid. After leaving the
+/// scope, it will return to the error setting as it was before. That also means
+/// that the error setting should not be changed while in that scope.
+///
+/// Such scopes are not allowed to be nested because the previous operations
+/// counter cannot be reset to the previous state, or one that adds the
+/// operations while being in the nested scope. Use therefore is only allowed
+/// while currently a no operations-limit is active.
+class IslMaxOperationsGuard {
+private:
+  /// The ISL context to set the operations limit.
+  ///
+  /// If set to nullptr, there is no need for any action at the end of the
+  /// scope.
+  isl_ctx *IslCtx;
+
+  /// Old OnError setting; to reset to when the scope ends.
+  int OldOnError;
+
+public:
+  /// Enter a max operations scope.
+  ///
+  /// @param IslCtx      The ISL context to set the operations limit for.
+  /// @param LocalMaxOps Maximum number of operations allowed in the
+  ///                    scope. If set to zero, no operations limit is enforced.
+  IslMaxOperationsGuard(isl_ctx *IslCtx, unsigned long LocalMaxOps)
+      : IslCtx(IslCtx) {
+    assert(IslCtx);
+    assert(isl_ctx_get_max_operations(IslCtx) == 0 &&
+           "Nested max operations not supported");
+
+    if (LocalMaxOps == 0) {
+      // No limit on operations; also disable restoring on_error/max_operations.
+      this->IslCtx = nullptr;
+      return;
+    }
+
+    // Save previous state.
+    OldOnError = isl_options_get_on_error(IslCtx);
+
+    // Activate the new setting.
+    isl_ctx_set_max_operations(IslCtx, LocalMaxOps);
+    isl_ctx_reset_operations(IslCtx);
+    isl_options_set_on_error(IslCtx, ISL_ON_ERROR_CONTINUE);
+  }
+
+  /// Leave the max operations scope.
+  ~IslMaxOperationsGuard() {
+    if (!IslCtx)
+      return;
+
+    assert(isl_options_get_on_error(IslCtx) == ISL_ON_ERROR_CONTINUE &&
+           "Unexpected change of the on_error setting");
+
+    // Return to the previous error setting.
+    isl_ctx_set_max_operations(IslCtx, 0);
+    isl_options_set_on_error(IslCtx, OldOnError);
+  }
+};
+
 } // end namespace polly
 
 #endif

Modified: polly/trunk/lib/Analysis/DependenceInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/DependenceInfo.cpp?rev=283744&r1=283743&r2=283744&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/DependenceInfo.cpp (original)
+++ polly/trunk/lib/Analysis/DependenceInfo.cpp Mon Oct 10 06:45:54 2016
@@ -370,74 +370,71 @@ void Dependences::calculateDependences(S
     }
   }
 
-  long MaxOpsOld = isl_ctx_get_max_operations(IslCtx.get());
-  if (OptComputeOut) {
-    isl_ctx_reset_operations(IslCtx.get());
-    isl_ctx_set_max_operations(IslCtx.get(), OptComputeOut);
-  }
+  {
+    IslMaxOperationsGuard MaxOpGuard(IslCtx.get(), OptComputeOut);
+
+    DEBUG(dbgs() << "Read: " << Read << "\n";
+          dbgs() << "Write: " << Write << "\n";
+          dbgs() << "MayWrite: " << MayWrite << "\n";
+          dbgs() << "Schedule: " << Schedule << "\n");
 
-  auto OnErrorStatus = isl_options_get_on_error(IslCtx.get());
-  isl_options_set_on_error(IslCtx.get(), ISL_ON_ERROR_CONTINUE);
+    RAW = WAW = WAR = RED = nullptr;
 
-  DEBUG(dbgs() << "Read: " << Read << "\n";
-        dbgs() << "Write: " << Write << "\n";
-        dbgs() << "MayWrite: " << MayWrite << "\n";
-        dbgs() << "Schedule: " << Schedule << "\n");
+    if (OptAnalysisType == VALUE_BASED_ANALYSIS) {
+      isl_union_flow *Flow;
 
-  RAW = WAW = WAR = RED = nullptr;
+      Flow = buildFlow(Read, Write, MayWrite, Schedule);
 
-  if (OptAnalysisType == VALUE_BASED_ANALYSIS) {
-    isl_union_flow *Flow;
+      RAW = isl_union_flow_get_must_dependence(Flow);
+      isl_union_flow_free(Flow);
 
-    Flow = buildFlow(Read, Write, MayWrite, Schedule);
+      Flow = buildFlow(Write, Write, Read, Schedule);
 
-    RAW = isl_union_flow_get_must_dependence(Flow);
-    isl_union_flow_free(Flow);
+      WAW = isl_union_flow_get_must_dependence(Flow);
+      WAR = isl_union_flow_get_may_dependence(Flow);
 
-    Flow = buildFlow(Write, Write, Read, Schedule);
+      // This subtraction is needed to obtain the same results as were given by
+      // isl_union_map_compute_flow. For large sets this may add some
+      // compile-time cost. As there does not seem to be a need to distinguish
+      // between WAW and WAR, refactoring Polly to only track general non-flow
+      // dependences may improve performance.
+      WAR = isl_union_map_subtract(WAR, isl_union_map_copy(WAW));
 
-    WAW = isl_union_flow_get_must_dependence(Flow);
-    WAR = isl_union_flow_get_may_dependence(Flow);
+      isl_union_flow_free(Flow);
+      isl_schedule_free(Schedule);
+    } else {
+      isl_union_flow *Flow;
 
-    // This subtraction is needed to obtain the same results as were given by
-    // isl_union_map_compute_flow. For large sets this may add some compile-time
-    // cost. As there does not seem to be a need to distinguish between WAW and
-    // WAR, refactoring Polly to only track general non-flow dependences may
-    // improve performance.
-    WAR = isl_union_map_subtract(WAR, isl_union_map_copy(WAW));
+      Write = isl_union_map_union(Write, isl_union_map_copy(MayWrite));
 
-    isl_union_flow_free(Flow);
-    isl_schedule_free(Schedule);
-  } else {
-    isl_union_flow *Flow;
+      Flow = buildFlow(Read, nullptr, Write, Schedule);
 
-    Write = isl_union_map_union(Write, isl_union_map_copy(MayWrite));
+      RAW = isl_union_flow_get_may_dependence(Flow);
+      isl_union_flow_free(Flow);
 
-    Flow = buildFlow(Read, nullptr, Write, Schedule);
+      Flow = buildFlow(Write, nullptr, Read, Schedule);
 
-    RAW = isl_union_flow_get_may_dependence(Flow);
-    isl_union_flow_free(Flow);
+      WAR = isl_union_flow_get_may_dependence(Flow);
+      isl_union_flow_free(Flow);
 
-    Flow = buildFlow(Write, nullptr, Read, Schedule);
+      Flow = buildFlow(Write, nullptr, Write, Schedule);
 
-    WAR = isl_union_flow_get_may_dependence(Flow);
-    isl_union_flow_free(Flow);
+      WAW = isl_union_flow_get_may_dependence(Flow);
+      isl_union_flow_free(Flow);
+      isl_schedule_free(Schedule);
+    }
 
-    Flow = buildFlow(Write, nullptr, Write, Schedule);
+    isl_union_map_free(MayWrite);
+    isl_union_map_free(Write);
+    isl_union_map_free(Read);
+
+    RAW = isl_union_map_coalesce(RAW);
+    WAW = isl_union_map_coalesce(WAW);
+    WAR = isl_union_map_coalesce(WAR);
 
-    WAW = isl_union_flow_get_may_dependence(Flow);
-    isl_union_flow_free(Flow);
-    isl_schedule_free(Schedule);
+    // End of max_operations scope.
   }
 
-  isl_union_map_free(MayWrite);
-  isl_union_map_free(Write);
-  isl_union_map_free(Read);
-
-  RAW = isl_union_map_coalesce(RAW);
-  WAW = isl_union_map_coalesce(WAW);
-  WAR = isl_union_map_coalesce(WAR);
-
   if (isl_ctx_last_error(IslCtx.get()) == isl_error_quota) {
     isl_union_map_free(RAW);
     isl_union_map_free(WAW);
@@ -445,9 +442,6 @@ void Dependences::calculateDependences(S
     RAW = WAW = WAR = nullptr;
     isl_ctx_reset_error(IslCtx.get());
   }
-  isl_options_set_on_error(IslCtx.get(), OnErrorStatus);
-  isl_ctx_reset_operations(IslCtx.get());
-  isl_ctx_set_max_operations(IslCtx.get(), MaxOpsOld);
 
   // Drop out early, as the remaining computations are only needed for
   // reduction dependences or dependences that are finer than statement




More information about the llvm-commits mailing list