8000 [mlir][loops] Reland Refactor LoopFuseSiblingOp and support parallel fusion #94391 by srcarroll · Pull Request #97607 · llvm/llvm-project · GitHub
[go: up one dir, main page]

Skip to content

[mlir][loops] Reland Refactor LoopFuseSiblingOp and support parallel fusion #94391 #97607

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 40 commits into from
Jul 3, 2024
Merged
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
5020e49
Add getters for multi dim loop variables in LoopLikeOpInterface
srcarroll Jun 5, 2024
50852d5
Refactor LoopFuseSiblingOp and support parallel fusion
srcarroll Jun 4, 2024
b73238a
add checkFusionStructuralLegality
srcarroll Jun 5, 2024
f5bbd13
replace isLoopWithIdenticalConfiguration with checkFusionStructuralLe…
srcarroll Jun 5, 2024
7d99581
address review comment
srcarroll Jun 5, 2024
a5fa3b3
Make return types optional and change names
srcarroll Jun 6, 2024
1babe68
change return type of getInductionVars to SmallVector<Value>
srcarroll Jun 6, 2024
009fd15
address maks's comments
srcarroll Jun 6, 2024
d34ad95
change interface method names again and revert steps operand change
srcarroll Jun 6, 2024
e0e5262
return option induction vars
srcarroll Jun 6, 2024
7115a6e
address review comments
srcarroll Jun 7, 2024
1d4a444
Merge branch 'main' into add-loop-like-interface-methods
srcarroll Jun 7, 2024
af6b030
Merge branch 'add-loop-like-interface-methods' into scf-parallel-loop…
srcarroll Jun 7, 2024
6336fdf
update after rebase
srcarroll Jun 7, 2024
aa15617
Merge branch 'main' into scf-parallel-loop-fusion
srcarroll Jun 7, 2024
7dbe646
Merge branch 'main' into scf-parallel-loop-fusion
srcarroll Jun 8, 2024
86406c3
refactor main parallel fusion logic from fuseIfLegal to util func
srcarroll Jun 9, 2024
694d589
remove unused functions
srcarroll Jun 9, 2024
67cb64f
refactor fuseIndependentSiblingForLoops to reuse replaceWithAdditiona…
srcarroll Jun 9, 2024
cc8599f
refactor fuseIndependentSiblingForallLoops to reuse replaceWithAdditi…
srcarroll Jun 9, 2024
48b1af9
wip
srcarroll Jun 10, 2024
7a51cb3
Decouple concrete loop type from `createFused` function
srcarroll Jun 17, 2024
3087326
Refactor ForallOp::replaceWithAdditionalYields
srcarroll Jun 17, 2024
bcf3d4a
revert unnecessary changes
srcarroll Jun 17, 2024
0cb3c4e
cleanup
srcarroll Jun 18, 2024
7e41a54
address some review comments
srcarroll Jun 21, 2024
cc95d75
move `createFused` to `LoopLikeInterface.h`
srcarroll Jun 24, 2024
3430a36
address more review comments
srcarroll Jun 26, 2024
8447c12
switch to function_ref
srcarroll Jun 27, 2024
fbd7b72
check optional values
srcarroll Jun 27, 2024
ffb73a7
replace equalIterationSpaces with checkFusionStructuredLegality
srcarroll Jun 27, 2024
a6d0588
check if isOpSibling in checkFusionStructuralLegality
srcarroll Jun 27, 2024
ff47980
remove extra dominance check
srcarroll Jun 27, 2024
c6847ec
address more review comments
srcarroll Jun 27, 2024
f50c6aa
add more lit tests for scf.parallel
srcarroll Jun 27, 2024
6dd68c1
check for equal loop types in checkFusionStructuralLegality
srcarroll Jun 27, 2024
99d821b
address more comments
srcarroll Jun 27, 2024
6825c15
Merge branch 'main' into scf-parallel-loop-fusion
srcarroll Jun 27, 2024
7f9c172
Fix bug in fusion refactor and add test
srcarroll Jul 3, 2024
4b4fd91
add comment
srcarroll Jul 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
remove unused functions
  • Loading branch information
srcarroll committed Jun 9, 2024
commit 694d589dc535892f3dda9d27c2a43052fc0b445e
113 changes: 0 additions & 113 deletions mlir/lib/Dialect/SCF/Utils/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1071,119 +1071,6 @@ TileLoops mlir::extractFixedOuterLoops(scf::ForOp rootForOp,
return tileLoops;
}

/// Checks if the parallel loops have mixed access to the same buffers. Returns
/// `true` if the first parallel loop writes to the same indices that the second
/// loop reads.
static bool haveNoReadsAfterWriteExceptSameIndex(
scf::ParallelOp firstPloop, scf::ParallelOp secondPloop,
const IRMapping &firstToSecondPloopIndices,
llvm::function_ref<bool(Value, Value)> mayAlias) {
DenseMap<Value, SmallVector<ValueRange, 1>> bufferStores;
SmallVector<Value> bufferStoresVec;
firstPloop.getBody()->walk([&](memref::StoreOp store) {
bufferStores[store.getMemRef()].push_back(store.getIndices());
bufferStoresVec.emplace_back(store.getMemRef());
});
auto walkResult = secondPloop.getBody()->walk([&](memref::LoadOp load) {
Value loadMem = load.getMemRef();
// Stop if the memref is defined in secondPloop body. Careful alias analysis
// is needed.
auto *memrefDef = loadMem.getDefiningOp();
if (memrefDef && memrefDef->getBlock() == load->getBlock())
return WalkResult::interrupt();

for (Value store : bufferStoresVec)
if (store != loadMem && mayAlias(store, loadMem))
return WalkResult::interrupt();

auto write = bufferStores.find(loadMem);
if (write == bufferStores.end())
return WalkResult::advance();

// Check that at last one store was retrieved
if (!write->second.size())
return WalkResult::interrupt();

auto storeIndices = write->second.front();

// Multiple writes to the same memref are allowed only on the same indices
for (const auto &othStoreIndices : write->second) {
if (othStoreIndices != storeIndices)
return WalkResult::interrupt();
}

// Check that the load indices of secondPloop coincide with store indices of
// firstPloop for the same memrefs.
auto loadIndices = load.getIndices();
if (storeIndices.size() != loadIndices.size())
return WalkResult::interrupt();
for (int i = 0, e = storeIndices.size(); i < e; ++i) {
if (firstToSecondPloopIndices.lookupOrDefault(storeIndices[i]) !=
loadIndices[i]) {
auto *storeIndexDefOp = storeIndices[i].getDefiningOp();
auto *loadIndexDefOp = loadIndices[i].getDefiningOp();
if (storeIndexDefOp && loadIndexDefOp) {
if (!isMemoryEffectFree(storeIndexDefOp))
return WalkResult::interrupt();
if (!isMemoryEffectFree(loadIndexDefOp))
return WalkResult::interrupt();
if (!OperationEquivalence::isEquivalentTo(
storeIndexDefOp, loadIndexDefOp,
[&](Value storeIndex, Value loadIndex) {
if (firstToSecondPloopIndices.lookupOrDefault(storeIndex) !=
firstToSecondPloopIndices.lookupOrDefault(loadIndex))
return failure();
else
return success();
},
/*markEquivalent=*/nullptr,
OperationEquivalence::Flags::IgnoreLocations)) {
return WalkResult::interrupt();
}
} else
return WalkResult::interrupt();
}
}
return WalkResult::advance();
});
return !walkResult.wasInterrupted();
}

/// Analyzes dependencies in the most primitive way by checking simple read and
/// write patterns.
static LogicalResult
verifyDependencies(scf::ParallelOp firstPloop, scf::ParallelOp secondPloop,
const IRMapping &firstToSecondPloopIndices,
llvm::function_ref<bool(Value, Value)> mayAlias) {
if (!haveNoReadsAfterWriteExceptSameIndex(
firstPloop, secondPloop, firstToSecondPloopIndices, mayAlias))
return failure();

IRMapping secondToFirstPloopIndices;
secondToFirstPloopIndices.map(secondPloop.getBody()->getArguments(),
firstPloop.getBody()->getArguments());
return success(haveNoReadsAfterWriteExceptSameIndex(
secondPloop, firstPloop, secondToFirstPloopIndices, mayAlias));
}

/// Verify equal iteration spaces.
static bool equalIterationSpaces(scf::ParallelOp firstPloop,
scf::ParallelOp secondPloop) {
if (firstPloop.getNumLoops() != secondPloop.getNumLoops())
return false;

auto matchOperands = [&](const OperandRange &lhs,
const OperandRange &rhs) -> bool {
// TODO: Extend this to support aliases and equal constants.
return std::equal(lhs.begin(), lhs.end(), rhs.begin());
};
return matchOperands(firstPloop.getLowerBound(),
secondPloop.getLowerBound()) &&
matchOperands(firstPloop.getUpperBound(),
secondPloop.getUpperBound()) &&
matchOperands(firstPloop.getStep(), secondPloop.getStep());
}

//===----------------------------------------------------------------------===//
// Fusion related helpers
//===----------------------------------------------------------------------===//
Expand Down
0