Skip to content

Commit 526ec90

Browse files
authored
Distribute immediately after wrap (#207)
* Fix barriers betting removed when they are required for interchange * Fix distributing after wrap * Make dsitrib after for respect mincut setting * Ignore CacheLoadOp's memory effects when checking recomputability * Use FullyRecomputable function in while wrap and interchange * Make CacheLoad a no side effect op * Reuse code for recomputability check * clang-format * Remove NoSideEffects from CacheLoad, handle it explicitly * Fix collectEffect behaviour for CanonicalizeFor * Fix distributing around the wrong barrier after a wrap * Forgot to set singleExecution=true for recomputable check before ifs * Update tests * Comments * Do not replicate reads if possible in distribute around barriers * Fix some resultless operations such as yield not getting recomputed * Fix op recalculation when distributing around barrier * Improved check for recomputability in distribute * Update tests * clang format
1 parent 4bef66b commit 526ec90

File tree

7 files changed

+1301
-1230
lines changed

7 files changed

+1301
-1230
lines changed

include/polygeist/Ops.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
#include "mlir/IR/PatternMatch.h"
2525
#include "llvm/Support/CommandLine.h"
2626

27+
bool collectEffects(
28+
mlir::Operation *op,
29+
llvm::SmallVectorImpl<mlir::MemoryEffects::EffectInstance> &effects,
30+
bool ignoreBarriers);
31+
2732
bool getEffectsBefore(
2833
mlir::Operation *op,
2934
llvm::SmallVectorImpl<mlir::MemoryEffects::EffectInstance> &effects,

lib/polygeist/Ops.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,18 @@ LogicalResult verify(BarrierOp) { return success(); }
4242
/// Collect the memory effects of the given op in 'effects'. Returns 'true' it
4343
/// could extract the effect information from the op, otherwise returns 'false'
4444
/// and conservatively populates the list with all possible effects.
45-
static bool
46-
collectEffects(Operation *op,
47-
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
45+
bool collectEffects(Operation *op,
46+
SmallVectorImpl<MemoryEffects::EffectInstance> &effects,
47+
bool ignoreBarriers) {
4848
// Skip over barriers to avoid infinite recursion (those barriers would ask
4949
// this barrier again).
50-
if (isa<BarrierOp>(op))
50+
if (ignoreBarriers && isa<BarrierOp>(op))
51+
return true;
52+
53+
// Ignore CacheLoads as they are already guaranteed to not have side effects
54+
// in the context of a parallel op, these only exist while we are in the
55+
// CPUifyPass
56+
if (isa<CacheLoad>(op))
5157
return true;
5258

5359
// Collect effect instances the operation. Note that the implementation of
@@ -64,7 +70,7 @@ collectEffects(Operation *op,
6470
for (auto &region : op->getRegions()) {
6571
for (auto &block : region) {
6672
for (auto &innerOp : block)
67-
if (!collectEffects(&innerOp, effects))
73+
if (!collectEffects(&innerOp, effects, ignoreBarriers))
6874
return false;
6975
}
7076
}
@@ -94,7 +100,7 @@ bool getEffectsBefore(Operation *op,
94100
else
95101
continue;
96102
}
97-
if (!collectEffects(it, effects))
103+
if (!collectEffects(it, effects, /* ignoreBarriers */ true))
98104
return false;
99105
}
100106

@@ -114,7 +120,7 @@ bool getEffectsBefore(Operation *op,
114120
op->getParentOp()->walk([&](Operation *in) {
115121
if (conservative)
116122
return WalkResult::interrupt();
117-
if (!collectEffects(in, effects)) {
123+
if (!collectEffects(in, effects, /* ignoreBarriers */ true)) {
118124
conservative = true;
119125
return WalkResult::interrupt();
120126
}
@@ -134,7 +140,7 @@ bool getEffectsAfter(Operation *op,
134140
return true;
135141
continue;
136142
}
137-
if (!collectEffects(it, effects))
143+
if (!collectEffects(it, effects, /* ignoreBarriers */ true))
138144
return false;
139145
}
140146

@@ -154,7 +160,7 @@ bool getEffectsAfter(Operation *op,
154160
op->getParentOp()->walk([&](Operation *in) {
155161
if (conservative)
156162
return WalkResult::interrupt();
157-
if (!collectEffects(in, effects)) {
163+
if (!collectEffects(in, effects, /* ignoreBarriers */ true)) {
158164
conservative = true;
159165
return WalkResult::interrupt();
160166
}

lib/polygeist/Passes/CanonicalizeFor.cpp

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,39 +1521,6 @@ struct MoveWhileDown3 : public OpRewritePattern<WhileOp> {
15211521
}
15221522
};
15231523

1524-
static bool
1525-
collectEffects(Operation *op,
1526-
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
1527-
// Collect effect instances the operation. Note that the implementation of
1528-
// getEffects erases all effect instances that have the type other than the
1529-
// template parameter so we collect them first in a local buffer and then
1530-
// copy.
1531-
if (auto iface = dyn_cast<MemoryEffectOpInterface>(op)) {
1532-
SmallVector<MemoryEffects::EffectInstance> localEffects;
1533-
iface.getEffects(localEffects);
1534-
llvm::append_range(effects, localEffects);
1535-
return true;
1536-
}
1537-
if (op->hasTrait<OpTrait::HasRecursiveSideEffects>()) {
1538-
for (auto &region : op->getRegions()) {
1539-
for (auto &block : region) {
1540-
for (auto &innerOp : block)
1541-
if (!collectEffects(&innerOp, effects))
1542-
return false;
1543-
}
1544-
}
1545-
return true;
1546-
}
1547-
1548-
// We need to be conservative here in case the op doesn't have the interface
1549-
// and assume it can have any possible effect.
1550-
effects.emplace_back(MemoryEffects::Effect::get<MemoryEffects::Read>());
1551-
effects.emplace_back(MemoryEffects::Effect::get<MemoryEffects::Write>());
1552-
effects.emplace_back(MemoryEffects::Effect::get<MemoryEffects::Allocate>());
1553-
effects.emplace_back(MemoryEffects::Effect::get<MemoryEffects::Free>());
1554-
return false;
1555-
}
1556-
15571524
// Rewritten from LoopInvariantCodeMotion.cpp
15581525
struct WhileLICM : public OpRewritePattern<WhileOp> {
15591526
using OpRewritePattern<WhileOp>::OpRewritePattern;
@@ -1573,10 +1540,10 @@ struct WhileLICM : public OpRewritePattern<WhileOp> {
15731540
if (isReadOnly(op) && !isSpeculatable) {
15741541

15751542
SmallVector<MemoryEffects::EffectInstance> whileEffects;
1576-
collectEffects(whileOp, whileEffects);
1543+
collectEffects(whileOp, whileEffects, /*ignoreBarriers*/ false);
15771544

15781545
SmallVector<MemoryEffects::EffectInstance> opEffects;
1579-
collectEffects(op, opEffects);
1546+
collectEffects(op, opEffects, /*ignoreBarriers*/ false);
15801547

15811548
bool conflict = false;
15821549
for (auto before : opEffects)

0 commit comments

Comments
 (0)