mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-27 02:09:54 +00:00
[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. llvm-svn: 283744
This commit is contained in:
parent
1eb779b5ae
commit
8bfba1ff46
@ -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
|
||||
|
@ -370,74 +370,71 @@ void Dependences::calculateDependences(Scop &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");
|
||||
|
||||
RAW = WAW = WAR = RED = nullptr;
|
||||
|
||||
if (OptAnalysisType == VALUE_BASED_ANALYSIS) {
|
||||
isl_union_flow *Flow;
|
||||
|
||||
Flow = buildFlow(Read, Write, MayWrite, Schedule);
|
||||
|
||||
RAW = isl_union_flow_get_must_dependence(Flow);
|
||||
isl_union_flow_free(Flow);
|
||||
|
||||
Flow = buildFlow(Write, Write, Read, Schedule);
|
||||
|
||||
WAW = isl_union_flow_get_must_dependence(Flow);
|
||||
WAR = isl_union_flow_get_may_dependence(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));
|
||||
|
||||
isl_union_flow_free(Flow);
|
||||
isl_schedule_free(Schedule);
|
||||
} else {
|
||||
isl_union_flow *Flow;
|
||||
|
||||
Write = isl_union_map_union(Write, isl_union_map_copy(MayWrite));
|
||||
|
||||
Flow = buildFlow(Read, nullptr, Write, Schedule);
|
||||
|
||||
RAW = isl_union_flow_get_may_dependence(Flow);
|
||||
isl_union_flow_free(Flow);
|
||||
|
||||
Flow = buildFlow(Write, nullptr, Read, Schedule);
|
||||
|
||||
WAR = isl_union_flow_get_may_dependence(Flow);
|
||||
isl_union_flow_free(Flow);
|
||||
|
||||
Flow = buildFlow(Write, nullptr, Write, Schedule);
|
||||
|
||||
WAW = isl_union_flow_get_may_dependence(Flow);
|
||||
isl_union_flow_free(Flow);
|
||||
isl_schedule_free(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);
|
||||
|
||||
// End of max_operations scope.
|
||||
}
|
||||
|
||||
auto OnErrorStatus = isl_options_get_on_error(IslCtx.get());
|
||||
isl_options_set_on_error(IslCtx.get(), ISL_ON_ERROR_CONTINUE);
|
||||
|
||||
DEBUG(dbgs() << "Read: " << Read << "\n";
|
||||
dbgs() << "Write: " << Write << "\n";
|
||||
dbgs() << "MayWrite: " << MayWrite << "\n";
|
||||
dbgs() << "Schedule: " << Schedule << "\n");
|
||||
|
||||
RAW = WAW = WAR = RED = nullptr;
|
||||
|
||||
if (OptAnalysisType == VALUE_BASED_ANALYSIS) {
|
||||
isl_union_flow *Flow;
|
||||
|
||||
Flow = buildFlow(Read, Write, MayWrite, Schedule);
|
||||
|
||||
RAW = isl_union_flow_get_must_dependence(Flow);
|
||||
isl_union_flow_free(Flow);
|
||||
|
||||
Flow = buildFlow(Write, Write, Read, Schedule);
|
||||
|
||||
WAW = isl_union_flow_get_must_dependence(Flow);
|
||||
WAR = isl_union_flow_get_may_dependence(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));
|
||||
|
||||
isl_union_flow_free(Flow);
|
||||
isl_schedule_free(Schedule);
|
||||
} else {
|
||||
isl_union_flow *Flow;
|
||||
|
||||
Write = isl_union_map_union(Write, isl_union_map_copy(MayWrite));
|
||||
|
||||
Flow = buildFlow(Read, nullptr, Write, Schedule);
|
||||
|
||||
RAW = isl_union_flow_get_may_dependence(Flow);
|
||||
isl_union_flow_free(Flow);
|
||||
|
||||
Flow = buildFlow(Write, nullptr, Read, Schedule);
|
||||
|
||||
WAR = isl_union_flow_get_may_dependence(Flow);
|
||||
isl_union_flow_free(Flow);
|
||||
|
||||
Flow = buildFlow(Write, nullptr, Write, Schedule);
|
||||
|
||||
WAW = isl_union_flow_get_may_dependence(Flow);
|
||||
isl_union_flow_free(Flow);
|
||||
isl_schedule_free(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);
|
||||
|
||||
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(Scop &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
|
||||
|
Loading…
Reference in New Issue
Block a user