Cleanup code
This commit is contained in:
parent
6b0536d483
commit
9619d130ee
|
@ -9,12 +9,12 @@
|
|||
#ifndef MLIR_LIB_DIALECT_SCF_TRANSFORMS_BARRIERUTILS_H_
|
||||
#define MLIR_LIB_DIALECT_SCF_TRANSFORMS_BARRIERUTILS_H_
|
||||
|
||||
#include "mlir/IR/Block.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "polygeist/Ops.h"
|
||||
#include "mlir/Dialect/SCF/SCF.h"
|
||||
#include "mlir/Dialect/MemRef/IR/MemRef.h"
|
||||
#include "mlir/Dialect/SCF/SCF.h"
|
||||
#include "mlir/Dialect/StandardOps/IR/Ops.h"
|
||||
#include "mlir/IR/Block.h"
|
||||
#include "polygeist/Ops.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
|
||||
void findValuesUsedBelow(mlir::polygeist::BarrierOp barrier,
|
||||
llvm::SetVector<mlir::Value> &crossing);
|
||||
|
@ -24,8 +24,8 @@ findInsertionPointAfterLoopOperands(mlir::scf::ParallelOp op);
|
|||
|
||||
/// Emits the IR computing the total number of iterations in the loop. We don't
|
||||
/// need to linearize them since we can allocate an nD array instead.
|
||||
static llvm::SmallVector<mlir::Value> emitIterationCounts(mlir::OpBuilder &rewriter,
|
||||
mlir::scf::ParallelOp op) {
|
||||
static llvm::SmallVector<mlir::Value>
|
||||
emitIterationCounts(mlir::OpBuilder &rewriter, mlir::scf::ParallelOp op) {
|
||||
using namespace mlir;
|
||||
SmallVector<Value> iterationCounts;
|
||||
for (auto bounds : llvm::zip(op.lowerBound(), op.upperBound(), op.step())) {
|
||||
|
@ -39,32 +39,32 @@ static llvm::SmallVector<mlir::Value> emitIterationCounts(mlir::OpBuilder &rewri
|
|||
return iterationCounts;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
static T allocateTemporaryBuffer(mlir::OpBuilder &rewriter, mlir::Value value,
|
||||
mlir::ValueRange iterationCounts, bool alloca=true) {
|
||||
mlir::ValueRange iterationCounts,
|
||||
bool alloca = true) {
|
||||
using namespace mlir;
|
||||
SmallVector<int64_t> bufferSize(iterationCounts.size(),
|
||||
ShapedType::kDynamicSize);
|
||||
mlir::Type ty = value.getType();
|
||||
if (alloca)
|
||||
if (auto allocaOp = value.getDefiningOp<memref::AllocaOp>()) {
|
||||
auto mt = allocaOp.getType();
|
||||
bool hasDynamicSize = false;
|
||||
for(auto s : mt.getShape()) {
|
||||
if (s == ShapedType::kDynamicSize) {
|
||||
hasDynamicSize = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasDynamicSize) {
|
||||
for(auto s : mt.getShape()) {
|
||||
bufferSize.push_back(s);
|
||||
}
|
||||
ty = mt.getElementType();
|
||||
}
|
||||
if (auto allocaOp = value.getDefiningOp<memref::AllocaOp>()) {
|
||||
auto mt = allocaOp.getType();
|
||||
bool hasDynamicSize = false;
|
||||
for (auto s : mt.getShape()) {
|
||||
if (s == ShapedType::kDynamicSize) {
|
||||
hasDynamicSize = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasDynamicSize) {
|
||||
for (auto s : mt.getShape()) {
|
||||
bufferSize.push_back(s);
|
||||
}
|
||||
ty = mt.getElementType();
|
||||
}
|
||||
}
|
||||
auto type = MemRefType::get(bufferSize, ty);
|
||||
return rewriter.create<T>(value.getLoc(), type, iterationCounts);
|
||||
}
|
||||
#endif // MLIR_LIB_DIALECT_SCF_TRANSFORMS_BARRIERUTILS_H_
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "mlir/Pass/Pass.h"
|
||||
#include "mlir/Conversion/LLVMCommon/LoweringOptions.h"
|
||||
#include "mlir/Pass/Pass.h"
|
||||
#include <memory>
|
||||
namespace mlir {
|
||||
namespace polygeist {
|
||||
|
@ -13,7 +13,8 @@ std::unique_ptr<Pass> createBarrierRemovalContinuation();
|
|||
std::unique_ptr<OperationPass<FuncOp>> detectReductionPass();
|
||||
std::unique_ptr<OperationPass<FuncOp>> createRemoveTrivialUsePass();
|
||||
std::unique_ptr<OperationPass<FuncOp>> createParallelLowerPass();
|
||||
std::unique_ptr<Pass> createConvertPolygeistToLLVMPass(const LowerToLLVMOptions &options);
|
||||
std::unique_ptr<Pass>
|
||||
createConvertPolygeistToLLVMPass(const LowerToLLVMOptions &options);
|
||||
} // namespace polygeist
|
||||
} // namespace mlir
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
#define GET_OP_CLASSES
|
||||
#include "polygeist/PolygeistOps.cpp.inc"
|
||||
|
||||
#include "mlir/Dialect/MemRef/IR/MemRef.h"
|
||||
#include "mlir/Dialect/Affine/IR/AffineOps.h"
|
||||
#include "mlir/Dialect/MemRef/IR/MemRef.h"
|
||||
#include "mlir/Dialect/StandardOps/IR/Ops.h"
|
||||
#include "mlir/Dialect/StandardOps/Utils/Utils.h"
|
||||
|
||||
|
@ -119,12 +119,12 @@ public:
|
|||
if (!subindexOp)
|
||||
return failure();
|
||||
|
||||
if (castOp.getType().cast<MemRefType>().getShape().size() != subindexOp.getType().cast<MemRefType>().getShape().size())
|
||||
if (castOp.getType().cast<MemRefType>().getShape().size() !=
|
||||
subindexOp.getType().cast<MemRefType>().getShape().size())
|
||||
return failure();
|
||||
|
||||
rewriter.replaceOpWithNewOp<SubIndexOp>(
|
||||
castOp, castOp.getType(),
|
||||
subindexOp.source(), subindexOp.index());
|
||||
castOp, castOp.getType(), subindexOp.source(), subindexOp.index());
|
||||
return success();
|
||||
}
|
||||
};
|
||||
|
@ -150,8 +150,10 @@ public:
|
|||
}
|
||||
if (mt0.getShape().size() == mt2.getShape().size() &&
|
||||
mt1.getShape().size() == mt0.getShape().size()) {
|
||||
rewriter.replaceOpWithNewOp<SubIndexOp>(subViewOp, mt2, prevOp.source(),
|
||||
rewriter.create<AddIOp>(prevOp.getLoc(), subViewOp.index(), prevOp.index()));
|
||||
rewriter.replaceOpWithNewOp<SubIndexOp>(
|
||||
subViewOp, mt2, prevOp.source(),
|
||||
rewriter.create<AddIOp>(prevOp.getLoc(), subViewOp.index(),
|
||||
prevOp.index()));
|
||||
return success();
|
||||
}
|
||||
return failure();
|
||||
|
@ -282,56 +284,60 @@ struct DeallocSubView : public OpRewritePattern<SubIndexOp> {
|
|||
}
|
||||
} else if (auto storeOp = dyn_cast<AffineStoreOp>(use.getOwner())) {
|
||||
if (storeOp.memref() == subindex) {
|
||||
if (subindex.getType().cast<MemRefType>().getShape().size() + 1 ==
|
||||
subindex.source()
|
||||
.getType()
|
||||
.cast<MemRefType>()
|
||||
.getShape()
|
||||
.size()) {
|
||||
if (subindex.getType().cast<MemRefType>().getShape().size() + 1 ==
|
||||
subindex.source()
|
||||
.getType()
|
||||
.cast<MemRefType>()
|
||||
.getShape()
|
||||
.size()) {
|
||||
|
||||
std::vector<Value> indices;
|
||||
auto map = storeOp.getAffineMap();
|
||||
indices.push_back(subindex.index());
|
||||
for (size_t i=0; i<map.getNumResults(); i++) {
|
||||
auto apply = rewriter.create<AffineApplyOp>(storeOp.getLoc(), map.getSliceMap(i, 1), storeOp.getMapOperands());
|
||||
indices.push_back(apply->getResult(0));
|
||||
}
|
||||
|
||||
assert(subindex.source()
|
||||
.getType()
|
||||
.cast<MemRefType>()
|
||||
.getShape()
|
||||
.size() == indices.size());
|
||||
rewriter.replaceOpWithNewOp<memref::StoreOp>(
|
||||
storeOp, storeOp.value(), subindex.source(), indices);
|
||||
changed = true;
|
||||
std::vector<Value> indices;
|
||||
auto map = storeOp.getAffineMap();
|
||||
indices.push_back(subindex.index());
|
||||
for (size_t i = 0; i < map.getNumResults(); i++) {
|
||||
auto apply = rewriter.create<AffineApplyOp>(
|
||||
storeOp.getLoc(), map.getSliceMap(i, 1),
|
||||
storeOp.getMapOperands());
|
||||
indices.push_back(apply->getResult(0));
|
||||
}
|
||||
|
||||
assert(subindex.source()
|
||||
.getType()
|
||||
.cast<MemRefType>()
|
||||
.getShape()
|
||||
.size() == indices.size());
|
||||
rewriter.replaceOpWithNewOp<memref::StoreOp>(
|
||||
storeOp, storeOp.value(), subindex.source(), indices);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
} else if (auto storeOp = dyn_cast<AffineLoadOp>(use.getOwner())) {
|
||||
if (storeOp.memref() == subindex) {
|
||||
if (subindex.getType().cast<MemRefType>().getShape().size() + 1 ==
|
||||
subindex.source()
|
||||
.getType()
|
||||
.cast<MemRefType>()
|
||||
.getShape()
|
||||
.size()) {
|
||||
if (subindex.getType().cast<MemRefType>().getShape().size() + 1 ==
|
||||
subindex.source()
|
||||
.getType()
|
||||
.cast<MemRefType>()
|
||||
.getShape()
|
||||
.size()) {
|
||||
|
||||
std::vector<Value> indices;
|
||||
auto map = storeOp.getAffineMap();
|
||||
indices.push_back(subindex.index());
|
||||
for (size_t i=0; i<map.getNumResults(); i++) {
|
||||
auto apply = rewriter.create<AffineApplyOp>(storeOp.getLoc(), map.getSliceMap(i, 1), storeOp.getMapOperands());
|
||||
indices.push_back(apply->getResult(0));
|
||||
}
|
||||
assert(subindex.source()
|
||||
.getType()
|
||||
.cast<MemRefType>()
|
||||
.getShape()
|
||||
.size() == indices.size());
|
||||
rewriter.replaceOpWithNewOp<memref::LoadOp>(
|
||||
storeOp, subindex.source(), indices);
|
||||
changed = true;
|
||||
std::vector<Value> indices;
|
||||
auto map = storeOp.getAffineMap();
|
||||
indices.push_back(subindex.index());
|
||||
for (size_t i = 0; i < map.getNumResults(); i++) {
|
||||
auto apply = rewriter.create<AffineApplyOp>(
|
||||
storeOp.getLoc(), map.getSliceMap(i, 1),
|
||||
storeOp.getMapOperands());
|
||||
indices.push_back(apply->getResult(0));
|
||||
}
|
||||
assert(subindex.source()
|
||||
.getType()
|
||||
.cast<MemRefType>()
|
||||
.getShape()
|
||||
.size() == indices.size());
|
||||
rewriter.replaceOpWithNewOp<memref::LoadOp>(
|
||||
storeOp, subindex.source(), indices);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -352,11 +358,12 @@ struct SelectOfCast : public OpRewritePattern<SelectOp> {
|
|||
auto cst2 = op.getFalseValue().getDefiningOp<memref::CastOp>();
|
||||
if (!cst2)
|
||||
return failure();
|
||||
|
||||
|
||||
if (cst1.source().getType() != cst2.source().getType())
|
||||
return failure();
|
||||
|
||||
auto newSel = rewriter.create<SelectOp>(op.getLoc(), op.condition(), cst1.source(), cst2.source());
|
||||
auto newSel = rewriter.create<SelectOp>(op.getLoc(), op.condition(),
|
||||
cst1.source(), cst2.source());
|
||||
|
||||
rewriter.replaceOpWithNewOp<memref::CastOp>(op, op.getType(), newSel);
|
||||
return success();
|
||||
|
@ -375,12 +382,14 @@ struct SelectOfSubIndex : public OpRewritePattern<SelectOp> {
|
|||
auto cst2 = op.getFalseValue().getDefiningOp<SubIndexOp>();
|
||||
if (!cst2)
|
||||
return failure();
|
||||
|
||||
|
||||
if (cst1.source().getType() != cst2.source().getType())
|
||||
return failure();
|
||||
|
||||
auto newSel = rewriter.create<SelectOp>(op.getLoc(), op.condition(), cst1.source(), cst2.source());
|
||||
auto newIdx = rewriter.create<SelectOp>(op.getLoc(), op.condition(), cst1.index(), cst2.index());
|
||||
auto newSel = rewriter.create<SelectOp>(op.getLoc(), op.condition(),
|
||||
cst1.source(), cst2.source());
|
||||
auto newIdx = rewriter.create<SelectOp>(op.getLoc(), op.condition(),
|
||||
cst1.index(), cst2.index());
|
||||
rewriter.replaceOpWithNewOp<SubIndexOp>(op, op.getType(), newSel, newIdx);
|
||||
return success();
|
||||
}
|
||||
|
@ -388,9 +397,9 @@ struct SelectOfSubIndex : public OpRewritePattern<SelectOp> {
|
|||
|
||||
void SubIndexOp::getCanonicalizationPatterns(OwningRewritePatternList &results,
|
||||
MLIRContext *context) {
|
||||
results
|
||||
.insert<CastOfSubIndex, SubIndexOpMemRefCastFolder, SubIndex2, SubToCast, DeallocSubView,
|
||||
SelectOfCast, SelectOfSubIndex>(context);
|
||||
results.insert<CastOfSubIndex, SubIndexOpMemRefCastFolder, SubIndex2,
|
||||
SubToCast, DeallocSubView, SelectOfCast, SelectOfSubIndex>(
|
||||
context);
|
||||
}
|
||||
|
||||
Value Memref2PointerOp::getViewSource() { return source(); }
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "polygeist/BarrierUtils.h"
|
||||
#include "mlir/Conversion/SCFToStandard/SCFToStandard.h"
|
||||
#include "mlir/Dialect/MemRef/IR/MemRef.h"
|
||||
#include "mlir/Dialect/SCF/Passes.h"
|
||||
|
@ -19,12 +18,13 @@
|
|||
#include "mlir/Dialect/StandardOps/IR/Ops.h"
|
||||
#include "mlir/IR/BlockAndValueMapping.h"
|
||||
#include "mlir/IR/BuiltinOps.h"
|
||||
#include "mlir/IR/Dominance.h"
|
||||
#include "mlir/IR/ImplicitLocOpBuilder.h"
|
||||
#include "mlir/IR/PatternMatch.h"
|
||||
#include "mlir/Pass/Pass.h"
|
||||
#include "mlir/Transforms/DialectConversion.h"
|
||||
#include "polygeist/BarrierUtils.h"
|
||||
#include "polygeist/Passes/Passes.h"
|
||||
#include "mlir/IR/Dominance.h"
|
||||
|
||||
using namespace mlir;
|
||||
using namespace polygeist;
|
||||
|
@ -300,7 +300,6 @@ emitContinuationCase(Value condition, Value storage, scf::ParallelOp parallel,
|
|||
builder.setInsertionPoint(b.getInsertionBlock(), b.getInsertionPoint());
|
||||
}
|
||||
|
||||
|
||||
/// Returns the insertion point (as block pointer and itertor in it) immediately
|
||||
/// after the definition of `v`.
|
||||
static std::pair<Block *, Block::iterator> getInsertionPointAfterDef(Value v) {
|
||||
|
@ -371,7 +370,7 @@ findInsertionPointAfterLoopOperands(scf::ParallelOp op) {
|
|||
/// elements as the surrounding `parallel` loop has iterations, with each
|
||||
/// iteration writing a different element.
|
||||
static void reg2mem(ArrayRef<llvm::SetVector<Block *>> subgraphs,
|
||||
scf::ParallelOp parallel, OpBuilder& allocaBuilder,
|
||||
scf::ParallelOp parallel, OpBuilder &allocaBuilder,
|
||||
OpBuilder &freeBuilder) {
|
||||
// Check if a block exists in another subgraph than the given subgraph (there
|
||||
// may be duplicates).
|
||||
|
@ -421,17 +420,18 @@ static void reg2mem(ArrayRef<llvm::SetVector<Block *>> subgraphs,
|
|||
emitIterationCounts(allocaBuilder, parallel);
|
||||
for (Value value : valuesToStore) {
|
||||
assert(!value.getDefiningOp<polygeist::SubIndexOp>());
|
||||
Value allocation =
|
||||
allocateTemporaryBuffer<mlir::memref::AllocOp>(allocaBuilder, value, iterationCounts, /*alloca*/true);
|
||||
Value allocation = allocateTemporaryBuffer<mlir::memref::AllocOp>(
|
||||
allocaBuilder, value, iterationCounts, /*alloca*/ true);
|
||||
/*
|
||||
if (allocation.getType().cast<MemRefType>().getElementType().isa<MemRefType>()) {
|
||||
llvm::errs() << " value: " << value << " alloc: " << allocation << "\n";
|
||||
if
|
||||
(allocation.getType().cast<MemRefType>().getElementType().isa<MemRefType>())
|
||||
{ llvm::errs() << " value: " << value << " alloc: " << allocation << "\n";
|
||||
llvm_unreachable("bad allocation\n");
|
||||
}
|
||||
*/
|
||||
freeBuilder.create<memref::DeallocOp>(allocation.getLoc(), allocation);
|
||||
accessBuilder.setInsertionPointAfterValue(value);
|
||||
Operation* store = nullptr;
|
||||
Operation *store = nullptr;
|
||||
if (!value.getDefiningOp<memref::AllocaOp>())
|
||||
store = accessBuilder.create<memref::StoreOp>(
|
||||
value.getLoc(), value, allocation, parallel.getInductionVars());
|
||||
|
@ -441,26 +441,27 @@ static void reg2mem(ArrayRef<llvm::SetVector<Block *>> subgraphs,
|
|||
continue;
|
||||
|
||||
if (!value.getDefiningOp<memref::AllocaOp>()) {
|
||||
Value &reloaded = reloadedCache[use.getOwner()];
|
||||
if (!reloaded) {
|
||||
accessBuilder.setInsertionPoint(use.getOwner());
|
||||
reloaded = accessBuilder.create<memref::LoadOp>(
|
||||
value.getLoc(), allocation, parallel.getInductionVars());
|
||||
}
|
||||
use.set(reloaded);
|
||||
Value &reloaded = reloadedCache[use.getOwner()];
|
||||
if (!reloaded) {
|
||||
accessBuilder.setInsertionPoint(use.getOwner());
|
||||
reloaded = accessBuilder.create<memref::LoadOp>(
|
||||
value.getLoc(), allocation, parallel.getInductionVars());
|
||||
}
|
||||
use.set(reloaded);
|
||||
} else {
|
||||
accessBuilder.setInsertionPoint(use.getOwner());
|
||||
auto buf = allocation;
|
||||
for (auto idx : parallel.getInductionVars()) {
|
||||
auto mt0 = buf.getType().cast<MemRefType>();
|
||||
std::vector<int64_t> shape(mt0.getShape());
|
||||
shape.erase(shape.begin());
|
||||
auto mt = MemRefType::get(shape, mt0.getElementType(),
|
||||
mt0.getAffineMaps(), mt0.getMemorySpace());
|
||||
auto subidx = accessBuilder.create<polygeist::SubIndexOp>(allocation.getLoc(), mt, buf, idx);
|
||||
buf = subidx;
|
||||
}
|
||||
use.set(buf);
|
||||
accessBuilder.setInsertionPoint(use.getOwner());
|
||||
auto buf = allocation;
|
||||
for (auto idx : parallel.getInductionVars()) {
|
||||
auto mt0 = buf.getType().cast<MemRefType>();
|
||||
std::vector<int64_t> shape(mt0.getShape());
|
||||
shape.erase(shape.begin());
|
||||
auto mt = MemRefType::get(shape, mt0.getElementType(),
|
||||
mt0.getAffineMaps(), mt0.getMemorySpace());
|
||||
auto subidx = accessBuilder.create<polygeist::SubIndexOp>(
|
||||
allocation.getLoc(), mt, buf, idx);
|
||||
buf = subidx;
|
||||
}
|
||||
use.set(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -533,7 +534,8 @@ static void createContinuations(scf::ParallelOp parallel, Value storage) {
|
|||
cast<scf::ExecuteRegionOp>(¶llel.getBody()->front());
|
||||
startBlocks.insert(&outerExecuteRegion.region().front());
|
||||
for (Block &block : outerExecuteRegion.region()) {
|
||||
if (!isa_and_nonnull<polygeist::BarrierOp>(block.getTerminator()->getPrevNode()))
|
||||
if (!isa_and_nonnull<polygeist::BarrierOp>(
|
||||
block.getTerminator()->getPrevNode()))
|
||||
continue;
|
||||
assert(block.getNumSuccessors() == 1 &&
|
||||
"expected one successor of a block with barrier after splitting");
|
||||
|
@ -546,7 +548,7 @@ static void createContinuations(scf::ParallelOp parallel, Value storage) {
|
|||
auto negOne = builder.create<ConstantIndexOp>(-1);
|
||||
builder.create<memref::StoreOp>(zero, storage);
|
||||
auto loop = builder.create<scf::WhileOp>(TypeRange(), ValueRange());
|
||||
|
||||
|
||||
SmallVector<llvm::SetVector<Block *>> subgraphs;
|
||||
for (Block *block : startBlocks) {
|
||||
traverseUntilBarrier(block, subgraphs.emplace_back());
|
||||
|
@ -569,7 +571,6 @@ static void createContinuations(scf::ParallelOp parallel, Value storage) {
|
|||
builder.create<CmpIOp>(CmpIPredicate::eq, idValue, next);
|
||||
}
|
||||
|
||||
|
||||
for (auto en : llvm::enumerate(subgraphs)) {
|
||||
emitContinuationCase(caseConditions[en.index()], storage, parallel,
|
||||
startBlocks, en.value(), builder);
|
||||
|
@ -580,7 +581,8 @@ static void createContinuations(scf::ParallelOp parallel, Value storage) {
|
|||
}
|
||||
|
||||
static void createContinuations(FuncOp func) {
|
||||
if (func->getNumRegions() == 0 || func.body().empty()) return;
|
||||
if (func->getNumRegions() == 0 || func.body().empty())
|
||||
return;
|
||||
|
||||
OpBuilder allocaBuilder(&func.body().front(), func.body().front().begin());
|
||||
func.walk([&](scf::ParallelOp parallel) {
|
||||
|
|
|
@ -640,8 +640,7 @@ struct MoveWhileToFor : public OpRewritePattern<WhileOp> {
|
|||
case CmpIPredicate::eq:
|
||||
case CmpIPredicate::sgt:
|
||||
case CmpIPredicate::ne:
|
||||
case CmpIPredicate::ugt:
|
||||
{
|
||||
case CmpIPredicate::ugt: {
|
||||
return failure();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,14 +13,14 @@
|
|||
#include "polygeist/Ops.h"
|
||||
#include "polygeist/Passes/Passes.h"
|
||||
|
||||
#include "mlir/Conversion/LLVMCommon/Pattern.h"
|
||||
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
|
||||
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
|
||||
#include "mlir/Analysis/DataLayoutAnalysis.h"
|
||||
#include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h"
|
||||
#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h"
|
||||
#include "mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h"
|
||||
#include "mlir/Conversion/LLVMCommon/ConversionTarget.h"
|
||||
#include "mlir/Conversion/LLVMCommon/Pattern.h"
|
||||
#include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h"
|
||||
#include "mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h"
|
||||
#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h"
|
||||
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
|
||||
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
|
||||
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
|
||||
#include "mlir/Dialect/StandardOps/IR/Ops.h"
|
||||
#include "mlir/Dialect/StandardOps/Transforms/Passes.h"
|
||||
|
@ -50,27 +50,30 @@ struct SubIndexOpLowering : public ConvertOpToLLVMPattern<SubIndexOp> {
|
|||
auto viewMemRefType = subViewOp.getType().cast<MemRefType>();
|
||||
|
||||
if (sourceMemRefType.getShape().size() != viewMemRefType.getShape().size())
|
||||
return failure();
|
||||
return failure();
|
||||
|
||||
|
||||
//MemRefDescriptor sourceMemRef(operands.front());
|
||||
// MemRefDescriptor sourceMemRef(operands.front());
|
||||
SubIndexOp::Adaptor transformed(operands);
|
||||
MemRefDescriptor targetMemRef(transformed.source());//MemRefDescriptor::undef(rewriter, loc, targetDescTy);
|
||||
MemRefDescriptor targetMemRef(
|
||||
transformed
|
||||
.source()); // MemRefDescriptor::undef(rewriter, loc, targetDescTy);
|
||||
|
||||
// Offset.
|
||||
auto llvmIndexType = typeConverter->convertType(rewriter.getIndexType());
|
||||
|
||||
|
||||
if (false) {
|
||||
Value baseOffset = targetMemRef.offset(rewriter, loc);
|
||||
Value stride = targetMemRef.stride(rewriter, loc, 0);
|
||||
Value offset = transformed.index(); //rewriter.create<mlir::IndexCastOp>(loc, operands.back(), stride.getType());
|
||||
Value offset = transformed.index();
|
||||
Value mul = rewriter.create<LLVM::MulOp>(loc, offset, stride);
|
||||
baseOffset = rewriter.create<LLVM::AddOp>(loc, baseOffset, mul);
|
||||
targetMemRef.setOffset(rewriter, loc, baseOffset);
|
||||
} else {
|
||||
Value prev = targetMemRef.alignedPtr(rewriter, loc);
|
||||
Value idxs[] = {transformed.index()};
|
||||
targetMemRef.setAlignedPtr(rewriter, loc, rewriter.create<LLVM::GEPOp>(loc, prev.getType(), prev, idxs));
|
||||
targetMemRef.setAlignedPtr(
|
||||
rewriter, loc,
|
||||
rewriter.create<LLVM::GEPOp>(loc, prev.getType(), prev, idxs));
|
||||
}
|
||||
|
||||
rewriter.replaceOp(subViewOp, {targetMemRef});
|
||||
|
@ -78,7 +81,8 @@ struct SubIndexOpLowering : public ConvertOpToLLVMPattern<SubIndexOp> {
|
|||
}
|
||||
};
|
||||
|
||||
struct Memref2PointerOpLowering : public ConvertOpToLLVMPattern<Memref2PointerOp> {
|
||||
struct Memref2PointerOpLowering
|
||||
: public ConvertOpToLLVMPattern<Memref2PointerOp> {
|
||||
using ConvertOpToLLVMPattern<Memref2PointerOp>::ConvertOpToLLVMPattern;
|
||||
|
||||
LogicalResult
|
||||
|
@ -86,13 +90,15 @@ struct Memref2PointerOpLowering : public ConvertOpToLLVMPattern<Memref2PointerOp
|
|||
ConversionPatternRewriter &rewriter) const override {
|
||||
auto loc = op.getLoc();
|
||||
|
||||
//MemRefDescriptor sourceMemRef(operands.front());
|
||||
// MemRefDescriptor sourceMemRef(operands.front());
|
||||
SubIndexOp::Adaptor transformed(operands);
|
||||
MemRefDescriptor targetMemRef(transformed.source());//MemRefDescriptor::undef(rewriter, loc, targetDescTy);
|
||||
MemRefDescriptor targetMemRef(
|
||||
transformed
|
||||
.source()); // MemRefDescriptor::undef(rewriter, loc, targetDescTy);
|
||||
|
||||
// Offset.
|
||||
auto llvmIndexType = typeConverter->convertType(rewriter.getIndexType());
|
||||
|
||||
|
||||
Value baseOffset = targetMemRef.offset(rewriter, loc);
|
||||
Value ptr = targetMemRef.alignedPtr(rewriter, loc);
|
||||
Value idxs[] = {baseOffset};
|
||||
|
@ -104,7 +110,7 @@ struct Memref2PointerOpLowering : public ConvertOpToLLVMPattern<Memref2PointerOp
|
|||
};
|
||||
|
||||
void populatePolygeistToLLVMConversionPatterns(LLVMTypeConverter &converter,
|
||||
RewritePatternSet &patterns) {
|
||||
RewritePatternSet &patterns) {
|
||||
// clang-format off
|
||||
patterns.add<SubIndexOpLowering>(converter);
|
||||
patterns.add<Memref2PointerOpLowering>(converter);
|
||||
|
|
|
@ -882,18 +882,20 @@ bool Mem2Reg::forwardStoreToLoad(mlir::Value AI, std::vector<ssize_t> idx,
|
|||
}
|
||||
for (auto pair : llvm::enumerate(op.caseDestinations())) {
|
||||
if (pair.value() == block) {
|
||||
auto pval2 = op.getCaseOperands(pair.index())[blockArg.getArgNumber()];
|
||||
auto pval2 =
|
||||
op.getCaseOperands(pair.index())[blockArg.getArgNumber()];
|
||||
if (pval2 != blockArg) {
|
||||
if (pval == nullptr)
|
||||
pval = pval2;
|
||||
else if (pval != pval2) {
|
||||
legal = false;
|
||||
break;
|
||||
}
|
||||
if (pval == nullptr)
|
||||
pval = pval2;
|
||||
else if (pval != pval2) {
|
||||
legal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (legal == false) break;
|
||||
if (legal == false)
|
||||
break;
|
||||
} else {
|
||||
llvm::errs() << *pred->getParent()->getParentOp() << "\n";
|
||||
pred->dump();
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
|
||||
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
|
||||
#include "mlir/Dialect/MemRef/IR/MemRef.h"
|
||||
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
|
||||
#include "mlir/Dialect/SCF/Passes.h"
|
||||
#include "mlir/Dialect/SCF/SCF.h"
|
||||
#include "mlir/Dialect/StandardOps/IR/Ops.h"
|
||||
|
@ -20,8 +20,8 @@
|
|||
#include "mlir/Transforms/DialectConversion.h"
|
||||
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
|
||||
|
||||
#include "polygeist/Ops.h"
|
||||
#include "polygeist/BarrierUtils.h"
|
||||
#include "polygeist/Ops.h"
|
||||
#include "polygeist/Passes/Passes.h"
|
||||
|
||||
#define DEBUG_TYPE "cpuify"
|
||||
|
@ -407,7 +407,7 @@ struct InterchangeForPFor : public OpRewritePattern<scf::ParallelOp> {
|
|||
LLVM_DEBUG(DBGS() << "[interchange] no nested barrier\n";);
|
||||
return failure();
|
||||
}
|
||||
|
||||
|
||||
auto newForLoop =
|
||||
rewriter.create<scf::ForOp>(forLoop.getLoc(), forLoop.lowerBound(),
|
||||
forLoop.upperBound(), forLoop.step());
|
||||
|
@ -604,7 +604,7 @@ struct InterchangeWhilePFor : public OpRewritePattern<scf::ParallelOp> {
|
|||
|
||||
rewriter.eraseOp(whileOp);
|
||||
rewriter.eraseOp(op);
|
||||
|
||||
|
||||
return success();
|
||||
}
|
||||
};
|
||||
|
@ -684,24 +684,24 @@ struct DistributeAroundBarrier : public OpRewritePattern<scf::ParallelOp> {
|
|||
return failure();
|
||||
}
|
||||
|
||||
Operation* barrier;
|
||||
Operation *barrier;
|
||||
{
|
||||
auto it =
|
||||
llvm::find_if(op.getBody()->getOperations(), [](Operation &nested) {
|
||||
return isa<polygeist::BarrierOp>(nested);
|
||||
});
|
||||
if (it == op.getBody()->end()) {
|
||||
LLVM_DEBUG(DBGS() << "[distribute] no barrier in the loop\n");
|
||||
return failure();
|
||||
}
|
||||
barrier = &*it;
|
||||
auto it =
|
||||
llvm::find_if(op.getBody()->getOperations(), [](Operation &nested) {
|
||||
return isa<polygeist::BarrierOp>(nested);
|
||||
});
|
||||
if (it == op.getBody()->end()) {
|
||||
LLVM_DEBUG(DBGS() << "[distribute] no barrier in the loop\n");
|
||||
return failure();
|
||||
}
|
||||
barrier = &*it;
|
||||
}
|
||||
|
||||
llvm::SetVector<Value> crossing;
|
||||
findValuesUsedBelow(barrier, crossing);
|
||||
//std::pair<Block *, Block::iterator> insertPoint =
|
||||
// findInsertionPointAfterLoopOperands(op);
|
||||
//rewriter.setInsertionPoint(insertPoint.first, insertPoint.second);
|
||||
// std::pair<Block *, Block::iterator> insertPoint =
|
||||
// findInsertionPointAfterLoopOperands(op);
|
||||
// rewriter.setInsertionPoint(insertPoint.first, insertPoint.second);
|
||||
rewriter.setInsertionPoint(op);
|
||||
SmallVector<Value> iterationCounts = emitIterationCounts(rewriter, op);
|
||||
|
||||
|
@ -709,7 +709,8 @@ struct DistributeAroundBarrier : public OpRewritePattern<scf::ParallelOp> {
|
|||
SmallVector<memref::AllocOp> allocations;
|
||||
allocations.reserve(crossing.size());
|
||||
for (Value v : crossing) {
|
||||
allocations.push_back(allocateTemporaryBuffer<memref::AllocOp>(rewriter, v, iterationCounts));
|
||||
allocations.push_back(allocateTemporaryBuffer<memref::AllocOp>(
|
||||
rewriter, v, iterationCounts));
|
||||
}
|
||||
|
||||
// Store values crossing the barrier in caches immediately when ready.
|
||||
|
@ -718,22 +719,23 @@ struct DistributeAroundBarrier : public OpRewritePattern<scf::ParallelOp> {
|
|||
Value alloc = std::get<1>(pair);
|
||||
rewriter.setInsertionPointAfter(v.getDefiningOp());
|
||||
if (auto ao = v.getDefiningOp<memref::AllocaOp>()) {
|
||||
for (auto& u : llvm::make_early_inc_range(ao.getResult().getUses())) {
|
||||
rewriter.setInsertionPoint(u.getOwner());
|
||||
auto buf = alloc;
|
||||
for (auto idx : op.getInductionVars()) {
|
||||
auto mt0 = buf.getType().cast<MemRefType>();
|
||||
std::vector<int64_t> shape(mt0.getShape());
|
||||
shape.erase(shape.begin());
|
||||
auto mt = MemRefType::get(shape, mt0.getElementType(),
|
||||
mt0.getAffineMaps(), mt0.getMemorySpace());
|
||||
auto subidx = rewriter.create<polygeist::SubIndexOp>(alloc.getLoc(), mt, buf, idx);
|
||||
buf = subidx;
|
||||
}
|
||||
u.set(buf);
|
||||
for (auto &u : llvm::make_early_inc_range(ao.getResult().getUses())) {
|
||||
rewriter.setInsertionPoint(u.getOwner());
|
||||
auto buf = alloc;
|
||||
for (auto idx : op.getInductionVars()) {
|
||||
auto mt0 = buf.getType().cast<MemRefType>();
|
||||
std::vector<int64_t> shape(mt0.getShape());
|
||||
shape.erase(shape.begin());
|
||||
auto mt =
|
||||
MemRefType::get(shape, mt0.getElementType(),
|
||||
mt0.getAffineMaps(), mt0.getMemorySpace());
|
||||
auto subidx = rewriter.create<polygeist::SubIndexOp>(alloc.getLoc(),
|
||||
mt, buf, idx);
|
||||
buf = subidx;
|
||||
}
|
||||
}
|
||||
else
|
||||
u.set(buf);
|
||||
}
|
||||
} else
|
||||
rewriter.create<memref::StoreOp>(v.getLoc(), v, alloc,
|
||||
op.getInductionVars());
|
||||
}
|
||||
|
@ -749,7 +751,7 @@ struct DistributeAroundBarrier : public OpRewritePattern<scf::ParallelOp> {
|
|||
rewriter.eraseOp(&newLoop.getBody()->back());
|
||||
|
||||
for (auto alloc : allocations)
|
||||
rewriter.create<memref::DeallocOp>(alloc.getLoc(), alloc);
|
||||
rewriter.create<memref::DeallocOp>(alloc.getLoc(), alloc);
|
||||
|
||||
// Recreate the operations in the new loop with new values.
|
||||
rewriter.setInsertionPointToStart(newLoop.getBody());
|
||||
|
@ -757,7 +759,8 @@ struct DistributeAroundBarrier : public OpRewritePattern<scf::ParallelOp> {
|
|||
mapping.map(op.getInductionVars(), newLoop.getInductionVars());
|
||||
SmallVector<Operation *> toDelete;
|
||||
toDelete.push_back(barrier);
|
||||
for (Operation *o = barrier->getNextNode(); o != nullptr; o = o->getNextNode()) {
|
||||
for (Operation *o = barrier->getNextNode(); o != nullptr;
|
||||
o = o->getNextNode()) {
|
||||
rewriter.clone(*o, mapping);
|
||||
toDelete.push_back(o);
|
||||
}
|
||||
|
@ -781,8 +784,8 @@ struct DistributeAroundBarrier : public OpRewritePattern<scf::ParallelOp> {
|
|||
rewriter.setInsertionPoint(nested);
|
||||
|
||||
Value reloaded = rewriter.create<memref::LoadOp>(
|
||||
operand.getOwner()->getLoc(), allocations[pos],
|
||||
newLoop.getInductionVars());
|
||||
operand.getOwner()->getLoc(), allocations[pos],
|
||||
newLoop.getInductionVars());
|
||||
rewriter.startRootUpdate(nested);
|
||||
operand.set(reloaded);
|
||||
rewriter.finalizeRootUpdate(nested);
|
||||
|
@ -882,8 +885,8 @@ struct Reg2MemWhile : public OpRewritePattern<scf::WhileOp> {
|
|||
if (!hasNestedBarrier(op))
|
||||
return failure();
|
||||
|
||||
//Value stackPtr = rewriter.create<LLVM::StackSaveOp>(
|
||||
// op.getLoc(), LLVM::LLVMPointerType::get(rewriter.getIntegerType(8)));
|
||||
// Value stackPtr = rewriter.create<LLVM::StackSaveOp>(
|
||||
// op.getLoc(), LLVM::LLVMPointerType::get(rewriter.getIntegerType(8)));
|
||||
Value zero = rewriter.create<ConstantIndexOp>(op.getLoc(), 0);
|
||||
SmallVector<Value> beforeAllocated, afterAllocated;
|
||||
allocaValues(op.getLoc(), op.getOperands(), zero, rewriter,
|
||||
|
@ -927,7 +930,7 @@ struct Reg2MemWhile : public OpRewritePattern<scf::WhileOp> {
|
|||
rewriter.setInsertionPointAfter(op);
|
||||
SmallVector<Value> results;
|
||||
loadValues(op.getLoc(), afterAllocated, zero, rewriter, results);
|
||||
//rewriter.create<LLVM::StackRestoreOp>(op.getLoc(), stackPtr);
|
||||
// rewriter.create<LLVM::StackRestoreOp>(op.getLoc(), stackPtr);
|
||||
rewriter.replaceOp(op, results);
|
||||
return success();
|
||||
}
|
||||
|
@ -938,31 +941,30 @@ struct CPUifyPass : public SCFCPUifyBase<CPUifyPass> {
|
|||
CPUifyPass(std::string method) : method(method) {}
|
||||
void runOnFunction() override {
|
||||
if (method == "distribute") {
|
||||
OwningRewritePatternList patterns(&getContext());
|
||||
patterns
|
||||
.insert<Reg2MemFor, Reg2MemWhile, ReplaceIfWithFors, WrapForWithBarrier,
|
||||
WrapWhileWithBarrier, InterchangeForPFor,
|
||||
InterchangeForPForLoad, InterchangeWhilePFor, NormalizeLoop,
|
||||
NormalizeParallel, RotateWhile, DistributeAroundBarrier>(
|
||||
&getContext());
|
||||
GreedyRewriteConfig config;
|
||||
config.maxIterations = 142;
|
||||
if (failed(applyPatternsAndFoldGreedily(getFunction(), std::move(patterns),
|
||||
config)))
|
||||
signalPassFailure();
|
||||
OwningRewritePatternList patterns(&getContext());
|
||||
patterns
|
||||
.insert<Reg2MemFor, Reg2MemWhile, ReplaceIfWithFors,
|
||||
WrapForWithBarrier, WrapWhileWithBarrier, InterchangeForPFor,
|
||||
InterchangeForPForLoad, InterchangeWhilePFor, NormalizeLoop,
|
||||
NormalizeParallel, RotateWhile, DistributeAroundBarrier>(
|
||||
&getContext());
|
||||
GreedyRewriteConfig config;
|
||||
config.maxIterations = 142;
|
||||
if (failed(applyPatternsAndFoldGreedily(getFunction(),
|
||||
std::move(patterns), config)))
|
||||
signalPassFailure();
|
||||
} else if (method == "omp") {
|
||||
SmallVector<polygeist::BarrierOp> toReplace;
|
||||
getFunction().walk([&](polygeist::BarrierOp b) {
|
||||
toReplace.push_back(b);
|
||||
});
|
||||
for (auto b : toReplace) {
|
||||
OpBuilder Builder(b);
|
||||
Builder.create<omp::BarrierOp>(b.getLoc());
|
||||
b->erase();
|
||||
}
|
||||
SmallVector<polygeist::BarrierOp> toReplace;
|
||||
getFunction().walk(
|
||||
[&](polygeist::BarrierOp b) { toReplace.push_back(b); });
|
||||
for (auto b : toReplace) {
|
||||
OpBuilder Builder(b);
|
||||
Builder.create<omp::BarrierOp>(b.getLoc());
|
||||
b->erase();
|
||||
}
|
||||
} else {
|
||||
llvm::errs() << "unknown cpuify type: " << method << "\n";
|
||||
llvm_unreachable("unknown cpuify type");
|
||||
llvm::errs() << "unknown cpuify type: " << method << "\n";
|
||||
llvm_unreachable("unknown cpuify type");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -180,7 +180,7 @@ void ParallelLower::runOnFunction() {
|
|||
caller.erase();
|
||||
if (callableOp->use_empty()) {
|
||||
callableOp.erase();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -325,29 +325,31 @@ void ParallelLower::runOnFunction() {
|
|||
});
|
||||
|
||||
container.walk([&](AffineStoreOp storeOp) {
|
||||
OpBuilder bz(storeOp);
|
||||
auto map = storeOp.getAffineMap();
|
||||
std::vector<Value> indices;
|
||||
for (size_t i=0; i<map.getNumResults(); i++) {
|
||||
auto apply = bz.create<AffineApplyOp>(storeOp.getLoc(), map.getSliceMap(i, 1), storeOp.getMapOperands());
|
||||
indices.push_back(apply->getResult(0));
|
||||
}
|
||||
bz.create<memref::StoreOp>(storeOp.getLoc(),
|
||||
storeOp.value(), storeOp.memref(), indices);
|
||||
storeOp.erase();
|
||||
OpBuilder bz(storeOp);
|
||||
auto map = storeOp.getAffineMap();
|
||||
std::vector<Value> indices;
|
||||
for (size_t i = 0; i < map.getNumResults(); i++) {
|
||||
auto apply = bz.create<AffineApplyOp>(
|
||||
storeOp.getLoc(), map.getSliceMap(i, 1), storeOp.getMapOperands());
|
||||
indices.push_back(apply->getResult(0));
|
||||
}
|
||||
bz.create<memref::StoreOp>(storeOp.getLoc(), storeOp.value(),
|
||||
storeOp.memref(), indices);
|
||||
storeOp.erase();
|
||||
});
|
||||
|
||||
|
||||
container.walk([&](AffineLoadOp storeOp) {
|
||||
OpBuilder bz(storeOp);
|
||||
auto map = storeOp.getAffineMap();
|
||||
std::vector<Value> indices;
|
||||
for (size_t i=0; i<map.getNumResults(); i++) {
|
||||
auto apply = bz.create<AffineApplyOp>(storeOp.getLoc(), map.getSliceMap(i, 1), storeOp.getMapOperands());
|
||||
indices.push_back(apply->getResult(0));
|
||||
}
|
||||
storeOp.replaceAllUsesWith((mlir::Value)bz.create<memref::LoadOp>(
|
||||
storeOp.getLoc(), storeOp.memref(), indices));
|
||||
storeOp.erase();
|
||||
OpBuilder bz(storeOp);
|
||||
auto map = storeOp.getAffineMap();
|
||||
std::vector<Value> indices;
|
||||
for (size_t i = 0; i < map.getNumResults(); i++) {
|
||||
auto apply = bz.create<AffineApplyOp>(
|
||||
storeOp.getLoc(), map.getSliceMap(i, 1), storeOp.getMapOperands());
|
||||
indices.push_back(apply->getResult(0));
|
||||
}
|
||||
storeOp.replaceAllUsesWith((mlir::Value)bz.create<memref::LoadOp>(
|
||||
storeOp.getLoc(), storeOp.memref(), indices));
|
||||
storeOp.erase();
|
||||
});
|
||||
|
||||
launchOp.erase();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -542,9 +542,9 @@ public:
|
|||
for (auto expr : CC->inits()) {
|
||||
if (ShowAST) {
|
||||
if (expr->getMember())
|
||||
expr->getMember()->dump();
|
||||
expr->getMember()->dump();
|
||||
if (expr->getInit())
|
||||
expr->getInit()->dump();
|
||||
expr->getInit()->dump();
|
||||
}
|
||||
assert(ThisVal.val);
|
||||
FieldDecl *field = expr->getMember();
|
||||
|
|
|
@ -9,8 +9,11 @@
|
|||
|
||||
#include "mlir/Conversion/AffineToStandard/AffineToStandard.h"
|
||||
#include "mlir/Conversion/LLVMCommon/LoweringOptions.h"
|
||||
#include "mlir/Conversion/MathToLLVM/MathToLLVM.h"
|
||||
#include "mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h"
|
||||
#include "mlir/Conversion/SCFToOpenMP/SCFToOpenMP.h"
|
||||
#include "mlir/Conversion/SCFToStandard/SCFToStandard.h"
|
||||
#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h"
|
||||
#include "mlir/Dialect/Affine/Passes.h"
|
||||
#include "mlir/Dialect/GPU/GPUDialect.h"
|
||||
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
|
||||
|
@ -20,12 +23,9 @@
|
|||
#include "mlir/IR/BuiltinTypes.h"
|
||||
#include "mlir/IR/MLIRContext.h"
|
||||
#include "mlir/IR/Verifier.h"
|
||||
#include "mlir/Pass/PassManager.h"
|
||||
#include "mlir/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h"
|
||||
#include "mlir/Target/LLVMIR/Export.h"
|
||||
#include "mlir/Conversion/MathToLLVM/MathToLLVM.h"
|
||||
#include "mlir/Conversion/SCFToStandard/SCFToStandard.h"
|
||||
#include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h"
|
||||
#include "mlir/Pass/PassManager.h"
|
||||
#include "mlir/Transforms/Passes.h"
|
||||
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
@ -49,16 +49,12 @@ static cl::opt<bool> EmitLLVM("emit-llvm", cl::init(false),
|
|||
cl::desc("Emit llvm"));
|
||||
|
||||
static cl::opt<bool> EmitAssembly("S", cl::init(false),
|
||||
cl::desc("Emit Assembly"));
|
||||
cl::desc("Emit Assembly"));
|
||||
|
||||
static cl::opt<bool> Opt0("O0", cl::init(false),
|
||||
cl::desc("Opt level 0"));
|
||||
static cl::opt<bool> Opt1("O1", cl::init(false),
|
||||
cl::desc("Opt level 1"));
|
||||
static cl::opt<bool> Opt2("O2", cl::init(false),
|
||||
cl::desc("Opt level 2"));
|
||||
static cl::opt<bool> Opt3("O3", cl::init(false),
|
||||
cl::desc("Opt level 3"));
|
||||
static cl::opt<bool> Opt0("O0", cl::init(false), cl::desc("Opt level 0"));
|
||||
static cl::opt<bool> Opt1("O1", cl::init(false), cl::desc("Opt level 1"));
|
||||
static cl::opt<bool> Opt2("O2", cl::init(false), cl::desc("Opt level 2"));
|
||||
static cl::opt<bool> Opt3("O3", cl::init(false), cl::desc("Opt level 3"));
|
||||
|
||||
static cl::opt<bool> SCFOpenMP("scf-openmp", cl::init(true),
|
||||
cl::desc("Emit llvm"));
|
||||
|
@ -98,7 +94,7 @@ static cl::opt<bool> FOpenMP("fopenmp", cl::init(false),
|
|||
cl::desc("Enable OpenMP"));
|
||||
|
||||
static cl::opt<std::string> ToCPU("cpuify", cl::init(""),
|
||||
cl::desc("Convert to cpu"));
|
||||
cl::desc("Convert to cpu"));
|
||||
|
||||
static cl::opt<std::string> MArch("march", cl::init(""),
|
||||
cl::desc("Architecture"));
|
||||
|
@ -148,7 +144,7 @@ std::string GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) {
|
|||
|
||||
// This just needs to be some symbol in the binary; C++ doesn't
|
||||
// allow taking the address of ::main however.
|
||||
void *P = (void*) (intptr_t) GetExecutablePath;
|
||||
void *P = (void *)(intptr_t)GetExecutablePath;
|
||||
return llvm::sys::fs::getMainExecutable(Argv0, P);
|
||||
}
|
||||
static int ExecuteCC1Tool(SmallVectorImpl<const char *> &ArgV) {
|
||||
|
@ -178,7 +174,8 @@ static int ExecuteCC1Tool(SmallVectorImpl<const char *> &ArgV) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int emitBinary(char* Argv0, const char* filename, SmallVectorImpl<char*> &LinkArgs, bool LinkOMP) {
|
||||
int emitBinary(char *Argv0, const char *filename,
|
||||
SmallVectorImpl<char *> &LinkArgs, bool LinkOMP) {
|
||||
|
||||
using namespace clang;
|
||||
using namespace clang::driver;
|
||||
|
@ -187,19 +184,19 @@ int emitBinary(char* Argv0, const char* filename, SmallVectorImpl<char*> &LinkAr
|
|||
// Buffer diagnostics from argument parsing so that we can output them using a
|
||||
// well formed diagnostic object.
|
||||
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
|
||||
TextDiagnosticPrinter *DiagBuffer
|
||||
= new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
|
||||
TextDiagnosticPrinter *DiagBuffer =
|
||||
new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
|
||||
|
||||
DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagBuffer);
|
||||
|
||||
const char *binary = Argv0;
|
||||
const unique_ptr<Driver> driver(
|
||||
new Driver(binary, llvm::sys::getDefaultTargetTriple(), Diags));
|
||||
driver->CC1Main = &ExecuteCC1Tool;
|
||||
new Driver(binary, llvm::sys::getDefaultTargetTriple(), Diags));
|
||||
driver->CC1Main = &ExecuteCC1Tool;
|
||||
std::vector<const char *> Argv;
|
||||
Argv.push_back(Argv0);
|
||||
//Argv.push_back("-x");
|
||||
//Argv.push_back("ir");
|
||||
// Argv.push_back("-x");
|
||||
// Argv.push_back("ir");
|
||||
Argv.push_back(filename);
|
||||
if (LinkOMP)
|
||||
Argv.push_back("-fopenmp");
|
||||
|
@ -251,29 +248,28 @@ int emitBinary(char* Argv0, const char* filename, SmallVectorImpl<char*> &LinkAr
|
|||
int Res = 0;
|
||||
|
||||
driver->ExecuteCompilation(*compilation, FailingCommands);
|
||||
for (const auto &P : FailingCommands) {
|
||||
int CommandRes = P.first;
|
||||
const Command *FailingCommand = P.second;
|
||||
if (!Res)
|
||||
Res = CommandRes;
|
||||
for (const auto &P : FailingCommands) {
|
||||
int CommandRes = P.first;
|
||||
const Command *FailingCommand = P.second;
|
||||
if (!Res)
|
||||
Res = CommandRes;
|
||||
|
||||
// If result status is < 0, then the driver command signalled an error.
|
||||
// If result status is 70, then the driver command reported a fatal error.
|
||||
// On Windows, abort will return an exit code of 3. In these cases,
|
||||
// generate additional diagnostic information if possible.
|
||||
bool IsCrash = CommandRes < 0 || CommandRes == 70;
|
||||
// If result status is < 0, then the driver command signalled an error.
|
||||
// If result status is 70, then the driver command reported a fatal error.
|
||||
// On Windows, abort will return an exit code of 3. In these cases,
|
||||
// generate additional diagnostic information if possible.
|
||||
bool IsCrash = CommandRes < 0 || CommandRes == 70;
|
||||
#ifdef _WIN32
|
||||
IsCrash |= CommandRes == 3;
|
||||
IsCrash |= CommandRes == 3;
|
||||
#endif
|
||||
if (IsCrash) {
|
||||
driver->generateCompilationDiagnostics(*compilation, *FailingCommand);
|
||||
break;
|
||||
}
|
||||
if (IsCrash) {
|
||||
driver->generateCompilationDiagnostics(*compilation, *FailingCommand);
|
||||
break;
|
||||
}
|
||||
Diags.getClient()->finish();
|
||||
|
||||
return Res;
|
||||
}
|
||||
Diags.getClient()->finish();
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
||||
#include "Lib/clang-mlir.cc"
|
||||
|
@ -281,52 +277,54 @@ int main(int argc, char **argv) {
|
|||
|
||||
if (argc >= 1) {
|
||||
if (std::string(argv[1]) == "-cc1") {
|
||||
SmallVector<const char*> Argv;
|
||||
for(int i=0; i<argc; i++) Argv.push_back(argv[i]);
|
||||
return ExecuteCC1Tool(Argv);
|
||||
SmallVector<const char *> Argv;
|
||||
for (int i = 0; i < argc; i++)
|
||||
Argv.push_back(argv[i]);
|
||||
return ExecuteCC1Tool(Argv);
|
||||
}
|
||||
}
|
||||
SmallVector<char*> LinkageArgs;
|
||||
SmallVector<char*> MLIRArgs;
|
||||
SmallVector<char *> LinkageArgs;
|
||||
SmallVector<char *> MLIRArgs;
|
||||
{
|
||||
bool linkOnly = false;
|
||||
for (int i=0; i<argc; i++) {
|
||||
StringRef ref(argv[i]);
|
||||
if (ref == "-Wl,--start-group")
|
||||
linkOnly = true;
|
||||
if (!linkOnly) {
|
||||
if (ref == "-fPIC" || ref == "-c" || ref.startswith("-fsanitize")) {
|
||||
LinkageArgs.push_back(argv[i]);
|
||||
} else if (ref == "-L" || ref == "-l") {
|
||||
LinkageArgs.push_back(argv[i]);
|
||||
i++;
|
||||
LinkageArgs.push_back(argv[i]);
|
||||
} else if (ref.startswith("-L") || ref.startswith("-l") || ref.startswith("-Wl")) {
|
||||
LinkageArgs.push_back(argv[i]);
|
||||
} else if (ref == "-D" || ref == "-I") {
|
||||
MLIRArgs.push_back(argv[i]);
|
||||
i++;
|
||||
MLIRArgs.push_back(argv[i]);
|
||||
} else if (ref.startswith("-D")) {
|
||||
MLIRArgs.push_back("-D");
|
||||
MLIRArgs.push_back(&argv[i][2]);
|
||||
} else if (ref.startswith("-I")) {
|
||||
MLIRArgs.push_back("-I");
|
||||
MLIRArgs.push_back(&argv[i][2]);
|
||||
} else {
|
||||
MLIRArgs.push_back(argv[i]);
|
||||
}
|
||||
} else {
|
||||
bool linkOnly = false;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
StringRef ref(argv[i]);
|
||||
if (ref == "-Wl,--start-group")
|
||||
linkOnly = true;
|
||||
if (!linkOnly) {
|
||||
if (ref == "-fPIC" || ref == "-c" || ref.startswith("-fsanitize")) {
|
||||
LinkageArgs.push_back(argv[i]);
|
||||
} else if (ref == "-L" || ref == "-l") {
|
||||
LinkageArgs.push_back(argv[i]);
|
||||
i++;
|
||||
LinkageArgs.push_back(argv[i]);
|
||||
} else if (ref.startswith("-L") || ref.startswith("-l") ||
|
||||
ref.startswith("-Wl")) {
|
||||
LinkageArgs.push_back(argv[i]);
|
||||
} else if (ref == "-D" || ref == "-I") {
|
||||
MLIRArgs.push_back(argv[i]);
|
||||
i++;
|
||||
MLIRArgs.push_back(argv[i]);
|
||||
} else if (ref.startswith("-D")) {
|
||||
MLIRArgs.push_back("-D");
|
||||
MLIRArgs.push_back(&argv[i][2]);
|
||||
} else if (ref.startswith("-I")) {
|
||||
MLIRArgs.push_back("-I");
|
||||
MLIRArgs.push_back(&argv[i][2]);
|
||||
} else {
|
||||
MLIRArgs.push_back(argv[i]);
|
||||
}
|
||||
if (ref == "-Wl,--end-group")
|
||||
linkOnly = false;
|
||||
} else {
|
||||
LinkageArgs.push_back(argv[i]);
|
||||
}
|
||||
if (ref == "-Wl,--end-group")
|
||||
linkOnly = false;
|
||||
}
|
||||
}
|
||||
using namespace mlir;
|
||||
|
||||
int size = MLIRArgs.size();
|
||||
char** data = MLIRArgs.data();
|
||||
char **data = MLIRArgs.data();
|
||||
InitLLVM y(size, data);
|
||||
cl::ParseCommandLineOptions(size, data);
|
||||
assert(inputFileName.size());
|
||||
|
@ -430,22 +428,21 @@ int main(int argc, char **argv) {
|
|||
#define optPM optPM2
|
||||
#define pm pm2
|
||||
{
|
||||
mlir::PassManager pm(&context);
|
||||
mlir::OpPassManager &optPM = pm.nest<mlir::FuncOp>();
|
||||
mlir::PassManager pm(&context);
|
||||
mlir::OpPassManager &optPM = pm.nest<mlir::FuncOp>();
|
||||
|
||||
if (DetectReduction)
|
||||
optPM.addPass(polygeist::detectReductionPass());
|
||||
if (DetectReduction)
|
||||
optPM.addPass(polygeist::detectReductionPass());
|
||||
|
||||
optPM.addPass(mlir::createCanonicalizerPass());
|
||||
optPM.addPass(mlir::createCSEPass());
|
||||
optPM.addPass(mlir::createCanonicalizerPass());
|
||||
optPM.addPass(mlir::createCSEPass());
|
||||
|
||||
pm.addPass(mlir::createInlinerPass());
|
||||
if (mlir::failed(pm.run(module))) {
|
||||
module.dump();
|
||||
return 4;
|
||||
pm.addPass(mlir::createInlinerPass());
|
||||
if (mlir::failed(pm.run(module.get()))) {
|
||||
module->dump();
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (CudaLower) {
|
||||
mlir::PassManager pm(&context);
|
||||
|
@ -457,8 +454,8 @@ int main(int argc, char **argv) {
|
|||
optPM.addPass(polygeist::replaceAffineCFGPass());
|
||||
optPM.addPass(mlir::createCanonicalizerPass());
|
||||
pm.addPass(mlir::createInlinerPass());
|
||||
if (mlir::failed(pm.run(module))) {
|
||||
module.dump();
|
||||
if (mlir::failed(pm.run(module.get()))) {
|
||||
module->dump();
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
@ -484,7 +481,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
if (ToCPU == "continuation") {
|
||||
optPM.addPass(polygeist::createBarrierRemovalContinuation());
|
||||
//pm.nest<mlir::FuncOp>().addPass(mlir::createCanonicalizerPass());
|
||||
// pm.nest<mlir::FuncOp>().addPass(mlir::createCanonicalizerPass());
|
||||
} else if (ToCPU.size() != 0) {
|
||||
optPM.addPass(polygeist::createCPUifyPass(ToCPU));
|
||||
}
|
||||
|
@ -506,9 +503,7 @@ int main(int argc, char **argv) {
|
|||
module->dump();
|
||||
return 4;
|
||||
}
|
||||
module.walk([&](mlir::omp::ParallelOp) {
|
||||
LinkOMP = true;
|
||||
});
|
||||
module->walk([&](mlir::omp::ParallelOp) { LinkOMP = true; });
|
||||
mlir::PassManager pm3(&context);
|
||||
pm3.addPass(mlir::createLowerToCFGPass());
|
||||
LowerToLLVMOptions options(&context);
|
||||
|
@ -546,23 +541,25 @@ int main(int argc, char **argv) {
|
|||
llvmModule->setDataLayout(DL);
|
||||
llvmModule->setTargetTriple(triple.getTriple());
|
||||
if (!EmitAssembly) {
|
||||
auto tmpFile = llvm::sys::fs::TempFile::create("/tmp/intermediate%%%%%%%.ll");
|
||||
if (!tmpFile) {
|
||||
llvm::errs() << "Failed to create temp file\n";
|
||||
return -1;
|
||||
}
|
||||
std::error_code EC;
|
||||
{
|
||||
llvm::raw_fd_ostream out(tmpFile->FD, /*shouldClose*/false);
|
||||
auto tmpFile =
|
||||
llvm::sys::fs::TempFile::create("/tmp/intermediate%%%%%%%.ll");
|
||||
if (!tmpFile) {
|
||||
llvm::errs() << "Failed to create temp file\n";
|
||||
return -1;
|
||||
}
|
||||
std::error_code EC;
|
||||
{
|
||||
llvm::raw_fd_ostream out(tmpFile->FD, /*shouldClose*/ false);
|
||||
out << *llvmModule << "\n";
|
||||
out.flush();
|
||||
}
|
||||
int res = emitBinary(argv[0], tmpFile->TmpName.c_str(), LinkageArgs, LinkOMP);
|
||||
if (tmpFile->discard()) {
|
||||
llvm::errs() << "Failed to erase temp file\n";
|
||||
return -1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
int res =
|
||||
emitBinary(argv[0], tmpFile->TmpName.c_str(), LinkageArgs, LinkOMP);
|
||||
if (tmpFile->discard()) {
|
||||
llvm::errs() << "Failed to erase temp file\n";
|
||||
return -1;
|
||||
}
|
||||
return res;
|
||||
} else if (Output == "-") {
|
||||
llvm::outs() << *llvmModule << "\n";
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue