summaryrefslogtreecommitdiff
path: root/polly/lib
diff options
context:
space:
mode:
authorMichael Kruse <llvm-project@meinersbur.de>2022-06-29 16:44:57 -0500
committerMichael Kruse <llvm-project@meinersbur.de>2022-06-29 17:20:05 -0500
commit6fa65f8a98967a5d2d2a6863e0f67a40d2961905 (patch)
treed282001c3c656e79d9cd256c5891d2ff27af4287 /polly/lib
parent3944780dd89018e7e12bf45bb835ac7f54c40181 (diff)
downloadllvm-6fa65f8a98967a5d2d2a6863e0f67a40d2961905.tar.gz
[Polly][MatMul] Abandon dependence analysis.
The copy statements inserted by the matrix-multiplication optimization introduce new dependencies between the copy statements and other statements. As a result, the DependenceInfo must be recomputed. Not recomputing them caused IslAstInfo to deduce that some loops are parallel but cause race conditions when accessing the packed arrays. As a result, matrix-matrix multiplication currently cannot be parallelized. Also see discussion at https://reviews.llvm.org/D125202
Diffstat (limited to 'polly/lib')
-rw-r--r--polly/lib/Analysis/DependenceInfo.cpp10
-rw-r--r--polly/lib/Transform/MatmulOptimizer.cpp3
-rw-r--r--polly/lib/Transform/ScheduleOptimizer.cpp56
3 files changed, 40 insertions, 29 deletions
diff --git a/polly/lib/Analysis/DependenceInfo.cpp b/polly/lib/Analysis/DependenceInfo.cpp
index f29355ffc51d..d58dc9917bc9 100644
--- a/polly/lib/Analysis/DependenceInfo.cpp
+++ b/polly/lib/Analysis/DependenceInfo.cpp
@@ -848,6 +848,11 @@ const Dependences &DependenceAnalysis::Result::recomputeDependences(
return *D[Level];
}
+void DependenceAnalysis::Result::abandonDependences() {
+ for (std::unique_ptr<Dependences> &Deps : D)
+ Deps.release();
+}
+
DependenceAnalysis::Result
DependenceAnalysis::run(Scop &S, ScopAnalysisManager &SAM,
ScopStandardAnalysisResults &SAR) {
@@ -890,6 +895,11 @@ DependenceInfo::recomputeDependences(Dependences::AnalysisLevel Level) {
return *D[Level];
}
+void DependenceInfo::abandonDependences() {
+ for (std::unique_ptr<Dependences> &Deps : D)
+ Deps.release();
+}
+
bool DependenceInfo::runOnScop(Scop &ScopVar) {
S = &ScopVar;
return false;
diff --git a/polly/lib/Transform/MatmulOptimizer.cpp b/polly/lib/Transform/MatmulOptimizer.cpp
index bad05dfb8ebf..4120cd82a8e0 100644
--- a/polly/lib/Transform/MatmulOptimizer.cpp
+++ b/polly/lib/Transform/MatmulOptimizer.cpp
@@ -491,9 +491,6 @@ createMacroKernel(isl::schedule_node Node,
Node = permuteBandNodeDimensions(Node, DimOutNum - 2, DimOutNum - 1);
Node = permuteBandNodeDimensions(Node, DimOutNum - 3, DimOutNum - 1);
- // Mark the outermost loop as parallelizable.
- Node = Node.as<isl::schedule_node_band>().member_set_coincident(0, true);
-
return Node.child(0).child(0);
}
diff --git a/polly/lib/Transform/ScheduleOptimizer.cpp b/polly/lib/Transform/ScheduleOptimizer.cpp
index c0366514ec50..99645d0ab3dd 100644
--- a/polly/lib/Transform/ScheduleOptimizer.cpp
+++ b/polly/lib/Transform/ScheduleOptimizer.cpp
@@ -228,6 +228,7 @@ struct OptimizerAdditionalInfoTy {
bool PatternOpts;
bool Postopts;
bool Prevect;
+ bool &DepsChanged;
};
class ScheduleTreeOptimizer final {
@@ -526,6 +527,7 @@ ScheduleTreeOptimizer::optimizeBand(__isl_take isl_schedule_node *NodeArg,
tryOptimizeMatMulPattern(Node, OAI->TTI, OAI->D);
if (!PatternOptimizedSchedule.is_null()) {
MatMulOpts++;
+ OAI->DepsChanged = true;
return PatternOptimizedSchedule.release();
}
}
@@ -676,21 +678,21 @@ static void walkScheduleTreeForStatistics(isl::schedule Schedule, int Version) {
&Version);
}
-static bool runIslScheduleOptimizer(
+static void runIslScheduleOptimizer(
Scop &S,
function_ref<const Dependences &(Dependences::AnalysisLevel)> GetDeps,
TargetTransformInfo *TTI, OptimizationRemarkEmitter *ORE,
- isl::schedule &LastSchedule) {
+ isl::schedule &LastSchedule, bool &DepsChanged) {
// Skip SCoPs in case they're already optimised by PPCGCodeGeneration
if (S.isToBeSkipped())
- return false;
+ return;
// Skip empty SCoPs but still allow code generation as it will delete the
// loops present but not needed.
if (S.getSize() == 0) {
S.markAsOptimized();
- return false;
+ return;
}
ScopsProcessed++;
@@ -706,7 +708,7 @@ static bool runIslScheduleOptimizer(
&S, Schedule, GetDeps(Dependences::AL_Statement), ORE);
if (ManuallyTransformed.is_null()) {
LLVM_DEBUG(dbgs() << "Error during manual optimization\n");
- return false;
+ return;
}
if (ManuallyTransformed.get() != Schedule.get()) {
@@ -724,18 +726,18 @@ static bool runIslScheduleOptimizer(
// metadata earlier in ScopDetection.
if (!HasUserTransformation && S.hasDisableHeuristicsHint()) {
LLVM_DEBUG(dbgs() << "Heuristic optimizations disabled by metadata\n");
- return false;
+ return;
}
// Get dependency analysis.
const Dependences &D = GetDeps(Dependences::AL_Statement);
if (D.getSharedIslCtx() != S.getSharedIslCtx()) {
LLVM_DEBUG(dbgs() << "DependenceInfo for another SCoP/isl_ctx\n");
- return false;
+ return;
}
if (!D.hasValidDependences()) {
LLVM_DEBUG(dbgs() << "Dependency information not available\n");
- return false;
+ return;
}
// Apply ISL's algorithm only if not overriden by the user. Note that
@@ -769,7 +771,7 @@ static bool runIslScheduleOptimizer(
isl::union_set Domain = S.getDomains();
if (Domain.is_null())
- return false;
+ return;
isl::union_map Validity = D.getDependences(ValidityKinds);
isl::union_map Proximity = D.getDependences(ProximityKinds);
@@ -847,7 +849,7 @@ static bool runIslScheduleOptimizer(
// In cases the scheduler is not able to optimize the code, we just do not
// touch the schedule.
if (Schedule.is_null())
- return false;
+ return;
if (GreedyFusion) {
isl::union_map Validity = D.getDependences(
@@ -858,10 +860,12 @@ static bool runIslScheduleOptimizer(
// Apply post-rescheduling optimizations (if enabled) and/or prevectorization.
const OptimizerAdditionalInfoTy OAI = {
- TTI, const_cast<Dependences *>(&D),
+ TTI,
+ const_cast<Dependences *>(&D),
/*PatternOpts=*/!HasUserTransformation && PMBasedOpts,
/*Postopts=*/!HasUserTransformation && EnablePostopts,
- /*Prevect=*/PollyVectorizerChoice != VECTORIZER_NONE};
+ /*Prevect=*/PollyVectorizerChoice != VECTORIZER_NONE,
+ DepsChanged};
if (OAI.PatternOpts || OAI.Postopts || OAI.Prevect) {
Schedule = ScheduleTreeOptimizer::optimizeSchedule(Schedule, &OAI);
Schedule = hoistExtensionNodes(Schedule);
@@ -872,7 +876,7 @@ static bool runIslScheduleOptimizer(
// Skip profitability check if user transformation(s) have been applied.
if (!HasUserTransformation &&
!ScheduleTreeOptimizer::isProfitableSchedule(S, Schedule))
- return false;
+ return;
auto ScopStats = S.getStatistics();
ScopsOptimized++;
@@ -885,8 +889,6 @@ static bool runIslScheduleOptimizer(
if (OptimizedScops)
errs() << S;
-
- return false;
}
bool IslScheduleOptimizerWrapperPass::runOnScop(Scop &S) {
@@ -904,7 +906,13 @@ bool IslScheduleOptimizerWrapperPass::runOnScop(Scop &S) {
getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
TargetTransformInfo *TTI =
&getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
- return runIslScheduleOptimizer(S, getDependences, TTI, &ORE, LastSchedule);
+
+ bool DepsChanged = false;
+ runIslScheduleOptimizer(S, getDependences, TTI, &ORE, LastSchedule,
+ DepsChanged);
+ if (DepsChanged)
+ getAnalysis<DependenceInfo>().abandonDependences();
+ return false;
}
static void runScheduleOptimizerPrinter(raw_ostream &OS,
@@ -971,22 +979,18 @@ runIslScheduleOptimizerUsingNPM(Scop &S, ScopAnalysisManager &SAM,
OptimizationRemarkEmitter ORE(&S.getFunction());
TargetTransformInfo *TTI = &SAR.TTI;
isl::schedule LastSchedule;
- bool Modified = runIslScheduleOptimizer(S, GetDeps, TTI, &ORE, LastSchedule);
+ bool DepsChanged = false;
+ runIslScheduleOptimizer(S, GetDeps, TTI, &ORE, LastSchedule, DepsChanged);
+ if (DepsChanged)
+ Deps.abandonDependences();
+
if (OS) {
*OS << "Printing analysis 'Polly - Optimize schedule of SCoP' for region: '"
<< S.getName() << "' in function '" << S.getFunction().getName()
<< "':\n";
runScheduleOptimizerPrinter(*OS, LastSchedule);
}
-
- if (!Modified)
- return PreservedAnalyses::all();
-
- PreservedAnalyses PA;
- PA.preserveSet<AllAnalysesOn<Module>>();
- PA.preserveSet<AllAnalysesOn<Function>>();
- PA.preserveSet<AllAnalysesOn<Loop>>();
- return PA;
+ return PreservedAnalyses::all();
}
llvm::PreservedAnalyses