#include "mlir/Analysis/BufferViewFlowAnalysis.h"
#include "mlir/Interfaces/ControlFlowInterfaces.h"
#include "mlir/Interfaces/ViewLikeInterface.h"
#include "llvm/ADT/SetOperations.h"
using namespace mlir;
BufferViewFlowAnalysis::BufferViewFlowAnalysis(Operation *op) { build(op); }
BufferViewFlowAnalysis::ValueSetT
BufferViewFlowAnalysis::resolve(Value rootValue) const {
ValueSetT result;
SmallVector<Value, 8> queue;
queue.push_back(rootValue);
while (!queue.empty()) {
Value currentValue = queue.pop_back_val();
if (result.insert(currentValue).second) {
auto it = dependencies.find(currentValue);
if (it != dependencies.end()) {
for (Value aliasValue : it->second)
queue.push_back(aliasValue);
}
}
}
return result;
}
void BufferViewFlowAnalysis::remove(const SmallPtrSetImpl<Value> &aliasValues) {
for (auto &entry : dependencies)
llvm::set_subtract(entry.second, aliasValues);
}
void BufferViewFlowAnalysis::build(Operation *op) {
auto registerDependencies = [&](auto values, auto dependencies) {
for (auto entry : llvm::zip(values, dependencies))
this->dependencies[std::get<0>(entry)].insert(std::get<1>(entry));
};
op->walk([&](ViewLikeOpInterface viewInterface) {
dependencies[viewInterface.getViewSource()].insert(
viewInterface->getResult(0));
});
op->walk([&](BranchOpInterface branchInterface) {
Block *parentBlock = branchInterface->getBlock();
for (auto it = parentBlock->succ_begin(), e = parentBlock->succ_end();
it != e; ++it) {
auto successorOperands =
branchInterface.getSuccessorOperands(it.getIndex());
registerDependencies(successorOperands.getForwardedOperands(),
(*it)->getArguments().drop_front(
successorOperands.getProducedOperandCount()));
}
});
op->walk([&](RegionBranchOpInterface regionInterface) {
SmallVector<RegionSuccessor, 2> entrySuccessors;
regionInterface.getSuccessorRegions(llvm::None, entrySuccessors);
for (RegionSuccessor &entrySuccessor : entrySuccessors) {
assert(entrySuccessor.getSuccessor() &&
"Invalid entry region without an attached successor region");
registerDependencies(
regionInterface.getSuccessorEntryOperands(
entrySuccessor.getSuccessor()->getRegionNumber()),
entrySuccessor.getSuccessorInputs());
}
for (Region ®ion : regionInterface->getRegions()) {
SmallVector<RegionSuccessor, 2> successorRegions;
regionInterface.getSuccessorRegions(region.getRegionNumber(),
successorRegions);
for (RegionSuccessor &successorRegion : successorRegions) {
Optional<unsigned> regionIndex;
Region *regionSuccessor = successorRegion.getSuccessor();
if (regionSuccessor)
regionIndex = regionSuccessor->getRegionNumber();
for (Block &block : region) {
auto successorOperands = getRegionBranchSuccessorOperands(
block.getTerminator(), regionIndex);
if (successorOperands) {
registerDependencies(*successorOperands,
successorRegion.getSuccessorInputs());
}
}
}
}
});
}