Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion include/polygeist/BarrierUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
#define MLIR_LIB_DIALECT_SCF_TRANSFORMS_BARRIERUTILS_H_

#include "mlir/Analysis/DataLayoutAnalysis.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.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"
Expand Down
16 changes: 10 additions & 6 deletions include/polygeist/Passes/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@
#include <memory>
namespace mlir {
namespace polygeist {
std::unique_ptr<OperationPass<FuncOp>> createMem2RegPass();
std::unique_ptr<OperationPass<FuncOp>> createLoopRestructurePass();
std::unique_ptr<OperationPass<FuncOp>> replaceAffineCFGPass();
std::unique_ptr<Pass> createMem2RegPass();
std::unique_ptr<Pass> createLoopRestructurePass();
std::unique_ptr<Pass> replaceAffineCFGPass();
std::unique_ptr<Pass> createOpenMPOptPass();
std::unique_ptr<Pass> createCanonicalizeForPass();
std::unique_ptr<Pass> createRaiseSCFToAffinePass();
std::unique_ptr<Pass> createCPUifyPass(StringRef method = "");
std::unique_ptr<Pass> createBarrierRemovalContinuation();
std::unique_ptr<OperationPass<FuncOp>> detectReductionPass();
std::unique_ptr<OperationPass<FuncOp>> createRemoveTrivialUsePass();
std::unique_ptr<Pass> detectReductionPass();
std::unique_ptr<Pass> createRemoveTrivialUsePass();
std::unique_ptr<Pass> createParallelLowerPass();
std::unique_ptr<Pass>
createConvertPolygeistToLLVMPass(const LowerToLLVMOptions &options);
Expand All @@ -40,8 +41,11 @@ namespace memref {
class MemRefDialect;
} // end namespace memref

namespace func {
class FuncDialect;
}

class AffineDialect;
class StandardOpsDialect;
namespace LLVM {
class LLVMDialect;
}
Expand Down
23 changes: 14 additions & 9 deletions include/polygeist/Passes/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

include "mlir/Pass/PassBase.td"

def AffineCFG : Pass<"affine-cfg", "FuncOp"> {
def AffineCFG : Pass<"affine-cfg"> {
let summary = "Replace scf.if and similar with affine.if";
let constructor = "mlir::polygeist::replaceAffineCFGPass()";
}
Expand All @@ -16,11 +16,11 @@ def Mem2Reg : Pass<"mem2reg", "FuncOp"> {
def ParallelLower : Pass<"parallel-lower", "mlir::ModuleOp"> {
let summary = "Replace scf.if and similar with affine.if";
let dependentDialects =
["memref::MemRefDialect", "StandardOpsDialect", "LLVM::LLVMDialect"];
["memref::MemRefDialect", "func::FuncDialect", "LLVM::LLVMDialect"];
let constructor = "mlir::polygeist::createParallelLowerPass()";
}

def AffineReduction : Pass<"detect-reduction", "FuncOp"> {
def AffineReduction : Pass<"detect-reduction"> {
let summary = "Detect reductions in affine.for";
let constructor = "mlir::polygeist::detectReductionPass()";
}
Expand All @@ -29,7 +29,7 @@ def SCFCPUify : Pass<"cpuify", "FuncOp"> {
let summary = "remove scf.barrier";
let constructor = "mlir::polygeist::createCPUifyPass()";
let dependentDialects =
["memref::MemRefDialect", "StandardOpsDialect", "LLVM::LLVMDialect"];
["memref::MemRefDialect", "func::FuncDialect", "LLVM::LLVMDialect"];
let options = [
Option<"method", "method", "std::string", /*default=*/"\"distribute\"", "Method of doing distribution">
];
Expand All @@ -38,26 +38,31 @@ def SCFCPUify : Pass<"cpuify", "FuncOp"> {
def SCFBarrierRemovalContinuation : Pass<"barrier-removal-continuation", "FuncOp"> {
let summary = "Remove scf.barrier using continuations";
let constructor = "mlir::polygeist::createBarrierRemovalContinuation()";
let dependentDialects = ["memref::MemRefDialect", "StandardOpsDialect"];
let dependentDialects = ["memref::MemRefDialect", "func::FuncDialect"];
}

def SCFRaiseToAffine : Pass<"raise-scf-to-affine", "FuncOp"> {
def SCFRaiseToAffine : Pass<"raise-scf-to-affine"> {
let summary = "Raise SCF to affine";
let constructor = "mlir::polygeist::createRaiseSCFToAffinePass()";
let dependentDialects = ["AffineDialect"];
}

def SCFCanonicalizeFor : Pass<"canonicalize-scf-for", "FuncOp"> {
def SCFCanonicalizeFor : Pass<"canonicalize-scf-for"> {
let summary = "Run some additional canonicalization for scf::for";
let constructor = "mlir::polygeist::createCanonicalizeForPass()";
}

def LoopRestructure : Pass<"loop-restructure", "FuncOp"> {
def OpenMPOptPass : Pass<"openmp-opt"> {
let summary = "Optimize OpenMP";
let constructor = "mlir::polygeist::createOpenMPOptPass()";
}

def LoopRestructure : Pass<"loop-restructure"> {
let constructor = "mlir::polygeist::createLoopRestructurePass()";
let dependentDialects = ["::mlir::scf::SCFDialect"];
}

def RemoveTrivialUse : Pass<"trivialuse", "FuncOp"> {
def RemoveTrivialUse : Pass<"trivialuse"> {
let constructor = "mlir::polygeist::createRemoveTrivialUsePass()";
}

Expand Down
102 changes: 101 additions & 1 deletion lib/polygeist/Ops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@

#include "mlir/Dialect/Affine/IR/AffineOps.h"
#include "mlir/Dialect/Arithmetic/Utils/Utils.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/MemRef/IR/MemRef.h"
#include "mlir/Dialect/SCF/SCF.h"
#include "mlir/Dialect/StandardOps/IR/Ops.h"
#include "mlir/IR/BlockAndValueMapping.h"

using namespace mlir;
Expand Down Expand Up @@ -896,6 +896,105 @@ class CopySimplification final : public OpRewritePattern<T> {
}
};

template <typename T>
class SetSimplification final : public OpRewritePattern<T> {
public:
using OpRewritePattern<T>::OpRewritePattern;

LogicalResult matchAndRewrite(T op,
PatternRewriter &rewriter) const override {

Value dstv = op.getDst();
auto dst = dstv.getDefiningOp<polygeist::Memref2PointerOp>();
if (!dst)
return failure();

auto dstTy = dst.source().getType().cast<MemRefType>();
Type elTy = dstTy.getElementType();

if (!elTy.isa<IntegerType, FloatType>())
return failure();

size_t width = 1;
if (auto IT = elTy.dyn_cast<IntegerType>())
width = IT.getWidth() / 8;
else if (auto FT = elTy.dyn_cast<FloatType>())
width = FT.getWidth() / 8;
else {
// TODO extend to llvm compatible type
return failure();
}
bool first = true;
SmallVector<size_t> bounds;
for (auto pair : dstTy.getShape()) {
if (first) {
first = false;
continue;
}
bounds.push_back(pair);
width *= pair;
}

Value len = op.getLen();
size_t factor = 1;
while (factor % width != 0) {
IntegerAttr constValue;
if (auto ext = len.getDefiningOp<arith::ExtUIOp>())
len = ext.getIn();
else if (auto ext = len.getDefiningOp<arith::ExtSIOp>())
len = ext.getIn();
else if (auto mul = len.getDefiningOp<arith::MulIOp>())
len = mul.getRhs();
else if (matchPattern(len, m_Constant(&constValue))) {
factor *= constValue.getValue().getLimitedValue();
} else
return failure();
}

if (factor % width != 0)
return failure();

Value c0 = rewriter.create<arith::ConstantIndexOp>(op.getLoc(), 0);
Value c1 = rewriter.create<arith::ConstantIndexOp>(op.getLoc(), 1);
SmallVector<Value> idxs;
Value val;

if (auto IT = elTy.dyn_cast<IntegerType>())
val =
rewriter.create<arith::ConstantIntOp>(op.getLoc(), 0, IT.getWidth());
else {
auto FT = elTy.cast<FloatType>();
val = rewriter.create<arith::ConstantFloatOp>(
op.getLoc(), APFloat(FT.getFloatSemantics(), "0"), FT);
}

auto forOp = rewriter.create<scf::ForOp>(
op.getLoc(), c0,
rewriter.create<arith::DivUIOp>(
op.getLoc(),
rewriter.create<arith::IndexCastOp>(
op.getLoc(), rewriter.getIndexType(), op.getLen()),
rewriter.create<arith::ConstantIndexOp>(op.getLoc(), width)),
c1);

rewriter.setInsertionPointToStart(&forOp.getLoopBody().front());
idxs.push_back(forOp.getInductionVar());

for (auto bound : bounds) {
auto forOp = rewriter.create<scf::ForOp>(
op.getLoc(), c0, rewriter.create<ConstantIndexOp>(op.getLoc(), bound),
c1);
rewriter.setInsertionPointToStart(&forOp.getLoopBody().front());
idxs.push_back(forOp.getInductionVar());
}

rewriter.create<memref::StoreOp>(op.getLoc(), val, dst.source(), idxs);

rewriter.eraseOp(op);
return success();
}
};

OpFoldResult Memref2PointerOp::fold(ArrayRef<Attribute> operands) {
if (auto subindex = source().getDefiningOp<SubIndexOp>()) {
if (auto cop = subindex.index().getDefiningOp<ConstantIndexOp>()) {
Expand All @@ -921,6 +1020,7 @@ OpFoldResult Memref2PointerOp::fold(ArrayRef<Attribute> operands) {
void Memref2PointerOp::getCanonicalizationPatterns(RewritePatternSet &results,
MLIRContext *context) {
results.insert<Memref2Pointer2MemrefCast, Memref2PointerIndex,
SetSimplification<LLVM::MemsetOp>,
CopySimplification<LLVM::MemcpyOp>,
CopySimplification<LLVM::MemmoveOp>>(context);
}
Expand Down
6 changes: 3 additions & 3 deletions lib/polygeist/Passes/AffineCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1135,16 +1135,16 @@ struct MoveIfToAffine : public OpRewritePattern<scf::IfOp> {
};

void AffineCFGPass::runOnOperation() {
mlir::RewritePatternSet rpl(getOperation().getContext());
mlir::RewritePatternSet rpl(getOperation()->getContext());
rpl.add<SimplfyIntegerCastMath, CanonicalizeAffineApply,
CanonicalizeIndexCast, IndexCastMovement, AffineFixup<AffineLoadOp>,
AffineFixup<AffineStoreOp>, CanonicalizIfBounds, MoveStoreToAffine,
MoveIfToAffine, MoveLoadToAffine, CanonicalieForBounds>(
getOperation().getContext());
getOperation()->getContext());
GreedyRewriteConfig config;
(void)applyPatternsAndFoldGreedily(getOperation(), std::move(rpl), config);
}

std::unique_ptr<OperationPass<FuncOp>> mlir::polygeist::replaceAffineCFGPass() {
std::unique_ptr<Pass> mlir::polygeist::replaceAffineCFGPass() {
return std::make_unique<AffineCFGPass>();
}
6 changes: 3 additions & 3 deletions lib/polygeist/Passes/AffineReduction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,15 +255,15 @@ struct AffineForReductionIter : public OpRewritePattern<AffineForOp> {
} // end namespace.

void AffineReductionPass::runOnOperation() {
mlir::RewritePatternSet rpl(getOperation().getContext());
rpl.add<AffineForReductionIter>(getOperation().getContext());
mlir::RewritePatternSet rpl(getOperation()->getContext());
rpl.add<AffineForReductionIter>(getOperation()->getContext());
GreedyRewriteConfig config;
(void)applyPatternsAndFoldGreedily(getOperation(), std::move(rpl), config);
}

namespace mlir {
namespace polygeist {
std::unique_ptr<OperationPass<FuncOp>> detectReductionPass() {
std::unique_ptr<Pass> detectReductionPass() {
return std::make_unique<AffineReductionPass>();
}
} // namespace polygeist
Expand Down
4 changes: 2 additions & 2 deletions lib/polygeist/Passes/BarrierRemovalContinuation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
#include "mlir/Conversion/SCFToControlFlow/SCFToControlFlow.h"
#include "mlir/Dialect/Arithmetic/IR/Arithmetic.h"
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/MemRef/IR/MemRef.h"
#include "mlir/Dialect/SCF/Passes.h"
#include "mlir/Dialect/SCF/SCF.h"
#include "mlir/Dialect/StandardOps/IR/Ops.h"
#include "mlir/IR/BlockAndValueMapping.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/Dominance.h"
Expand Down Expand Up @@ -78,7 +78,7 @@ static LogicalResult applyCFGConversion(FuncOp function) {
// Configure the target to preserve parallel ops with barriers, unless those
// barriers are nested in deeper parallel ops.
ConversionTarget target(*function.getContext());
target.addLegalDialect<StandardOpsDialect>();
target.addLegalDialect<func::FuncDialect>();
target.addLegalDialect<memref::MemRefDialect>();
target.addIllegalOp<scf::ForOp, scf::IfOp, scf::WhileOp>();
target.addLegalOp<scf::ExecuteRegionOp, FuncOp, ModuleOp>();
Expand Down
7 changes: 5 additions & 2 deletions lib/polygeist/Passes/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ add_mlir_dialect_library(MLIRPolygeistTransforms
LoopRestructure.cpp
Mem2Reg.cpp
ParallelLoopDistribute.cpp
OpenMPOpt.cpp
BarrierRemovalContinuation.cpp
RaiseToAffine.cpp
ParallelLower.cpp
Expand All @@ -21,16 +22,18 @@ add_mlir_dialect_library(MLIRPolygeistTransforms
LINK_LIBS PUBLIC
MLIRAffine
MLIRAffineUtils
MLIRFunc
MLIRFuncTransforms
MLIRGPUOps
MLIRIR
MLIRLLVMIR
MLIRMath
MLIRMathToLLVM
MLIRMemRef
MLIRNVVMIR
MLIRPass
MLIRPolygeist
MLIRSideEffectInterfaces
MLIRStandard
MLIRStandardOpsTransforms
MLIRSCFToControlFlow
MLIRTransformUtils
)
7 changes: 4 additions & 3 deletions lib/polygeist/Passes/CanonicalizeFor.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "PassDetails.h"

#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/SCF/Passes.h"
#include "mlir/Dialect/SCF/SCF.h"
#include "mlir/Dialect/StandardOps/IR/Ops.h"
#include "mlir/IR/BlockAndValueMapping.h"
#include "mlir/IR/Dominance.h"
#include "mlir/IR/Matchers.h"
Expand All @@ -12,6 +12,7 @@

using namespace mlir;
using namespace mlir::scf;
using namespace mlir::func;
using namespace mlir::arith;
using namespace polygeist;

Expand Down Expand Up @@ -1408,7 +1409,7 @@ struct ReturnSq : public OpRewritePattern<ReturnOp> {
}
};
void CanonicalizeFor::runOnOperation() {
mlir::RewritePatternSet rpl(getOperation().getContext());
mlir::RewritePatternSet rpl(getOperation()->getContext());
rpl.add<PropagateInLoopBody, ForOpInductionReplacement, RemoveUnusedArgs,
MoveWhileToFor,

Expand All @@ -1417,7 +1418,7 @@ void CanonicalizeFor::runOnOperation() {
,
MoveWhileDown3, MoveWhileInvariantIfResult, WhileLogicalNegation,
SubToAdd, WhileCmpOffset, WhileLICM, RemoveUnusedCondVar, ReturnSq,
MoveSideEffectFreeWhile>(getOperation().getContext());
MoveSideEffectFreeWhile>(getOperation()->getContext());
GreedyRewriteConfig config;
config.maxIterations = 47;
(void)applyPatternsAndFoldGreedily(getOperation(), std::move(rpl), config);
Expand Down
Loading