diff --git a/lib/Analysis/CMakeLists.txt b/lib/Analysis/CMakeLists.txt deleted file mode 100644 index a52d48b..0000000 --- a/lib/Analysis/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_subdirectory(ReduceNoiseAnalysis) diff --git a/lib/Analysis/ReduceNoiseAnalysis/BUILD b/lib/Analysis/ReduceNoiseAnalysis/BUILD deleted file mode 100644 index 90981d0..0000000 --- a/lib/Analysis/ReduceNoiseAnalysis/BUILD +++ /dev/null @@ -1,16 +0,0 @@ -package( - default_visibility = ["//visibility:public"], -) - -cc_library( - name = "ReduceNoiseAnalysis", - srcs = ["ReduceNoiseAnalysis.cpp"], - hdrs = ["ReduceNoiseAnalysis.h"], - deps = [ - "//lib/Dialect/Noisy", - "@com_google_ortools//ortools/base", - "@com_google_ortools//ortools/linear_solver", - "@llvm-project//llvm:Support", - "@llvm-project//mlir:IR", - ], -) diff --git a/lib/Analysis/ReduceNoiseAnalysis/CMakeLists.txt b/lib/Analysis/ReduceNoiseAnalysis/CMakeLists.txt deleted file mode 100644 index 1889df5..0000000 --- a/lib/Analysis/ReduceNoiseAnalysis/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -add_mlir_library(ReduceNoiseAnalysis - ReduceNoiseAnalysis.cpp - - ${PROJECT_SOURCE_DIR}/lib/Analysis/ReduceNoiseAnalysis/ - ADDITIONAL_HEADER_DIRS - LINK_LIBS PUBLIC - ortools::ortools -) diff --git a/lib/Analysis/ReduceNoiseAnalysis/ReduceNoiseAnalysis.cpp b/lib/Analysis/ReduceNoiseAnalysis/ReduceNoiseAnalysis.cpp deleted file mode 100644 index e65b3de..0000000 --- a/lib/Analysis/ReduceNoiseAnalysis/ReduceNoiseAnalysis.cpp +++ /dev/null @@ -1,266 +0,0 @@ -#include "lib/Analysis/ReduceNoiseAnalysis/ReduceNoiseAnalysis.h" - -#include - -#include "lib/Dialect/Noisy/NoisyOps.h" -#include "mlir/include/mlir/IR/Operation.h" -#include "mlir/include/mlir/IR/Value.h" -#include "ortools/linear_solver/linear_solver.h" -#include "llvm/Support/Debug.h" -#include "llvm/include/llvm/ADT/DenseMap.h" -#include "llvm/include/llvm/ADT/TypeSwitch.h" - -using namespace operations_research; - -namespace mlir { -namespace tutorial { - -#define DEBUG_TYPE "ReduceNoiseAnalysis" - -// This needs only be larger than 32, since we're hard coding i32s in this -// tutorial. -constexpr int IF_THEN_AUX = 100; - -std::string nameAndLoc(Operation *op) { - std::string varName; - llvm::raw_string_ostream ss(varName); - ss << op->getName() << "_" << op->getLoc(); - return ss.str(); -} - -ReduceNoiseAnalysis::ReduceNoiseAnalysis(Operation *op) { - std::unique_ptr solver(MPSolver::CreateSolver("SCIP")); - MPObjective *const objective = solver->MutableObjective(); - objective->SetMinimization(); - - llvm::DenseMap decisionVariables; - llvm::DenseMap ssaNoiseVariables; - std::vector allVariables; - - // First walk the IR to define variables for all values and ops, - // and constraint initial conditions. - op->walk([&](Operation *op) { - // FIXME: assumes all reduce_noise ops have already been removed and their - // values forwarded. - if (!isa(op)) { - return; - } - - std::string varName = "InsertReduceNoise_" + nameAndLoc(op); - auto decisionVar = solver->MakeIntVar(0, 1, varName); - decisionVariables.insert(std::make_pair(op, decisionVar)); - allVariables.push_back(decisionVar); - objective->SetCoefficient(decisionVar, 1); - - int index = 0; - for (auto operand : op->getOperands()) { - if (ssaNoiseVariables.contains(operand)) { - continue; - } - std::string varName = - "NoiseAt_" + nameAndLoc(op) + "_arg_" + std::to_string(index++); - auto ssaNoiseVar = solver->MakeNumVar(0, MAX_NOISE, varName); - allVariables.push_back(ssaNoiseVar); - ssaNoiseVariables.insert(std::make_pair(operand, ssaNoiseVar)); - } - - if (!ssaNoiseVariables.contains(op->getResult(0))) { - std::string varName = "NoiseAt_" + nameAndLoc(op) + "_result"; - auto ssaNoiseVar = solver->MakeNumVar(0, MAX_NOISE, varName); - allVariables.push_back(ssaNoiseVar); - ssaNoiseVariables.insert(std::make_pair(op->getResult(0), ssaNoiseVar)); - } - }); - - // Define constraints on the noise at each SSA value - for (auto item : ssaNoiseVariables) { - auto value = item.first; - auto var = item.second; - // An input node has noise equal to the initial noise, though we're being a - // bit sloppy by saying that EVERY block argument counts as an input node. - // In the tutorial, there is no control flow, so these are the function - // arguments of the main function being analyzed. A real compiler would - // need to handle this more generically. - if (isa(value) || - isa(value.getDefiningOp())) { - MPConstraint *const ct = - solver->MakeRowConstraint(INITIAL_NOISE, INITIAL_NOISE, ""); - ct->SetCoefficient(var, 1); - } - } - - std::string cstName; - // Define the decision variable constraints - op->walk([&](Operation *op) { - llvm::TypeSwitch(*op) - .Case([&](auto op) { - // result_noise = input_noise (1 - reduce_decision) + 12 * - // reduce_decision but linearized due to the quadratic term - // input_noise * reduce_decision - - auto inf = solver->infinity(); - auto lhsNoiseVar = ssaNoiseVariables.lookup(op.getLhs()); - auto rhsNoiseVar = ssaNoiseVariables.lookup(op.getRhs()); - auto resultNoiseVar = ssaNoiseVariables.lookup(op.getResult()); - auto reduceNoiseDecision = decisionVariables.lookup(op); - - // result_noise >= 12 * reduce_decision - cstName = "DecisionDynamics_" + nameAndLoc(op) + "_1"; - MPConstraint *const ct1 = - solver->MakeRowConstraint(0.0, inf, cstName); - ct1->SetCoefficient(resultNoiseVar, 1); - ct1->SetCoefficient(reduceNoiseDecision, -INITIAL_NOISE); - - // result_noise <= 12 + (1 - reduce_decision) * BIG_CONST - cstName = "DecisionDynamics_" + nameAndLoc(op) + "_2"; - MPConstraint *const ct2 = solver->MakeRowConstraint( - 0.0, INITIAL_NOISE * IF_THEN_AUX, cstName); - ct2->SetCoefficient(resultNoiseVar, 1); - ct2->SetCoefficient(reduceNoiseDecision, IF_THEN_AUX); - - // result_noise >= input_noise - reduce_decision * BIG_CONST - cstName = "DecisionDynamics_" + nameAndLoc(op) + "_3"; - MPConstraint *const ct3 = - solver->MakeRowConstraint(0.0, inf, cstName); - ct3->SetCoefficient(resultNoiseVar, 1); - ct3->SetCoefficient(reduceNoiseDecision, IF_THEN_AUX); - // The input noise is the sum of the two argument noises - if (op.getLhs() == op.getRhs()) { - ct3->SetCoefficient(lhsNoiseVar, -2); - } else { - ct3->SetCoefficient(lhsNoiseVar, -1); - ct3->SetCoefficient(rhsNoiseVar, -1); - } - - // result_noise <= input_noise + reduce_decision * BIG_CONST - cstName = "DecisionDynamics_" + nameAndLoc(op) + "_4"; - MPConstraint *const ct4 = - solver->MakeRowConstraint(-inf, 0.0, cstName); - ct4->SetCoefficient(resultNoiseVar, 1); - ct4->SetCoefficient(reduceNoiseDecision, -IF_THEN_AUX); - if (op.getLhs() == op.getRhs()) { - ct4->SetCoefficient(lhsNoiseVar, -2); - } else { - ct4->SetCoefficient(lhsNoiseVar, -1); - ct4->SetCoefficient(rhsNoiseVar, -1); - } - - // ensure the noise before the reduce_noise op (input_noise) - // also is not too large - cstName = "DecisionDynamics_" + nameAndLoc(op) + "_5"; - MPConstraint *const ct5 = - solver->MakeRowConstraint(0.0, MAX_NOISE, cstName); - if (op.getLhs() == op.getRhs()) { - ct5->SetCoefficient(lhsNoiseVar, 2); - } else { - ct5->SetCoefficient(lhsNoiseVar, 1); - ct5->SetCoefficient(rhsNoiseVar, 1); - } - }) - .Case([&](auto op) { - // Same as for MulOp, but the noise combination function is more - // complicated because it involves a maximum. - auto inf = solver->infinity(); - auto lhsNoiseVar = ssaNoiseVariables.lookup(op.getLhs()); - auto rhsNoiseVar = ssaNoiseVariables.lookup(op.getRhs()); - auto resultNoiseVar = ssaNoiseVariables.lookup(op.getResult()); - auto reduceNoiseDecision = decisionVariables.lookup(op); - - // result_noise >= 12 * reduce_decision - cstName = "DecisionDynamics_" + nameAndLoc(op) + "_1"; - MPConstraint *const ct1 = - solver->MakeRowConstraint(0.0, inf, cstName); - ct1->SetCoefficient(resultNoiseVar, 1); - ct1->SetCoefficient(reduceNoiseDecision, -INITIAL_NOISE); - - // result_noise <= 12 + (1 - reduce_decision) * BIG_CONST - cstName = "DecisionDynamics_" + nameAndLoc(op) + "_2"; - MPConstraint *const ct2 = solver->MakeRowConstraint( - 0.0, INITIAL_NOISE * IF_THEN_AUX, cstName); - ct2->SetCoefficient(resultNoiseVar, 1); - ct2->SetCoefficient(reduceNoiseDecision, IF_THEN_AUX); - - // for AddOp, the input noise is the max of the two argument noises - // plus one. Model this with an extra variable Z and two constraints: - // - // lhs_noise + 1 <= Z <= MAX_NOISE - // rhs_noise + 1 <= Z <= MAX_NOISE - // input_noise := Z - // - // Then add theze Z variables to the minimization objective, and - // they will be clamped to the larger of the two lower bounds. - cstName = "Z_" + nameAndLoc(op); - auto zVar = solver->MakeNumVar(0, MAX_NOISE, cstName); - allVariables.push_back(zVar); - // The objective coefficient is not all that important: the solver - // cannot cheat by making Z larger than necessary, since making Z - // larger than it needs to be would further increase the need to - // insert reduce_noise ops, which would be more expensive. - objective->SetCoefficient(zVar, 0.1); - - cstName = "DecisionDynamics_" + nameAndLoc(op) + "_z1"; - MPConstraint *const zCt1 = - solver->MakeRowConstraint(1.0, inf, cstName); - zCt1->SetCoefficient(zVar, 1); - zCt1->SetCoefficient(lhsNoiseVar, -1); - - if (op.getLhs() != op.getRhs()) { - cstName = "DecisionDynamics_" + nameAndLoc(op) + "_z2"; - MPConstraint *const zCt2 = - solver->MakeRowConstraint(1.0, inf, cstName); - zCt2->SetCoefficient(zVar, 1); - zCt2->SetCoefficient(rhsNoiseVar, -1); - } - - // result_noise >= input_noise - reduce_decision * BIG_CONST - cstName = "DecisionDynamics_" + nameAndLoc(op) + "_3"; - MPConstraint *const ct3 = - solver->MakeRowConstraint(0.0, inf, cstName); - ct3->SetCoefficient(resultNoiseVar, 1); - ct3->SetCoefficient(reduceNoiseDecision, IF_THEN_AUX); - ct3->SetCoefficient(zVar, -1); - - // result_noise <= input_noise + reduce_decision * BIG_CONST - cstName = "DecisionDynamics_" + nameAndLoc(op) + "_4"; - MPConstraint *const ct4 = - solver->MakeRowConstraint(-inf, 0.0, cstName); - ct4->SetCoefficient(resultNoiseVar, 1); - ct4->SetCoefficient(reduceNoiseDecision, -IF_THEN_AUX); - ct4->SetCoefficient(zVar, -1); - - // ensure the noise before the reduce_noise op (input_noise) - // also is not too large - cstName = "DecisionDynamics_" + nameAndLoc(op) + "_5"; - MPConstraint *const ct5 = - solver->MakeRowConstraint(0.0, MAX_NOISE, cstName); - ct5->SetCoefficient(zVar, 1); - }); - }); - - // Uncomment if you want to read the model's textual description, - // generally not for those unfamiliar with linear programming. - // std::string modelAsString; - // solver->ExportModelAsLpFormat(false, &modelAsString); - // LLVM_DEBUG(llvm::dbgs() << "Model string = " << modelAsString << "\n"); - - solver->Solve(); - LLVM_DEBUG(llvm::dbgs() << "Problem solved in " << solver->wall_time() - << " milliseconds" - << "\n"); - - LLVM_DEBUG(llvm::dbgs() << "Solution:\n"); - LLVM_DEBUG(llvm::dbgs() << "Objective value = " << objective->Value() - << "\n"); - // LLVM_DEBUG(llvm::dbgs() << "Variables:\n"); - // for (auto var : allVariables) { - // LLVM_DEBUG(llvm::dbgs() << " " << var->name() << " = " - // << var->solution_value() << "\n"); - // } - - for (auto item : decisionVariables) { - solution.insert(std::make_pair(item.first, item.second->solution_value())); - } -} - -} // namespace tutorial -} // namespace mlir diff --git a/lib/Analysis/ReduceNoiseAnalysis/ReduceNoiseAnalysis.h b/lib/Analysis/ReduceNoiseAnalysis/ReduceNoiseAnalysis.h deleted file mode 100644 index efffca1..0000000 --- a/lib/Analysis/ReduceNoiseAnalysis/ReduceNoiseAnalysis.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef LIB_ANALYSIS_REDUCENOISEANALYSIS_REDUCENOISEANALYSIS_H_ -#define LIB_ANALYSIS_REDUCENOISEANALYSIS_REDUCENOISEANALYSIS_H_ - -#include "llvm/include/llvm/ADT/DenseMap.h" // from @llvm-project -#include "mlir/include/mlir/IR/Operation.h" // from @llvm-project -#include "mlir/include/mlir/IR/Value.h" // from @llvm-project - -namespace mlir { -namespace tutorial { - -class ReduceNoiseAnalysis { - public: - ReduceNoiseAnalysis(Operation *op); - ~ReduceNoiseAnalysis() = default; - - /// Return true if a reduce_noise op should be inserted after the given - /// operation, according to the solution to the optimization problem. - bool shouldInsertReduceNoise(Operation *op) const { - return solution.lookup(op); - } - - private: - llvm::DenseMap solution; -}; - -} // namespace tutorial -} // namespace mlir - -#endif // LIB_ANALYSIS_REDUCENOISEANALYSIS_REDUCENOISEANALYSIS_H_ diff --git a/lib/Conversion/CMakeLists.txt b/lib/Conversion/CMakeLists.txt deleted file mode 100644 index fb91c06..0000000 --- a/lib/Conversion/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_subdirectory(PolyToStandard) diff --git a/lib/Conversion/PolyToStandard/BUILD b/lib/Conversion/PolyToStandard/BUILD deleted file mode 100644 index c51d951..0000000 --- a/lib/Conversion/PolyToStandard/BUILD +++ /dev/null @@ -1,42 +0,0 @@ -load("@llvm-project//mlir:tblgen.bzl", "gentbl_cc_library") - -package( - default_visibility = ["//visibility:public"], -) - -gentbl_cc_library( - name = "pass_inc_gen", - tbl_outs = [ - ( - [ - "-gen-pass-decls", - "-name=PolyToStandard", - ], - "PolyToStandard.h.inc", - ), - ], - tblgen = "@llvm-project//mlir:mlir-tblgen", - td_file = "PolyToStandard.td", - deps = [ - "@llvm-project//mlir:OpBaseTdFiles", - "@llvm-project//mlir:PassBaseTdFiles", - ], -) - -cc_library( - name = "PolyToStandard", - srcs = ["PolyToStandard.cpp"], - hdrs = ["PolyToStandard.h"], - deps = [ - "pass_inc_gen", - "//lib/Dialect/Poly", - "@llvm-project//mlir:ArithDialect", - "@llvm-project//mlir:FuncDialect", - "@llvm-project//mlir:FuncTransforms", - "@llvm-project//mlir:IR", - "@llvm-project//mlir:Pass", - "@llvm-project//mlir:SCFDialect", - "@llvm-project//mlir:TensorDialect", - "@llvm-project//mlir:Transforms", - ], -) diff --git a/lib/Conversion/PolyToStandard/CMakeLists.txt b/lib/Conversion/PolyToStandard/CMakeLists.txt deleted file mode 100644 index 96dde92..0000000 --- a/lib/Conversion/PolyToStandard/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -add_mlir_library(PolyToStandard - PolyToStandard.cpp - - ${PROJECT_SOURCE_DIR}/lib/Conversion/PolyToStandard/ - ADDITIONAL_HEADER_DIRS - - DEPENDS - PolyToStandardPassIncGen - - LINK_COMPONENTS - Core - - LINK_LIBS PUBLIC - MLIRPoly - MLIRArithDialect - MLIRFuncDialect - MLIRFuncTransforms - MLIRIR - MLIRPass - MLIRSCFDialect - MLIRTensorDialect - MLIRTransforms - ) - -set(LLVM_TARGET_DEFINITIONS PolyToStandard.td) -mlir_tablegen(PolyToStandard.h.inc -gen-pass-decls -name PolyToStandard) -add_dependencies(mlir-headers MLIRPolyOpsIncGen) -add_public_tablegen_target(PolyToStandardPassIncGen) -add_mlir_doc(PolyToStandard PolyToStandard PolyToStandard/ -gen-pass-doc) diff --git a/lib/Conversion/PolyToStandard/PolyToStandard.cpp b/lib/Conversion/PolyToStandard/PolyToStandard.cpp deleted file mode 100644 index e7a76dd..0000000 --- a/lib/Conversion/PolyToStandard/PolyToStandard.cpp +++ /dev/null @@ -1,301 +0,0 @@ -#include "lib/Conversion/PolyToStandard/PolyToStandard.h" - -#include "lib/Dialect/Poly/PolyOps.h" -#include "lib/Dialect/Poly/PolyTypes.h" -#include "llvm/include/llvm/ADT/SmallVector.h" // from @llvm-project -#include "mlir/Dialect/SCF/IR/SCF.h" // from @llvm-project -#include "mlir/include/mlir/Dialect/Func/IR/FuncOps.h" // from @llvm-project -#include "mlir/include/mlir/Dialect/Func/Transforms/FuncConversions.h" // from @llvm-project -#include "mlir/include/mlir/IR/ImplicitLocOpBuilder.h" // from @llvm-project -#include "mlir/include/mlir/Transforms/DialectConversion.h" // from @llvm-project - -namespace mlir { -namespace tutorial { -namespace poly { - -#define GEN_PASS_DEF_POLYTOSTANDARD -#include "lib/Conversion/PolyToStandard/PolyToStandard.h.inc" - -class PolyToStandardTypeConverter : public TypeConverter { - public: - PolyToStandardTypeConverter(MLIRContext *ctx) { - addConversion([](Type type) { return type; }); - addConversion([ctx](PolynomialType type) -> Type { - int degreeBound = type.getDegreeBound(); - IntegerType elementTy = - IntegerType::get(ctx, 32, IntegerType::SignednessSemantics::Signless); - return RankedTensorType::get({degreeBound}, elementTy); - }); - - // We don't include any custom materialization hooks because this lowering - // is all done in a single pass. The dialect conversion framework works by - // resolving intermediate (mid-pass) type conflicts by inserting - // unrealized_conversion_cast ops, and only converting those to custom - // materializations if they persist at the end of the pass. In our case, - // we'd only need to use custom materializations if we split this lowering - // across multiple passes. - } -}; - -struct ConvertAdd : public OpConversionPattern { - ConvertAdd(mlir::MLIRContext *context) - : OpConversionPattern(context) {} - - using OpConversionPattern::OpConversionPattern; - - LogicalResult matchAndRewrite( - AddOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override { - arith::AddIOp addOp = rewriter.create( - op.getLoc(), adaptor.getLhs(), adaptor.getRhs()); - rewriter.replaceOp(op.getOperation(), addOp); - return success(); - } -}; - -struct ConvertSub : public OpConversionPattern { - ConvertSub(mlir::MLIRContext *context) - : OpConversionPattern(context) {} - - using OpConversionPattern::OpConversionPattern; - - LogicalResult matchAndRewrite( - SubOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override { - arith::SubIOp subOp = rewriter.create( - op.getLoc(), adaptor.getLhs(), adaptor.getRhs()); - rewriter.replaceOp(op.getOperation(), subOp); - return success(); - } -}; - -struct ConvertMul : public OpConversionPattern { - ConvertMul(mlir::MLIRContext *context) - : OpConversionPattern(context) {} - - using OpConversionPattern::OpConversionPattern; - - LogicalResult matchAndRewrite( - MulOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override { - auto polymulTensorType = cast(adaptor.getLhs().getType()); - auto numTerms = polymulTensorType.getShape()[0]; - ImplicitLocOpBuilder b(op.getLoc(), rewriter); - - // Create an all-zeros tensor to store the result - auto polymulResult = b.create( - polymulTensorType, DenseElementsAttr::get(polymulTensorType, 0)); - - // Loop bounds and step. - auto lowerBound = - b.create(b.getIndexType(), b.getIndexAttr(0)); - auto numTermsOp = - b.create(b.getIndexType(), b.getIndexAttr(numTerms)); - auto step = - b.create(b.getIndexType(), b.getIndexAttr(1)); - - auto p0 = adaptor.getLhs(); - auto p1 = adaptor.getRhs(); - - // for i = 0, ..., N-1 - // for j = 0, ..., N-1 - // product[i+j (mod N)] += p0[i] * p1[j] - auto outerLoop = b.create( - lowerBound, numTermsOp, step, ValueRange(polymulResult.getResult()), - [&](OpBuilder &builder, Location loc, Value p0Index, - ValueRange loopState) { - ImplicitLocOpBuilder b(op.getLoc(), builder); - auto innerLoop = b.create( - lowerBound, numTermsOp, step, loopState, - [&](OpBuilder &builder, Location loc, Value p1Index, - ValueRange loopState) { - ImplicitLocOpBuilder b(op.getLoc(), builder); - auto accumTensor = loopState.front(); - auto destIndex = b.create( - b.create(p0Index, p1Index), numTermsOp); - auto mulOp = b.create( - b.create(p0, ValueRange(p0Index)), - b.create(p1, ValueRange(p1Index))); - auto result = b.create( - mulOp, b.create(accumTensor, - destIndex.getResult())); - auto stored = b.create(result, accumTensor, - destIndex.getResult()); - b.create(stored.getResult()); - }); - - b.create(innerLoop.getResults()); - }); - - rewriter.replaceOp(op, outerLoop.getResult(0)); - return success(); - } -}; - -struct ConvertEval : public OpConversionPattern { - ConvertEval(mlir::MLIRContext *context) - : OpConversionPattern(context) {} - - using OpConversionPattern::OpConversionPattern; - - LogicalResult matchAndRewrite( - EvalOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override { - auto polyTensorType = - cast(adaptor.getPolynomial().getType()); - auto numTerms = polyTensorType.getShape()[0]; - ImplicitLocOpBuilder b(op.getLoc(), rewriter); - - auto lowerBound = - b.create(b.getIndexType(), b.getIndexAttr(1)); - auto numTermsOp = b.create(b.getIndexType(), - b.getIndexAttr(numTerms)); - auto upperBound = b.create(b.getIndexType(), - b.getIndexAttr(numTerms + 1)); - auto step = lowerBound; - - auto poly = adaptor.getPolynomial(); - auto point = adaptor.getPoint(); - - // Horner's method: - // - // accum = 0 - // for i = 1, 2, ..., N - // accum = point * accum + coeff[N - i] - auto accum = - b.create(b.getI32Type(), b.getI32IntegerAttr(0)); - auto loop = b.create( - lowerBound, upperBound, step, accum.getResult(), - [&](OpBuilder &builder, Location loc, Value loopIndex, - ValueRange loopState) { - ImplicitLocOpBuilder b(op.getLoc(), builder); - auto accum = loopState.front(); - auto coeffIndex = b.create(numTermsOp, loopIndex); - auto mulOp = b.create(point, accum); - auto result = b.create( - mulOp, b.create(poly, coeffIndex.getResult())); - b.create(result.getResult()); - }); - - rewriter.replaceOp(op, loop.getResult(0)); - return success(); - } -}; - -struct ConvertFromTensor : public OpConversionPattern { - ConvertFromTensor(mlir::MLIRContext *context) - : OpConversionPattern(context) {} - - using OpConversionPattern::OpConversionPattern; - - LogicalResult matchAndRewrite( - FromTensorOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override { - auto resultTensorTy = cast( - typeConverter->convertType(op->getResultTypes()[0])); - auto resultShape = resultTensorTy.getShape()[0]; - auto resultEltTy = resultTensorTy.getElementType(); - - auto inputTensorTy = op.getInput().getType(); - auto inputShape = inputTensorTy.getShape()[0]; - - // Zero pad the tensor if the coefficients' size is less than the polynomial - // degree. - ImplicitLocOpBuilder b(op.getLoc(), rewriter); - auto coeffValue = adaptor.getInput(); - if (inputShape < resultShape) { - SmallVector low, high; - low.push_back(rewriter.getIndexAttr(0)); - high.push_back(rewriter.getIndexAttr(resultShape - inputShape)); - coeffValue = b.create( - resultTensorTy, coeffValue, low, high, - b.create(rewriter.getIntegerAttr(resultEltTy, 0)), - /*nofold=*/false); - } - - rewriter.replaceOp(op, coeffValue); - return success(); - } -}; - -struct ConvertToTensor : public OpConversionPattern { - ConvertToTensor(mlir::MLIRContext *context) - : OpConversionPattern(context) {} - - using OpConversionPattern::OpConversionPattern; - - LogicalResult matchAndRewrite( - ToTensorOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override { - rewriter.replaceOp(op, adaptor.getInput()); - return success(); - } -}; - -struct ConvertConstant : public OpConversionPattern { - ConvertConstant(mlir::MLIRContext *context) - : OpConversionPattern(context) {} - - using OpConversionPattern::OpConversionPattern; - - LogicalResult matchAndRewrite( - ConstantOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override { - ImplicitLocOpBuilder b(op.getLoc(), rewriter); - auto constOp = b.create(adaptor.getCoefficients()); - auto fromTensorOp = - b.create(op.getResult().getType(), constOp); - rewriter.replaceOp(op, fromTensorOp.getResult()); - return success(); - } -}; - -struct PolyToStandard : impl::PolyToStandardBase { - using PolyToStandardBase::PolyToStandardBase; - - void runOnOperation() override { - MLIRContext *context = &getContext(); - auto *module = getOperation(); - - ConversionTarget target(*context); - target.addLegalDialect(); - target.addIllegalDialect(); - - RewritePatternSet patterns(context); - PolyToStandardTypeConverter typeConverter(context); - patterns.add(typeConverter, - context); - - populateFunctionOpInterfaceTypeConversionPattern( - patterns, typeConverter); - target.addDynamicallyLegalOp([&](func::FuncOp op) { - return typeConverter.isSignatureLegal(op.getFunctionType()) && - typeConverter.isLegal(&op.getBody()); - }); - - populateReturnOpTypeConversionPattern(patterns, typeConverter); - target.addDynamicallyLegalOp( - [&](func::ReturnOp op) { return typeConverter.isLegal(op); }); - - populateCallOpTypeConversionPattern(patterns, typeConverter); - target.addDynamicallyLegalOp( - [&](func::CallOp op) { return typeConverter.isLegal(op); }); - - populateBranchOpInterfaceTypeConversionPattern(patterns, typeConverter); - target.markUnknownOpDynamicallyLegal([&](Operation *op) { - return isNotBranchOpInterfaceOrReturnLikeOp(op) || - isLegalForBranchOpInterfaceTypeConversionPattern(op, - typeConverter) || - isLegalForReturnOpTypeConversionPattern(op, typeConverter); - }); - - if (failed(applyPartialConversion(module, target, std::move(patterns)))) { - signalPassFailure(); - } - } -}; - -} // namespace poly -} // namespace tutorial -} // namespace mlir diff --git a/lib/Conversion/PolyToStandard/PolyToStandard.h b/lib/Conversion/PolyToStandard/PolyToStandard.h deleted file mode 100644 index ca7dfc9..0000000 --- a/lib/Conversion/PolyToStandard/PolyToStandard.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef LIB_CONVERSION_POLYTOSTANDARD_POLYTOSTANDARD_H_ -#define LIB_CONVERSION_POLYTOSTANDARD_POLYTOSTANDARD_H_ - -#include "mlir/include/mlir/Pass/Pass.h" // from @llvm-project - -// Extra includes needed for dependent dialects -#include "mlir/include/mlir/Dialect/Arith/IR/Arith.h" // from @llvm-project -#include "mlir/include/mlir/Dialect/Tensor/IR/Tensor.h" // from @llvm-project - -namespace mlir { -namespace tutorial { -namespace poly { - -#define GEN_PASS_DECL -#include "lib/Conversion/PolyToStandard/PolyToStandard.h.inc" - -#define GEN_PASS_REGISTRATION -#include "lib/Conversion/PolyToStandard/PolyToStandard.h.inc" - -} // namespace poly -} // namespace tutorial -} // namespace mlir - -#endif // LIB_CONVERSION_POLYTOSTANDARD_POLYTOSTANDARD_H_ diff --git a/lib/Conversion/PolyToStandard/PolyToStandard.td b/lib/Conversion/PolyToStandard/PolyToStandard.td deleted file mode 100644 index 31e9d9b..0000000 --- a/lib/Conversion/PolyToStandard/PolyToStandard.td +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef LIB_CONVERSION_POLYTOSTANDARD_POLYTOSTANDARD_TD_ -#define LIB_CONVERSION_POLYTOSTANDARD_POLYTOSTANDARD_TD_ - -include "mlir/Pass/PassBase.td" - -def PolyToStandard : Pass<"poly-to-standard"> { - let summary = "Lower `poly` to standard MLIR dialects."; - - let description = [{ - This pass lowers the `poly` dialect to standard MLIR, a mixture of affine, - tensor, and arith. - }]; - let dependentDialects = [ - "mlir::arith::ArithDialect", - "mlir::tutorial::poly::PolyDialect", - "mlir::tensor::TensorDialect", - "mlir::scf::SCFDialect", - ]; -} - -#endif // LIB_CONVERSION_POLYTOSTANDARD_POLYTOSTANDARD_TD_ diff --git a/lib/Dialect/CMakeLists.txt b/lib/Dialect/CMakeLists.txt deleted file mode 100644 index 1f27a0f..0000000 --- a/lib/Dialect/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -add_subdirectory(Noisy) -add_subdirectory(Poly) diff --git a/lib/Dialect/Noisy/BUILD b/lib/Dialect/Noisy/BUILD deleted file mode 100644 index 2a93043..0000000 --- a/lib/Dialect/Noisy/BUILD +++ /dev/null @@ -1,105 +0,0 @@ -load("@llvm-project//mlir:tblgen.bzl", "gentbl_cc_library", "td_library") - -package( - default_visibility = ["//visibility:public"], -) - -td_library( - name = "td_files", - srcs = [ - "NoisyDialect.td", - "NoisyOps.td", - "NoisyTypes.td", - ], - deps = [ - "@llvm-project//mlir:BuiltinDialectTdFiles", - "@llvm-project//mlir:InferIntRangeInterfaceTdFiles", - "@llvm-project//mlir:InferTypeOpInterfaceTdFiles", - "@llvm-project//mlir:OpBaseTdFiles", - "@llvm-project//mlir:SideEffectInterfacesTdFiles", - ], -) - -gentbl_cc_library( - name = "dialect_inc_gen", - tbl_outs = [ - ( - ["-gen-dialect-decls"], - "NoisyDialect.h.inc", - ), - ( - ["-gen-dialect-defs"], - "NoisyDialect.cpp.inc", - ), - ], - tblgen = "@llvm-project//mlir:mlir-tblgen", - td_file = "NoisyDialect.td", - deps = [ - ":td_files", - ], -) - -gentbl_cc_library( - name = "types_inc_gen", - tbl_outs = [ - ( - ["-gen-typedef-decls"], - "NoisyTypes.h.inc", - ), - ( - ["-gen-typedef-defs"], - "NoisyTypes.cpp.inc", - ), - ], - tblgen = "@llvm-project//mlir:mlir-tblgen", - td_file = "NoisyTypes.td", - deps = [ - ":dialect_inc_gen", - ":td_files", - ], -) - -gentbl_cc_library( - name = "ops_inc_gen", - tbl_outs = [ - ( - ["-gen-op-decls"], - "NoisyOps.h.inc", - ), - ( - ["-gen-op-defs"], - "NoisyOps.cpp.inc", - ), - ], - tblgen = "@llvm-project//mlir:mlir-tblgen", - td_file = "NoisyOps.td", - deps = [ - ":dialect_inc_gen", - ":td_files", - ":types_inc_gen", - ], -) - -cc_library( - name = "Noisy", - srcs = [ - "NoisyDialect.cpp", - "NoisyOps.cpp", - ], - hdrs = [ - "NoisyDialect.h", - "NoisyOps.h", - "NoisyTypes.h", - ], - deps = [ - ":dialect_inc_gen", - ":ops_inc_gen", - ":types_inc_gen", - "@llvm-project//mlir:ComplexDialect", - "@llvm-project//mlir:Dialect", - "@llvm-project//mlir:IR", - "@llvm-project//mlir:InferIntRangeInterface", - "@llvm-project//mlir:InferTypeOpInterface", - "@llvm-project//mlir:Support", - ], -) diff --git a/lib/Dialect/Noisy/CMakeLists.txt b/lib/Dialect/Noisy/CMakeLists.txt deleted file mode 100644 index adb5864..0000000 --- a/lib/Dialect/Noisy/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -# Inlining `add_mlir_dialect(Noisy noisy)` commands so that -# we can custom name `*.inc` generated files. -set(LLVM_TARGET_DEFINITIONS NoisyOps.td) -mlir_tablegen(NoisyOps.h.inc -gen-op-decls) -mlir_tablegen(NoisyOps.cpp.inc -gen-op-defs) -mlir_tablegen(NoisyTypes.h.inc -gen-typedef-decls -typedefs-dialect=noisy) -mlir_tablegen(NoisyTypes.cpp.inc -gen-typedef-defs -typedefs-dialect=noisy) -mlir_tablegen(NoisyDialect.h.inc -gen-dialect-decls -dialect=noisy) -mlir_tablegen(NoisyDialect.cpp.inc -gen-dialect-defs -dialect=noisy) -add_public_tablegen_target(MLIRNoisyOpsIncGen) -add_dependencies(mlir-headers MLIRNoisyOpsIncGen) - -add_mlir_doc(NoisyDialect NoisyDialect Noisy/ -gen-dialect-doc) - -add_mlir_dialect_library(MLIRNoisy - NoisyDialect.cpp - NoisyOps.cpp - - ADDITIONAL_HEADER_DIRS - ${PROJECT_SOURCE_DIR}/lib/Dialect/Noisy - ) diff --git a/lib/Dialect/Noisy/NoisyDialect.cpp b/lib/Dialect/Noisy/NoisyDialect.cpp deleted file mode 100644 index 0a4f5a5..0000000 --- a/lib/Dialect/Noisy/NoisyDialect.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "lib/Dialect/Noisy/NoisyDialect.h" - -#include "lib/Dialect/Noisy/NoisyOps.h" -#include "lib/Dialect/Noisy/NoisyTypes.h" -#include "mlir/include/mlir/IR/Builders.h" -#include "llvm/include/llvm/ADT/TypeSwitch.h" - -#include "lib/Dialect/Noisy/NoisyDialect.cpp.inc" -#define GET_TYPEDEF_CLASSES -#include "lib/Dialect/Noisy/NoisyTypes.cpp.inc" -#define GET_OP_CLASSES -#include "lib/Dialect/Noisy/NoisyOps.cpp.inc" - -namespace mlir { -namespace tutorial { -namespace noisy { - -void NoisyDialect::initialize() { - addTypes< -#define GET_TYPEDEF_LIST -#include "lib/Dialect/Noisy/NoisyTypes.cpp.inc" - >(); - addOperations< -#define GET_OP_LIST -#include "lib/Dialect/Noisy/NoisyOps.cpp.inc" - >(); -} - -} // namespace noisy -} // namespace tutorial -} // namespace mlir diff --git a/lib/Dialect/Noisy/NoisyDialect.h b/lib/Dialect/Noisy/NoisyDialect.h deleted file mode 100644 index 5098e1e..0000000 --- a/lib/Dialect/Noisy/NoisyDialect.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef LIB_DIALECT_NOISY_NOISYDIALECT_H_ -#define LIB_DIALECT_NOISY_NOISYDIALECT_H_ - -// Required because the .h.inc file refers to MLIR classes and does not itself -// have any includes. -#include "mlir/include/mlir/IR/DialectImplementation.h" - -#include "lib/Dialect/Noisy/NoisyDialect.h.inc" - - -constexpr int INITIAL_NOISE = 12; -constexpr int MAX_NOISE = 26; - -#endif // LIB_DIALECT_NOISY_NOISYDIALECT_H_ diff --git a/lib/Dialect/Noisy/NoisyDialect.td b/lib/Dialect/Noisy/NoisyDialect.td deleted file mode 100644 index 954e703..0000000 --- a/lib/Dialect/Noisy/NoisyDialect.td +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef LIB_DIALECT_NOISY_NOISYDIALECT_TD_ -#define LIB_DIALECT_NOISY_NOISYDIALECT_TD_ - -include "mlir/IR/OpBase.td" - -def Noisy_Dialect : Dialect { - let name = "noisy"; - let summary = "A dialect for arithmetic on noisy i32s"; - - let cppNamespace = "::mlir::tutorial::noisy"; - - let useDefaultTypePrinterParser = 1; -} - -#endif // LIB_DIALECT_NOISY_NOISYDIALECT_TD_ diff --git a/lib/Dialect/Noisy/NoisyOps.cpp b/lib/Dialect/Noisy/NoisyOps.cpp deleted file mode 100644 index 97e16a2..0000000 --- a/lib/Dialect/Noisy/NoisyOps.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "lib/Dialect/Noisy/NoisyOps.h" - -namespace mlir { -namespace tutorial { -namespace noisy { - -ConstantIntRanges initialNoiseRange() { - return ConstantIntRanges::fromUnsigned(APInt(32, 0), - APInt(32, INITIAL_NOISE)); -} - -ConstantIntRanges unionPlusOne(ArrayRef inputRanges) { - auto lhsRange = inputRanges[0]; - auto rhsRange = inputRanges[1]; - auto joined = lhsRange.rangeUnion(rhsRange); - return ConstantIntRanges::fromUnsigned(joined.umin(), joined.umax() + 1); -} - -void EncodeOp::inferResultRanges(ArrayRef inputRanges, - SetIntRangeFn setResultRange) { - setResultRange(getResult(), initialNoiseRange()); -} - -void AddOp::inferResultRanges(ArrayRef inputRanges, - SetIntRangeFn setResultRange) { - setResultRange(getResult(), unionPlusOne(inputRanges)); -} - -void SubOp::inferResultRanges(ArrayRef inputRanges, - SetIntRangeFn setResultRange) { - setResultRange(getResult(), unionPlusOne(inputRanges)); -} - -void MulOp::inferResultRanges(ArrayRef inputRanges, - SetIntRangeFn setResultRange) { - auto lhsRange = inputRanges[0]; - auto rhsRange = inputRanges[1]; - setResultRange(getResult(), ConstantIntRanges::fromUnsigned( - lhsRange.umin() + rhsRange.umin(), - lhsRange.umax() + rhsRange.umax())); -} - -void ReduceNoiseOp::inferResultRanges(ArrayRef inputRanges, - SetIntRangeFn setResultRange) { - setResultRange(getResult(), initialNoiseRange()); -} - -} // namespace noisy -} // namespace tutorial -} // namespace mlir diff --git a/lib/Dialect/Noisy/NoisyOps.h b/lib/Dialect/Noisy/NoisyOps.h deleted file mode 100644 index 12f83e4..0000000 --- a/lib/Dialect/Noisy/NoisyOps.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef LIB_DIALECT_NOISY_NOISYOPS_H_ -#define LIB_DIALECT_NOISY_NOISYOPS_H_ - -#include "lib/Dialect/Noisy/NoisyDialect.h" -#include "lib/Dialect/Noisy/NoisyTypes.h" -#include "mlir/Interfaces/InferTypeOpInterface.h" -#include "mlir/Interfaces/InferIntRangeInterface.h" -#include "mlir/include/mlir/IR/BuiltinOps.h" -#include "mlir/include/mlir/IR/BuiltinTypes.h" -#include "mlir/include/mlir/IR/Dialect.h" - -#define GET_OP_CLASSES -#include "lib/Dialect/Noisy/NoisyOps.h.inc" - -#endif // LIB_DIALECT_NOISY_NOISYOPS_H_ diff --git a/lib/Dialect/Noisy/NoisyOps.td b/lib/Dialect/Noisy/NoisyOps.td deleted file mode 100644 index bf2b604..0000000 --- a/lib/Dialect/Noisy/NoisyOps.td +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef LIB_DIALECT_NOISY_NOISYOPS_TD_ -#define LIB_DIALECT_NOISY_NOISYOPS_TD_ - -include "NoisyDialect.td" -include "NoisyTypes.td" -include "mlir/IR/BuiltinAttributes.td" -include "mlir/IR/CommonTypeConstraints.td" -include "mlir/IR/OpBase.td" -include "mlir/Interfaces/InferIntRangeInterface.td" -include "mlir/Interfaces/InferTypeOpInterface.td" -include "mlir/Interfaces/SideEffectInterfaces.td" - -class Noisy_BinOp : Op -]> { - let arguments = (ins Noisy_I32:$lhs, Noisy_I32:$rhs); - let results = (outs Noisy_I32:$output); - let assemblyFormat = "$lhs `,` $rhs attr-dict `:` qualified(type($output))"; -} - -def Noisy_AddOp : Noisy_BinOp<"add"> { - let summary = "Addition operation between noisy ints. Adds noise."; -} - -def Noisy_SubOp : Noisy_BinOp<"sub"> { - let summary = "Subtraction operation between noisy ints. Adds noise."; -} - -def Noisy_MulOp : Noisy_BinOp<"mul"> { - let summary = "Multiplication operation between noisy ints. Multiplies noise."; -} - -def Noisy_EncodeOp : Op]> { - let summary = "Encodes a noisy i32 from a small-width integer, injecting 12 bits of noise."; - let arguments = (ins AnyIntOfWidths<[1, 2, 3, 4, 5]>:$input); - let results = (outs Noisy_I32:$output); - let assemblyFormat = "$input attr-dict `:` type($input) `->` qualified(type($output))"; -} - -def Noisy_DecodeOp : Op { - let summary = "Decodes a noisy integer to a regular integer, failing if the noise is too high."; - let arguments = (ins Noisy_I32:$input); - let results = (outs AnyIntOfWidths<[1, 2, 3, 4, 5]>:$output); - let assemblyFormat = "$input attr-dict `:` qualified(type($input)) `->` type($output)"; -} - -def Noisy_ReduceNoiseOp : Op]> { - let summary = "Reduces the noise in a noisy integer to a fixed noise level. Expensive!"; - let arguments = (ins Noisy_I32:$input); - let results = (outs Noisy_I32:$output); - let assemblyFormat = "$input attr-dict `:` qualified(type($output))"; -} - -#endif // LIB_DIALECT_NOISY_NOISYOPS_TD_ diff --git a/lib/Dialect/Noisy/NoisyTypes.h b/lib/Dialect/Noisy/NoisyTypes.h deleted file mode 100644 index 7b432c9..0000000 --- a/lib/Dialect/Noisy/NoisyTypes.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef LIB_TYPES_NOISY_NOISYTYPES_H_ -#define LIB_TYPES_NOISY_NOISYTYPES_H_ - -#include "mlir/include/mlir/IR/DialectImplementation.h" - -#define GET_TYPEDEF_CLASSES -#include "lib/Dialect/Noisy/NoisyTypes.h.inc" - -#endif // LIB_TYPES_NOISY_NOISYTYPES_H_ diff --git a/lib/Dialect/Noisy/NoisyTypes.td b/lib/Dialect/Noisy/NoisyTypes.td deleted file mode 100644 index 2e65307..0000000 --- a/lib/Dialect/Noisy/NoisyTypes.td +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef LIB_DIALECT_NOISY_NOISYTYPES_TD_ -#define LIB_DIALECT_NOISY_NOISYTYPES_TD_ - -include "NoisyDialect.td" -include "mlir/IR/AttrTypeBase.td" - -class Noisy_Type : TypeDef { - let mnemonic = typeMnemonic; -} - -def Noisy_I32 : Noisy_Type<"NoisyI32", "i32"> { - let summary = "A type for approximate 32-bit integers."; -} - -#endif // LIB_DIALECT_NOISY_NOISYTYPES_TD_ diff --git a/lib/Dialect/Poly/BUILD b/lib/Dialect/Poly/BUILD deleted file mode 100644 index 5a4d699..0000000 --- a/lib/Dialect/Poly/BUILD +++ /dev/null @@ -1,123 +0,0 @@ -load("@llvm-project//mlir:tblgen.bzl", "gentbl_cc_library", "td_library") - -package( - default_visibility = ["//visibility:public"], -) - -td_library( - name = "td_files", - srcs = [ - "PolyDialect.td", - "PolyOps.td", - "PolyPatterns.td", - "PolyTypes.td", - ], - deps = [ - "@llvm-project//mlir:BuiltinDialectTdFiles", - "@llvm-project//mlir:InferTypeOpInterfaceTdFiles", - "@llvm-project//mlir:OpBaseTdFiles", - "@llvm-project//mlir:SideEffectInterfacesTdFiles", - ], -) - -gentbl_cc_library( - name = "dialect_inc_gen", - tbl_outs = [ - ( - ["-gen-dialect-decls"], - "PolyDialect.h.inc", - ), - ( - ["-gen-dialect-defs"], - "PolyDialect.cpp.inc", - ), - ], - tblgen = "@llvm-project//mlir:mlir-tblgen", - td_file = "PolyDialect.td", - deps = [ - ":td_files", - ], -) - -gentbl_cc_library( - name = "types_inc_gen", - tbl_outs = [ - ( - ["-gen-typedef-decls"], - "PolyTypes.h.inc", - ), - ( - ["-gen-typedef-defs"], - "PolyTypes.cpp.inc", - ), - ], - tblgen = "@llvm-project//mlir:mlir-tblgen", - td_file = "PolyTypes.td", - deps = [ - ":dialect_inc_gen", - ":td_files", - ], -) - -gentbl_cc_library( - name = "ops_inc_gen", - tbl_outs = [ - ( - ["-gen-op-decls"], - "PolyOps.h.inc", - ), - ( - ["-gen-op-defs"], - "PolyOps.cpp.inc", - ), - ], - tblgen = "@llvm-project//mlir:mlir-tblgen", - td_file = "PolyOps.td", - deps = [ - ":dialect_inc_gen", - ":td_files", - ":types_inc_gen", - ], -) - -gentbl_cc_library( - name = "canonicalize_inc_gen", - tbl_outs = [ - ( - ["-gen-rewriters"], - "PolyCanonicalize.cpp.inc", - ), - ], - tblgen = "@llvm-project//mlir:mlir-tblgen", - td_file = "PolyPatterns.td", - deps = [ - ":td_files", - ":types_inc_gen", - "@llvm-project//mlir:ComplexOpsTdFiles", - ], -) - -cc_library( - name = "Poly", - srcs = [ - "PolyDialect.cpp", - "PolyOps.cpp", - ], - hdrs = [ - "PolyDialect.h", - "PolyOps.h", - "PolyTraits.h", - "PolyTypes.h", - ], - deps = [ - ":canonicalize_inc_gen", - ":dialect_inc_gen", - ":ops_inc_gen", - ":types_inc_gen", - "@llvm-project//mlir:ComplexDialect", - "@llvm-project//mlir:Dialect", - "@llvm-project//mlir:IR", - "@llvm-project//mlir:InferTypeOpInterface", - "@llvm-project//mlir:Support", - ], -) diff --git a/lib/Dialect/Poly/CMakeLists.txt b/lib/Dialect/Poly/CMakeLists.txt deleted file mode 100644 index f001992..0000000 --- a/lib/Dialect/Poly/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -# Inlining `add_mlir_dialect(Poly poly)` commands so that -# we can custom name `*.inc` generated files. -set(LLVM_TARGET_DEFINITIONS PolyOps.td) -mlir_tablegen(PolyOps.h.inc -gen-op-decls) -mlir_tablegen(PolyOps.cpp.inc -gen-op-defs) -mlir_tablegen(PolyTypes.h.inc -gen-typedef-decls -typedefs-dialect=poly) -mlir_tablegen(PolyTypes.cpp.inc -gen-typedef-defs -typedefs-dialect=poly) -mlir_tablegen(PolyDialect.h.inc -gen-dialect-decls -dialect=poly) -mlir_tablegen(PolyDialect.cpp.inc -gen-dialect-defs -dialect=poly) -add_public_tablegen_target(MLIRPolyOpsIncGen) -add_dependencies(mlir-headers MLIRPolyOpsIncGen) - -add_mlir_doc(PolyDialect PolyDialect Poly/ -gen-dialect-doc) - -set(LLVM_TARGET_DEFINITIONS PolyPatterns.td) -mlir_tablegen(PolyCanonicalize.cpp.inc -gen-rewriters) -add_public_tablegen_target(MLIRPolyCanonicalizationIncGen) - -add_mlir_dialect_library(MLIRPoly - PolyDialect.cpp - PolyOps.cpp - - ADDITIONAL_HEADER_DIRS - ${PROJECT_SOURCE_DIR}/lib/Dialect/Poly - - LINK_LIBS PUBLIC - ) diff --git a/lib/Dialect/Poly/PolyDialect.cpp b/lib/Dialect/Poly/PolyDialect.cpp deleted file mode 100644 index 291cb12..0000000 --- a/lib/Dialect/Poly/PolyDialect.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "lib/Dialect/Poly/PolyDialect.h" - -#include "lib/Dialect/Poly/PolyOps.h" -#include "lib/Dialect/Poly/PolyTypes.h" -#include "mlir/include/mlir/IR/Builders.h" -#include "llvm/include/llvm/ADT/TypeSwitch.h" - -#include "lib/Dialect/Poly/PolyDialect.cpp.inc" -#define GET_TYPEDEF_CLASSES -#include "lib/Dialect/Poly/PolyTypes.cpp.inc" -#define GET_OP_CLASSES -#include "lib/Dialect/Poly/PolyOps.cpp.inc" - -namespace mlir { -namespace tutorial { -namespace poly { - -void PolyDialect::initialize() { - addTypes< -#define GET_TYPEDEF_LIST -#include "lib/Dialect/Poly/PolyTypes.cpp.inc" - >(); - addOperations< -#define GET_OP_LIST -#include "lib/Dialect/Poly/PolyOps.cpp.inc" - >(); -} - -Operation *PolyDialect::materializeConstant(OpBuilder &builder, Attribute value, - Type type, Location loc) { - auto coeffs = dyn_cast(value); - if (!coeffs) - return nullptr; - return builder.create(loc, type, coeffs); -} - -} // namespace poly -} // namespace tutorial -} // namespace mlir diff --git a/lib/Dialect/Poly/PolyDialect.h b/lib/Dialect/Poly/PolyDialect.h deleted file mode 100644 index 7f2948d..0000000 --- a/lib/Dialect/Poly/PolyDialect.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef LIB_DIALECT_POLY_POLYDIALECT_H_ -#define LIB_DIALECT_POLY_POLYDIALECT_H_ - -// Required because the .h.inc file refers to MLIR classes and does not itself -// have any includes. -#include "mlir/include/mlir/IR/DialectImplementation.h" - -#include "lib/Dialect/Poly/PolyDialect.h.inc" - -#endif // LIB_DIALECT_POLY_POLYDIALECT_H_ diff --git a/lib/Dialect/Poly/PolyDialect.td b/lib/Dialect/Poly/PolyDialect.td deleted file mode 100644 index b7df1b3..0000000 --- a/lib/Dialect/Poly/PolyDialect.td +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef LIB_DIALECT_POLY_POLYDIALECT_TD_ -#define LIB_DIALECT_POLY_POLYDIALECT_TD_ - -include "mlir/IR/OpBase.td" - -def Poly_Dialect : Dialect { - let name = "poly"; - let summary = "A dialect for polynomial math"; - let description = [{ - The poly dialect defines types and operations for single-variable - polynomials over integers. - }]; - - let cppNamespace = "::mlir::tutorial::poly"; - - let useDefaultTypePrinterParser = 1; - let hasConstantMaterializer = 1; -} - -#endif // LIB_DIALECT_POLY_POLYDIALECT_TD_ diff --git a/lib/Dialect/Poly/PolyOps.cpp b/lib/Dialect/Poly/PolyOps.cpp deleted file mode 100644 index 5436401..0000000 --- a/lib/Dialect/Poly/PolyOps.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include "lib/Dialect/Poly/PolyOps.h" - -#include "mlir/Dialect/CommonFolders.h" -#include "mlir/Dialect/Complex/IR/Complex.h" -#include "mlir/IR/PatternMatch.h" - -// Required after PatternMatch.h -#include "lib/Dialect/Poly/PolyCanonicalize.cpp.inc" - -namespace mlir { -namespace tutorial { -namespace poly { - -OpFoldResult ConstantOp::fold(ConstantOp::FoldAdaptor adaptor) { - return adaptor.getCoefficients(); -} - -OpFoldResult AddOp::fold(AddOp::FoldAdaptor adaptor) { - return constFoldBinaryOp( - adaptor.getOperands(), [&](APInt a, APInt b) { return a + b; }); -} - -OpFoldResult SubOp::fold(SubOp::FoldAdaptor adaptor) { - return constFoldBinaryOp( - adaptor.getOperands(), [&](APInt a, APInt b) { return a - b; }); -} - -OpFoldResult MulOp::fold(MulOp::FoldAdaptor adaptor) { - auto lhs = dyn_cast_or_null(adaptor.getOperands()[0]); - auto rhs = dyn_cast_or_null(adaptor.getOperands()[1]); - - if (!lhs || !rhs) return nullptr; - - auto degree = llvm::cast(getResult().getType()).getDegreeBound(); - auto maxIndex = lhs.size() + rhs.size() - 1; - - SmallVector result; - result.reserve(maxIndex); - for (int i = 0; i < maxIndex; ++i) { - result.push_back(APInt((*lhs.begin()).getBitWidth(), 0)); - } - - int i = 0; - for (auto lhsIt = lhs.value_begin(); lhsIt != lhs.value_end(); - ++lhsIt) { - int j = 0; - for (auto rhsIt = rhs.value_begin(); rhsIt != rhs.value_end(); - ++rhsIt) { - // index is modulo degree because poly's semantics are defined modulo x^N - // = 1. - result[(i + j) % degree] += *rhsIt * (*lhsIt); - ++j; - } - ++i; - } - - return DenseIntElementsAttr::get( - RankedTensorType::get(static_cast(result.size()), - IntegerType::get(getContext(), 32)), - result); -} - -OpFoldResult FromTensorOp::fold(FromTensorOp::FoldAdaptor adaptor) { - // Returns null if the cast failed, which corresponds to a failed fold. - return dyn_cast_or_null(adaptor.getInput()); -} - -LogicalResult EvalOp::verify() { - auto pointTy = getPoint().getType(); - bool isSignlessInteger = pointTy.isSignlessInteger(32); - auto complexPt = dyn_cast(pointTy); - return isSignlessInteger || complexPt ? success() - : emitOpError( - "argument point must be a 32-bit " - "integer, or a complex number"); -} - -void AddOp::getCanonicalizationPatterns(::mlir::RewritePatternSet &results, - ::mlir::MLIRContext *context) {} - -void SubOp::getCanonicalizationPatterns(::mlir::RewritePatternSet &results, - ::mlir::MLIRContext *context) { - results.add(context); -} - -void MulOp::getCanonicalizationPatterns(::mlir::RewritePatternSet &results, - ::mlir::MLIRContext *context) {} - -void EvalOp::getCanonicalizationPatterns(::mlir::RewritePatternSet &results, - ::mlir::MLIRContext *context) { - results.add(context); -} - -} // namespace poly -} // namespace tutorial -} // namespace mlir diff --git a/lib/Dialect/Poly/PolyOps.h b/lib/Dialect/Poly/PolyOps.h deleted file mode 100644 index c562244..0000000 --- a/lib/Dialect/Poly/PolyOps.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef LIB_DIALECT_POLY_POLYOPS_H_ -#define LIB_DIALECT_POLY_POLYOPS_H_ - -#include "lib/Dialect/Poly/PolyDialect.h" -#include "lib/Dialect/Poly/PolyTraits.h" -#include "lib/Dialect/Poly/PolyTypes.h" -#include "mlir/Interfaces/InferTypeOpInterface.h" // from @llvm-project -#include "mlir/include/mlir/IR/BuiltinOps.h" // from @llvm-project -#include "mlir/include/mlir/IR/BuiltinTypes.h" // from @llvm-project -#include "mlir/include/mlir/IR/Dialect.h" // from @llvm-project - -#define GET_OP_CLASSES -#include "lib/Dialect/Poly/PolyOps.h.inc" - -#endif // LIB_DIALECT_POLY_POLYOPS_H_ diff --git a/lib/Dialect/Poly/PolyOps.td b/lib/Dialect/Poly/PolyOps.td deleted file mode 100644 index 76cb2f9..0000000 --- a/lib/Dialect/Poly/PolyOps.td +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef LIB_DIALECT_POLY_POLYOPS_TD_ -#define LIB_DIALECT_POLY_POLYOPS_TD_ - -include "PolyDialect.td" -include "PolyTypes.td" -include "mlir/IR/BuiltinAttributes.td" -include "mlir/IR/OpBase.td" -include "mlir/Interfaces/InferTypeOpInterface.td" -include "mlir/Interfaces/SideEffectInterfaces.td" - -// Type constraint for poly binop arguments: polys, vectors of polys, or -// tensors of polys. -def PolyOrContainer : TypeOrContainer; - -// Inject verification that all integer-like arguments are 32-bits -def Has32BitArguments : NativeOpTrait<"Has32BitArguments"> { - let cppNamespace = "::mlir::tutorial::poly"; -} - -class Poly_BinOp : Op { - let arguments = (ins PolyOrContainer:$lhs, PolyOrContainer:$rhs); - let results = (outs PolyOrContainer:$output); - let assemblyFormat = "$lhs `,` $rhs attr-dict `:` qualified(type($output))"; - let hasFolder = 1; - let hasCanonicalizer = 1; -} - -def Poly_AddOp : Poly_BinOp<"add"> { - let summary = "Addition operation between polynomials."; -} - -def Poly_SubOp : Poly_BinOp<"sub"> { - let summary = "Subtraction operation between polynomials."; -} - -def Poly_MulOp : Poly_BinOp<"mul"> { - let summary = "Multiplication operation between polynomials."; -} - -def Poly_FromTensorOp : Op { - let summary = "Creates a Polynomial from integer coefficients stored in a tensor."; - let arguments = (ins TensorOf<[AnyInteger]>:$input); - let results = (outs Polynomial:$output); - let assemblyFormat = "$input attr-dict `:` type($input) `->` qualified(type($output))"; - let hasFolder = 1; -} - -def Poly_ToTensorOp : Op { - let summary = "Converts a polynomial to a tensor of its integer coefficients."; - let arguments = (ins Polynomial:$input); - let results = (outs TensorOf<[AnyInteger]>:$output); - let assemblyFormat = "$input attr-dict `:` qualified(type($input)) `->` type($output)"; -} - -def IntOrComplex : AnyTypeOf<[AnyInteger, AnyComplex]>; - -def Poly_EvalOp : Op, Has32BitArguments]> { - let summary = "Evaluates a Polynomial at a given input value."; - let arguments = (ins Polynomial:$polynomial, IntOrComplex:$point); - let results = (outs IntOrComplex:$output); - let assemblyFormat = "$polynomial `,` $point attr-dict `:` `(` qualified(type($polynomial)) `,` type($point) `)` `->` type($output)"; - let hasVerifier = 1; - let hasCanonicalizer = 1; -} - -def Poly_ConstantOp : Op { - let summary = "Define a constant polynomial via an attribute."; - let arguments = (ins AnyIntElementsAttr:$coefficients); - let results = (outs Polynomial:$output); - let assemblyFormat = "$coefficients attr-dict `:` qualified(type($output))"; - let hasFolder = 1; -} - - -#endif // LIB_DIALECT_POLY_POLYOPS_TD_ diff --git a/lib/Dialect/Poly/PolyPatterns.td b/lib/Dialect/Poly/PolyPatterns.td deleted file mode 100644 index 47d0ac7..0000000 --- a/lib/Dialect/Poly/PolyPatterns.td +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef LIB_DIALECT_POLY_POLYPATTERNS_TD_ -#define LIB_DIALECT_POLY_POLYPATTERNS_TD_ - -include "PolyOps.td" -include "mlir/Dialect/Complex/IR/ComplexOps.td" -include "mlir/IR/PatternBase.td" - -def LiftConjThroughEval : Pat< - (Poly_EvalOp $f, (ConjOp $z, $fastmath)), - (ConjOp (Poly_EvalOp $f, $z), $fastmath) ->; - -def HasOneUse: Constraint, "has one use">; - -// Rewrites (x^2 - y^2) as (x+y)(x-y) if x^2 and y^2 have no other uses. -def DifferenceOfSquares : Pattern< - (Poly_SubOp (Poly_MulOp:$lhs $x, $x), (Poly_MulOp:$rhs $y, $y)), - [ - (Poly_AddOp:$sum $x, $y), - (Poly_SubOp:$diff $x, $y), - (Poly_MulOp:$res $sum, $diff), - ], - [(HasOneUse:$lhs), (HasOneUse:$rhs)] ->; - -#endif // LIB_DIALECT_POLY_POLYPATTERNS_TD_ diff --git a/lib/Dialect/Poly/PolyTraits.h b/lib/Dialect/Poly/PolyTraits.h deleted file mode 100644 index d220f1c..0000000 --- a/lib/Dialect/Poly/PolyTraits.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef LIB_DIALECT_POLY_POLYTRAITS_H_ -#define LIB_DIALECT_POLY_POLYTRAITS_H_ - -#include "mlir/include/mlir/IR/OpDefinition.h" - -namespace mlir::tutorial::poly { - -template -class Has32BitArguments : public OpTrait::TraitBase { - public: - static LogicalResult verifyTrait(Operation *op) { - for (auto type : op->getOperandTypes()) { - // OK to skip non-integer operand types - if (!type.isIntOrIndex()) continue; - - if (!type.isInteger(32)) { - return op->emitOpError() - << "requires each numeric operand to be a 32-bit integer"; - } - } - - return success(); - } -}; - -} - -#endif // LIB_DIALECT_POLY_POLYTRAITS_H_ diff --git a/lib/Dialect/Poly/PolyTypes.h b/lib/Dialect/Poly/PolyTypes.h deleted file mode 100644 index 7dcfe2b..0000000 --- a/lib/Dialect/Poly/PolyTypes.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef LIB_TYPES_POLY_POLYTYPES_H_ -#define LIB_TYPES_POLY_POLYTYPES_H_ - -// Required because the .h.inc file refers to MLIR classes and does not itself -// have any includes. -#include "mlir/include/mlir/IR/DialectImplementation.h" - -#define GET_TYPEDEF_CLASSES -#include "lib/Dialect/Poly/PolyTypes.h.inc" - -#endif // LIB_TYPES_POLY_POLYTYPES_H_ diff --git a/lib/Dialect/Poly/PolyTypes.td b/lib/Dialect/Poly/PolyTypes.td deleted file mode 100644 index 85b68f5..0000000 --- a/lib/Dialect/Poly/PolyTypes.td +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef LIB_DIALECT_POLY_POLYTYPES_TD_ -#define LIB_DIALECT_POLY_POLYTYPES_TD_ - -include "PolyDialect.td" -include "mlir/IR/AttrTypeBase.td" - -// A base class for all types in this dialect -class Poly_Type : TypeDef { - let mnemonic = typeMnemonic; -} - -def Polynomial : Poly_Type<"Polynomial", "poly"> { - let summary = "A polynomial with u32 coefficients"; - - let description = [{ - A type for polynomials with integer coefficients in a single-variable polynomial ring. - }]; - - let parameters = (ins "int":$degreeBound); - let assemblyFormat = "`<` $degreeBound `>`"; -} - -#endif // LIB_DIALECT_POLY_POLYTYPES_TD_ diff --git a/lib/Transform/Arith/BUILD b/lib/Transform/Arith/BUILD deleted file mode 100644 index eff7694..0000000 --- a/lib/Transform/Arith/BUILD +++ /dev/null @@ -1,87 +0,0 @@ -# Passes that work with the Arith dialect - -load("@llvm-project//mlir:tblgen.bzl", "gentbl_cc_library") - -package( - default_visibility = ["//visibility:public"], -) - -gentbl_cc_library( - name = "pass_inc_gen", - tbl_outs = [ - ( - [ - "-gen-pass-decls", - "-name=Arith", - ], - "Passes.h.inc", - ), - ( - ["-gen-pass-doc"], - "ArithPasses.md", - ), - ], - tblgen = "@llvm-project//mlir:mlir-tblgen", - td_file = "Passes.td", - deps = [ - "@llvm-project//mlir:OpBaseTdFiles", - "@llvm-project//mlir:PDLDialectTdFiles", - "@llvm-project//mlir:PDLInterpOpsTdFiles", - "@llvm-project//mlir:PassBaseTdFiles", - ], -) - -cc_library( - name = "MulToAdd", - srcs = ["MulToAdd.cpp"], - hdrs = ["MulToAdd.h"], - deps = [ - ":pass_inc_gen", - "@llvm-project//mlir:ArithDialect", - "@llvm-project//mlir:FuncDialect", - "@llvm-project//mlir:Pass", - "@llvm-project//mlir:Transforms", - ], -) - -cc_library( - name = "Passes", - hdrs = ["Passes.h"], - deps = [ - ":MulToAdd", - ":MulToAddPdll", - ":pass_inc_gen", - ], -) - -gentbl_cc_library( - name = "MulToAddPdllIncGen", - tbl_outs = [ - ( - ["-x=cpp"], - "MulToAddPdll.h.inc", - ), - ], - tblgen = "@llvm-project//mlir:mlir-pdll", - td_file = "MulToAdd.pdll", - deps = [ - "@llvm-project//mlir:ArithDialect", - "@llvm-project//mlir:FuncDialect", - "@llvm-project//mlir:ArithOpsTdFiles", - ], -) - -cc_library( - name = "MulToAddPdll", - srcs = ["MulToAddPdll.cpp"], - hdrs = ["MulToAddPdll.h"], - deps = [ - ":pass_inc_gen", - ":MulToAddPdllIncGen", - "@llvm-project//mlir:ArithDialect", - "@llvm-project//mlir:FuncDialect", - "@llvm-project//mlir:Pass", - "@llvm-project//mlir:Transforms", - ], -) - diff --git a/lib/Transform/Arith/CMakeLists.txt b/lib/Transform/Arith/CMakeLists.txt deleted file mode 100644 index 4f5d918..0000000 --- a/lib/Transform/Arith/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -add_mlir_pdll_library(MulToAddPdllIncGen - MulToAdd.pdll - MulToAddPdll.h.inc -) - -add_mlir_library(MulToAdd - MulToAdd.cpp - MulToAddPdll.cpp - - ${PROJECT_SOURCE_DIR}/lib/Transform/Arith/ - ADDITIONAL_HEADER_DIRS - - DEPENDS - MLIRMulToAddPasses - MulToAddPdllIncGen - - LINK_LIBS PUBLIC -) - -set(LLVM_TARGET_DEFINITIONS Passes.td) -mlir_tablegen(Passes.h.inc -gen-pass-decls -name Arith) -add_public_tablegen_target(MLIRMulToAddPasses) -add_mlir_doc(Passes ArithPasses ./ -gen-pass-doc) diff --git a/lib/Transform/Arith/MulToAdd.cpp b/lib/Transform/Arith/MulToAdd.cpp deleted file mode 100644 index 03ebd35..0000000 --- a/lib/Transform/Arith/MulToAdd.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "lib/Transform/Arith/MulToAdd.h" -#include "mlir/Dialect/Arith/IR/Arith.h" -#include "mlir/IR/PatternMatch.h" -#include "mlir/Transforms/GreedyPatternRewriteDriver.h" -#include "mlir/include/mlir/Pass/Pass.h" - -namespace mlir { -namespace tutorial { - -#define GEN_PASS_DEF_MULTOADD -#include "lib/Transform/Arith/Passes.h.inc" - -using arith::AddIOp; -using arith::ConstantOp; -using arith::MulIOp; - -// Replace y = C*x with y = C/2*x + C/2*x, when C is a power of 2, otherwise do -// nothing. -struct PowerOfTwoExpand : public OpRewritePattern { - PowerOfTwoExpand(mlir::MLIRContext *context) - : OpRewritePattern(context, /*benefit=*/2) {} - - LogicalResult matchAndRewrite(MulIOp op, - PatternRewriter &rewriter) const override { - Value lhs = op.getOperand(0); - - // canonicalization patterns ensure the constant is on the right, if there - // is a constant See - // https://mlir.llvm.org/docs/Canonicalization/#globally-applied-rules - Value rhs = op.getOperand(1); - auto rhsDefiningOp = rhs.getDefiningOp(); - if (!rhsDefiningOp) { - return failure(); - } - - int64_t value = rhsDefiningOp.value(); - bool is_power_of_two = (value & (value - 1)) == 0; - - if (!is_power_of_two) { - return failure(); - } - - ConstantOp newConstant = rewriter.create( - rhsDefiningOp.getLoc(), - rewriter.getIntegerAttr(rhs.getType(), value / 2)); - MulIOp newMul = rewriter.create(op.getLoc(), lhs, newConstant); - AddIOp newAdd = rewriter.create(op.getLoc(), newMul, newMul); - - rewriter.replaceOp(op, newAdd); - rewriter.eraseOp(rhsDefiningOp); - - return success(); - } -}; - -// Replace y = 9*x with y = 8*x + x -struct PeelFromMul : public OpRewritePattern { - PeelFromMul(mlir::MLIRContext *context) - : OpRewritePattern(context, /*benefit=*/1) {} - - LogicalResult matchAndRewrite(MulIOp op, - PatternRewriter &rewriter) const override { - Value lhs = op.getOperand(0); - Value rhs = op.getOperand(1); - auto rhsDefiningOp = rhs.getDefiningOp(); - if (!rhsDefiningOp) { - return failure(); - } - - int64_t value = rhsDefiningOp.value(); - - // We are guaranteed `value` is not a power of two, because the greedy - // rewrite engine ensures the PowerOfTwoExpand pattern is run first, since - // it has higher benefit. - - ConstantOp newConstant = rewriter.create( - rhsDefiningOp.getLoc(), - rewriter.getIntegerAttr(rhs.getType(), value - 1)); - MulIOp newMul = rewriter.create(op.getLoc(), lhs, newConstant); - AddIOp newAdd = rewriter.create(op.getLoc(), newMul, lhs); - - rewriter.replaceOp(op, newAdd); - rewriter.eraseOp(rhsDefiningOp); - - return success(); - } -}; - -struct MulToAdd : impl::MulToAddBase { - using MulToAddBase::MulToAddBase; - - void runOnOperation() { - mlir::RewritePatternSet patterns(&getContext()); - patterns.add(&getContext()); - patterns.add(&getContext()); - (void)applyPatternsAndFoldGreedily(getOperation(), std::move(patterns)); - } -}; - -} // namespace tutorial -} // namespace mlir diff --git a/lib/Transform/Arith/MulToAdd.h b/lib/Transform/Arith/MulToAdd.h deleted file mode 100644 index cb6846d..0000000 --- a/lib/Transform/Arith/MulToAdd.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef LIB_TRANSFORM_ARITH_MULTOADD_H_ -#define LIB_TRANSFORM_ARITH_MULTOADD_H_ - -#include "mlir/Pass/Pass.h" - -namespace mlir { -namespace tutorial { - -#define GEN_PASS_DECL_MULTOADD -#include "lib/Transform/Arith/Passes.h.inc" - -} // namespace tutorial -} // namespace mlir - -#endif // LIB_TRANSFORM_ARITH_MULTOADD_H_ diff --git a/lib/Transform/Arith/MulToAdd.pdll b/lib/Transform/Arith/MulToAdd.pdll deleted file mode 100644 index 8bbddcb..0000000 --- a/lib/Transform/Arith/MulToAdd.pdll +++ /dev/null @@ -1,67 +0,0 @@ -#include "mlir/Dialect/Arith/IR/ArithOps.td" - -Constraint IsPowerOfTwo(attr: Attr) [{ - int64_t value = cast<::mlir::IntegerAttr>(attr).getValue().getSExtValue(); - return success((value & (value - 1)) == 0); -}]; - -// Currently, constraints that return values must be defined in C++ -Constraint Halve(atttr: Attr) -> Attr; -Constraint MinusOne(attr: Attr) -> Attr; - -// Replace y = C*x with y = C/2*x + C/2*x, when C is a power of 2, otherwise do -// nothing. -Pattern PowerOfTwoExpandRhs with benefit(2) { - let root = op(op {value = const: Attr}, rhs: Value); - IsPowerOfTwo(const); - let halved: Attr = Halve(const); - - rewrite root with { - let newConst = op {value = halved}; - let newMul = op(newConst, rhs); - let newAdd = op(newMul, newMul); - replace root with newAdd; - }; -} - -Pattern PowerOfTwoExpandLhs with benefit(2) { - let root = op(lhs: Value, op {value = const: Attr}); - IsPowerOfTwo(const); - let halved: Attr = Halve(const); - - rewrite root with { - let newConst = op {value = halved}; - let newMul = op(lhs, newConst); - let newAdd = op(newMul, newMul); - replace root with newAdd; - }; -} - -// Replace y = 9*x with y = 8*x + x -Pattern PeelFromMulRhs with benefit(1) { - let root = op(lhs: Value, op {value = const: Attr}); - - // We are guaranteed `value` is not a power of two, because the greedy - // rewrite engine ensures the PowerOfTwoExpand pattern is run first, since - // it has higher benefit. - let minusOne: Attr = MinusOne(const); - - rewrite root with { - let newConst = op {value = minusOne}; - let newMul = op(lhs, newConst); - let newAdd = op(newMul, lhs); - replace root with newAdd; - }; -} - -Pattern PeelFromMulLhs with benefit(1) { - let root = op(op {value = const: Attr}, rhs: Value); - let minusOne: Attr = MinusOne(const); - - rewrite root with { - let newConst = op {value = minusOne}; - let newMul = op(newConst, rhs); - let newAdd = op(newMul, rhs); - replace root with newAdd; - }; -} diff --git a/lib/Transform/Arith/MulToAddPdll.cpp b/lib/Transform/Arith/MulToAddPdll.cpp deleted file mode 100644 index 0566342..0000000 --- a/lib/Transform/Arith/MulToAddPdll.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "lib/Transform/Arith/MulToAddPdll.h" -#include "mlir/Dialect/Arith/IR/Arith.h" -#include "mlir/Dialect/PDLInterp/IR/PDLInterp.h" -#include "mlir/IR/PatternMatch.h" -#include "mlir/Transforms/GreedyPatternRewriteDriver.h" -#include "mlir/include/mlir/Pass/Pass.h" - -namespace mlir { -namespace tutorial { - -#define GEN_PASS_DEF_MULTOADDPDLL -#include "lib/Transform/Arith/Passes.h.inc" - -LogicalResult halveImpl(PatternRewriter &rewriter, PDLResultList &results, - ArrayRef args) { - Attribute attr = args[0].cast(); - IntegerAttr cAttr = cast(attr); - int64_t value = cAttr.getValue().getSExtValue(); - results.push_back(rewriter.getIntegerAttr(cAttr.getType(), value / 2)); - return success(); -} - -LogicalResult minusOneImpl(PatternRewriter &rewriter, PDLResultList &results, - ArrayRef args) { - Attribute attr = args[0].cast(); - IntegerAttr cAttr = cast(attr); - int64_t value = cAttr.getValue().getSExtValue(); - results.push_back(rewriter.getIntegerAttr(cAttr.getType(), value - 1)); - return success(); -} - -void registerNativeConstraints(RewritePatternSet &patterns) { - patterns.getPDLPatterns().registerConstraintFunction("Halve", halveImpl); - patterns.getPDLPatterns().registerConstraintFunction("MinusOne", minusOneImpl); -} - -struct MulToAddPdll : impl::MulToAddPdllBase { - using MulToAddPdllBase::MulToAddPdllBase; - - void runOnOperation() { - mlir::RewritePatternSet patterns(&getContext()); - populateGeneratedPDLLPatterns(patterns); - registerNativeConstraints(patterns); - (void)applyPatternsAndFoldGreedily(getOperation(), std::move(patterns)); - } -}; - -} // namespace tutorial -} // namespace mlir diff --git a/lib/Transform/Arith/MulToAddPdll.h b/lib/Transform/Arith/MulToAddPdll.h deleted file mode 100644 index 36ee995..0000000 --- a/lib/Transform/Arith/MulToAddPdll.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef LIB_TRANSFORM_ARITH_MULTOADDPDLL_H_ -#define LIB_TRANSFORM_ARITH_MULTOADDPDLL_H_ - -#include "mlir/Pass/Pass.h" -#include "mlir/IR/PatternMatch.h" -#include "mlir/Dialect/Arith/IR/Arith.h" -#include "mlir/Parser/Parser.h" - -namespace mlir { -namespace tutorial { - -#define GEN_PASS_DECL_MULTOADDPDLL -#include "lib/Transform/Arith/Passes.h.inc" - -#include "lib/Transform/Arith/MulToAddPdll.h.inc" - -} // namespace tutorial -} // namespace mlir - -#endif // LIB_TRANSFORM_ARITH_MULTOADDPDLL_H_ diff --git a/lib/Transform/Arith/Passes.h b/lib/Transform/Arith/Passes.h deleted file mode 100644 index d2e849f..0000000 --- a/lib/Transform/Arith/Passes.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef LIB_TRANSFORM_ARITH_PASSES_H_ -#define LIB_TRANSFORM_ARITH_PASSES_H_ - -#include "lib/Transform/Arith/MulToAdd.h" -#include "lib/Transform/Arith/MulToAddPdll.h" - -namespace mlir { -namespace tutorial { - -#define GEN_PASS_REGISTRATION -#include "lib/Transform/Arith/Passes.h.inc" - -} // namespace tutorial -} // namespace mlir - -#endif // LIB_TRANSFORM_ARITH_PASSES_H_ diff --git a/lib/Transform/Arith/Passes.td b/lib/Transform/Arith/Passes.td deleted file mode 100644 index e403b10..0000000 --- a/lib/Transform/Arith/Passes.td +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef LIB_TRANSFORM_ARITH_PASSES_TD_ -#define LIB_TRANSFORM_ARITH_PASSES_TD_ - -include "mlir/Dialect/PDL/IR/PDLDialect.td" -include "mlir/Dialect/PDLInterp/IR/PDLInterpOps.td" -include "mlir/Pass/PassBase.td" - -def MulToAdd : Pass<"mul-to-add"> { - let summary = "Convert multiplications to repeated additions"; - let description = [{ - Convert multiplications to repeated additions. - }]; -} - -def MulToAddPdll : Pass<"mul-to-add-pdll"> { - let summary = "Convert multiplications to repeated additions using pdll"; - let description = [{ - Convert multiplications to repeated additions (using pdll). - }]; - let dependentDialects = [ - "mlir::pdl::PDLDialect", - "mlir::pdl_interp::PDLInterpDialect", -]; -} - -#endif // LIB_TRANSFORM_ARITH_PASSES_TD_ diff --git a/lib/Transform/Noisy/BUILD b/lib/Transform/Noisy/BUILD deleted file mode 100644 index 369c4f0..0000000 --- a/lib/Transform/Noisy/BUILD +++ /dev/null @@ -1,57 +0,0 @@ -# Passes that work with the Noisy dialect - -load("@llvm-project//mlir:tblgen.bzl", "gentbl_cc_library") - -package( - default_visibility = ["//visibility:public"], -) - -gentbl_cc_library( - name = "pass_inc_gen", - tbl_outs = [ - ( - [ - "-gen-pass-decls", - "-name=Noisy", - ], - "Passes.h.inc", - ), - ( - ["-gen-pass-doc"], - "NoisyPasses.md", - ), - ], - tblgen = "@llvm-project//mlir:mlir-tblgen", - td_file = "Passes.td", - deps = [ - "@llvm-project//mlir:OpBaseTdFiles", - "@llvm-project//mlir:PassBaseTdFiles", - ], -) - -cc_library( - name = "ReduceNoiseOptimizer", - srcs = ["ReduceNoiseOptimizer.cpp"], - hdrs = [ - "Passes.h", - "ReduceNoiseOptimizer.h", - ], - deps = [ - ":pass_inc_gen", - "//lib/Analysis/ReduceNoiseAnalysis", - "//lib/Dialect/Noisy", - "@llvm-project//llvm:Support", - "@llvm-project//mlir:Analysis", - "@llvm-project//mlir:Pass", - "@llvm-project//mlir:Transforms", - ], -) - -cc_library( - name = "Passes", - hdrs = ["Passes.h"], - deps = [ - ":ReduceNoiseOptimizer", - ":pass_inc_gen", - ], -) diff --git a/lib/Transform/Noisy/CMakeLists.txt b/lib/Transform/Noisy/CMakeLists.txt deleted file mode 100644 index 94568d8..0000000 --- a/lib/Transform/Noisy/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -add_mlir_library(NoisyPasses - ReduceNoiseOptimizer.cpp - - ${PROJECT_SOURCE_DIR}/lib/Transform/Noisy/ - ADDITIONAL_HEADER_DIRS - - DEPENDS - MLIRNoisy - MLIRNoisyPasses - - LINK_LIBS PUBLIC - ReduceNoiseAnalysis -) - -set(LLVM_TARGET_DEFINITIONS Passes.td) -mlir_tablegen(Passes.h.inc -gen-pass-decls -name Noisy) -add_public_tablegen_target(MLIRNoisyPasses) -add_mlir_doc(Passes NoisyPasses ./ -gen-pass-doc) diff --git a/lib/Transform/Noisy/Passes.h b/lib/Transform/Noisy/Passes.h deleted file mode 100644 index 6711b1f..0000000 --- a/lib/Transform/Noisy/Passes.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef LIB_TRANSFORM_NOISY_PASSES_H_ -#define LIB_TRANSFORM_NOISY_PASSES_H_ - -#include "lib/Transform/Noisy/ReduceNoiseOptimizer.h" - -namespace mlir { -namespace tutorial { -namespace noisy { - -#define GEN_PASS_REGISTRATION -#include "lib/Transform/Noisy/Passes.h.inc" - -} // namespace noisy -} // namespace tutorial -} // namespace mlir - -#endif // LIB_TRANSFORM_NOISY_PASSES_H_ diff --git a/lib/Transform/Noisy/Passes.td b/lib/Transform/Noisy/Passes.td deleted file mode 100644 index a25b53d..0000000 --- a/lib/Transform/Noisy/Passes.td +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef LIB_TRANSFORM_NOISY_PASSES_TD_ -#define LIB_TRANSFORM_NOISY_PASSES_TD_ - -include "mlir/Pass/PassBase.td" - -def ReduceNoiseOptimizer : Pass<"noisy-reduce-noise-optimizer"> { - let summary = "Insert reduce_noise ops optimally"; - let description = [{ - Solves an integer linear program to select the optimal locations in the IR - to insert `reduce_noise` ops. - }]; - let dependentDialects = ["mlir::tutorial::noisy::NoisyDialect"]; -} - -#endif // LIB_TRANSFORM_NOISY_PASSES_TD_ diff --git a/lib/Transform/Noisy/ReduceNoiseOptimizer.cpp b/lib/Transform/Noisy/ReduceNoiseOptimizer.cpp deleted file mode 100644 index 05b4088..0000000 --- a/lib/Transform/Noisy/ReduceNoiseOptimizer.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#include "lib/Transform/Noisy/ReduceNoiseOptimizer.h" - -#include "lib/Analysis/ReduceNoiseAnalysis/ReduceNoiseAnalysis.h" -#include "lib/Dialect/Noisy/NoisyOps.h" -#include "lib/Dialect/Noisy/NoisyTypes.h" -#include "mlir/include/mlir/Analysis/DataFlow/DeadCodeAnalysis.h" -#include "mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h" -#include "mlir/include/mlir/Analysis/DataFlowFramework.h" -#include "mlir/include/mlir/IR/Visitors.h" -#include "mlir/include/mlir/Pass/Pass.h" - -namespace mlir { -namespace tutorial { -namespace noisy { - -#define GEN_PASS_DEF_REDUCENOISEOPTIMIZER -#include "lib/Transform/Noisy/Passes.h.inc" - -struct ReduceNoiseOptimizer - : impl::ReduceNoiseOptimizerBase { - using ReduceNoiseOptimizerBase::ReduceNoiseOptimizerBase; - - void runOnOperation() { - Operation *module = getOperation(); - - // FIXME: Should have some way to mark failure when solver is infeasible - ReduceNoiseAnalysis analysis(module); - OpBuilder b(&getContext()); - - module->walk([&](Operation *op) { - if (!analysis.shouldInsertReduceNoise(op)) - return; - - b.setInsertionPointAfter(op); - auto reduceOp = b.create(op->getLoc(), op->getResult(0)); - op->getResult(0).replaceAllUsesExcept(reduceOp.getResult(), {reduceOp}); - }); - - // Use the int range analysis to confirm the noise is always below the - // maximum. - DataFlowSolver solver; - // The IntegerRangeAnalysis depends on DeadCodeAnalysis, but this - // dependence is not automatic and fails silently. - solver.load(); - solver.load(); - if (failed(solver.initializeAndRun(module))) { - getOperation()->emitOpError() << "Failed to run the analysis.\n"; - signalPassFailure(); - return; - } - - auto result = module->walk([&](Operation *op) { - if (!llvm::isa(*op)) { - return WalkResult::advance(); - } - const dataflow::IntegerValueRangeLattice *opRange = - solver.lookupState( - op->getResult(0)); - if (!opRange || opRange->getValue().isUninitialized()) { - op->emitOpError() - << "Found op without a set integer range; did the analysis fail?"; - return WalkResult::interrupt(); - } - - ConstantIntRanges range = opRange->getValue().getValue(); - if (range.umax().getZExtValue() > MAX_NOISE) { - op->emitOpError() << "Found op after which the noise exceeds the " - "allowable maximum of " - << MAX_NOISE - << "; it was: " << range.umax().getZExtValue() - << "\n"; - return WalkResult::interrupt(); - } - - return WalkResult::advance(); - }); - - if (result.wasInterrupted()) { - getOperation()->emitOpError() - << "Detected error in the noise analysis.\n"; - signalPassFailure(); - } - } -}; - -} // namespace noisy -} // namespace tutorial -} // namespace mlir diff --git a/lib/Transform/Noisy/ReduceNoiseOptimizer.h b/lib/Transform/Noisy/ReduceNoiseOptimizer.h deleted file mode 100644 index b3afd84..0000000 --- a/lib/Transform/Noisy/ReduceNoiseOptimizer.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef LIB_TRANSFORM_NOISY_REDUCENOISEOPTIMIZER_H_ -#define LIB_TRANSFORM_NOISY_REDUCENOISEOPTIMIZER_H_ - -#include "mlir/Pass/Pass.h" - -namespace mlir { -namespace tutorial { -namespace noisy { - -#define GEN_PASS_DECL_REDUCENOISEOPTIMIZER -#include "lib/Transform/Noisy/Passes.h.inc" - -} // namespace noisy -} // namespace tutorial -} // namespace mlir - -#endif // LIB_TRANSFORM_NOISY_REDUCENOISEOPTIMIZER_H_ diff --git a/tests/BUILD b/tests/BUILD index 4490c4a..d04f605 100644 --- a/tests/BUILD +++ b/tests/BUILD @@ -6,7 +6,6 @@ filegroup( testonly = True, data = [ "//tests:lit.cfg.py", - "//tests:poly_to_llvm_main.c", "//tools:tutorial-opt", "@llvm-project//clang:clang", "@llvm-project//llvm:FileCheck", diff --git a/tests/affine_loop_unroll.mlir b/tests/affine_loop_unroll.mlir deleted file mode 100644 index 7374f4e..0000000 --- a/tests/affine_loop_unroll.mlir +++ /dev/null @@ -1,34 +0,0 @@ -// RUN: tutorial-opt %s --affine-full-unroll > %t -// RUN: FileCheck %s < %t - -// RUN: tutorial-opt %s --affine-full-unroll-rewrite > %t -// RUN: FileCheck %s < %t - -func.func @test_single_nested_loop(%buffer: memref<4xi32>) -> (i32) { - %sum_0 = arith.constant 0 : i32 - // CHECK-LABEL: test_single_nested_loop - // CHECK-NOT: affine.for - %sum = affine.for %i = 0 to 4 iter_args(%sum_iter = %sum_0) -> i32 { - %t = affine.load %buffer[%i] : memref<4xi32> - %sum_next = arith.addi %sum_iter, %t : i32 - affine.yield %sum_next : i32 - } - return %sum : i32 -} - -func.func @test_doubly_nested_loop(%buffer: memref<4x3xi32>) -> (i32) { - %sum_0 = arith.constant 0 : i32 - // CHECK-LABEL: test_doubly_nested_loop - // CHECK-NOT: affine.for - %sum = affine.for %i = 0 to 4 iter_args(%sum_iter = %sum_0) -> i32 { - %sum_nested_0 = arith.constant 0 : i32 - %sum_nested = affine.for %j = 0 to 3 iter_args(%sum_nested_iter = %sum_nested_0) -> i32 { - %t = affine.load %buffer[%i, %j] : memref<4x3xi32> - %sum_nested_next = arith.addi %sum_nested_iter, %t : i32 - affine.yield %sum_nested_next : i32 - } - %sum_next = arith.addi %sum_iter, %sum_nested : i32 - affine.yield %sum_next : i32 - } - return %sum : i32 -} diff --git a/tests/code_motion.mlir b/tests/code_motion.mlir deleted file mode 100644 index 51004a3..0000000 --- a/tests/code_motion.mlir +++ /dev/null @@ -1,25 +0,0 @@ -// RUN: tutorial-opt %s --loop-invariant-code-motion > %t -// RUN: FileCheck %s < %t - -module { - // CHECK-LABEL: func.func @test_loop_invariant_code_motion - func.func @test_loop_invariant_code_motion() -> !poly.poly<10> { - %0 = arith.constant dense<[1, 2, 3]> : tensor<3xi32> - %p0 = poly.from_tensor %0 : tensor<3xi32> -> !poly.poly<10> - - %1 = arith.constant dense<[9, 8, 16]> : tensor<3xi32> - %p1 = poly.from_tensor %1 : tensor<3xi32> -> !poly.poly<10> - // CHECK: poly.mul - - // CHECK: affine.for - %ret_val = affine.for %i = 0 to 100 iter_args(%sum_iter = %p0) -> !poly.poly<10> { - // The poly.mul should be hoisted out of the loop. - // CHECK-NOT: poly.mul - %2 = poly.mul %p0, %p1 : !poly.poly<10> - %sum_next = poly.add %sum_iter, %2 : !poly.poly<10> - affine.yield %sum_next : !poly.poly<10> - } - - return %ret_val : !poly.poly<10> - } -} diff --git a/tests/control_flow_sink.mlir b/tests/control_flow_sink.mlir deleted file mode 100644 index d90fb68..0000000 --- a/tests/control_flow_sink.mlir +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: tutorial-opt -control-flow-sink %s | FileCheck %s - -// Test that operations can be sunk. - -// CHECK-LABEL: @test_simple_sink -func.func @test_simple_sink(%arg0: i1) -> !poly.poly<10> { - %0 = arith.constant dense<[1, 2, 3]> : tensor<3xi32> - %p0 = poly.from_tensor %0 : tensor<3xi32> -> !poly.poly<10> - %1 = arith.constant dense<[9, 8, 16]> : tensor<3xi32> - %p1 = poly.from_tensor %1 : tensor<3xi32> -> !poly.poly<10> - // CHECK-NOT: poly.from_tensor - // CHECK: scf.if - %4 = scf.if %arg0 -> (!poly.poly<10>) { - // CHECK: poly.from_tensor - %2 = poly.mul %p0, %p0 : !poly.poly<10> - scf.yield %2 : !poly.poly<10> - // CHECK: else - } else { - // CHECK: poly.from_tensor - %3 = poly.mul %p1, %p1 : !poly.poly<10> - scf.yield %3 : !poly.poly<10> - } - return %4 : !poly.poly<10> -} diff --git a/tests/cse.mlir b/tests/cse.mlir deleted file mode 100644 index 899e402..0000000 --- a/tests/cse.mlir +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: tutorial-opt -cse %s | FileCheck %s - -// CHECK-LABEL: @test_simple_cse -func.func @test_simple_cse() -> !poly.poly<10> { - %0 = arith.constant dense<[1, 2, 3]> : tensor<3xi32> - // CHECK: poly.from_tensor - %p0 = poly.from_tensor %0 : tensor<3xi32> -> !poly.poly<10> - // exactly one mul op - // CHECK-NEXT: poly.mul - // CHECK-NEXT: poly.add - %2 = poly.mul %p0, %p0 : !poly.poly<10> - %3 = poly.mul %p0, %p0 : !poly.poly<10> - %4 = poly.add %2, %3 : !poly.poly<10> - return %4 : !poly.poly<10> -} diff --git a/tests/ctlz.mlir b/tests/ctlz.mlir deleted file mode 100644 index 30a9f2d..0000000 --- a/tests/ctlz.mlir +++ /dev/null @@ -1,43 +0,0 @@ -// RUN: mlir-opt %s --convert-math-to-funcs=convert-ctlz | FileCheck %s - -func.func @main(%arg0: i32) { - %0 = math.ctlz %arg0 : i32 - func.return -} -// CHECK-LABEL: func.func @main( -// CHECK-SAME: %[[VAL_0:.*]]: i32 -// CHECK-SAME: ) { -// CHECK: %[[VAL_1:.*]] = call @__mlir_math_ctlz_i32(%[[VAL_0]]) : (i32) -> i32 -// CHECK: return -// CHECK: } - -// CHECK-LABEL: func.func private @__mlir_math_ctlz_i32( -// CHECK-SAME: %[[ARG:.*]]: i32 -// CHECK-SAME: ) -> i32 attributes {llvm.linkage = #llvm.linkage} { -// CHECK: %[[C_32:.*]] = arith.constant 32 : i32 -// CHECK: %[[C_0:.*]] = arith.constant 0 : i32 -// CHECK: %[[ARGCMP:.*]] = arith.cmpi eq, %[[ARG]], %[[C_0]] : i32 -// CHECK: %[[OUT:.*]] = scf.if %[[ARGCMP]] -> (i32) { -// CHECK: scf.yield %[[C_32]] : i32 -// CHECK: } else { -// CHECK: %[[C_1INDEX:.*]] = arith.constant 1 : index -// CHECK: %[[C_1I32:.*]] = arith.constant 1 : i32 -// CHECK: %[[C_32INDEX:.*]] = arith.constant 32 : index -// CHECK: %[[N:.*]] = arith.constant 0 : i32 -// CHECK: %[[FOR_RET:.*]]:2 = scf.for %[[I:.*]] = %[[C_1INDEX]] to %[[C_32INDEX]] step %[[C_1INDEX]] -// CHECK: iter_args(%[[ARG_ITER:.*]] = %[[ARG]], %[[N_ITER:.*]] = %[[N]]) -> (i32, i32) { -// CHECK: %[[COND:.*]] = arith.cmpi slt, %[[ARG_ITER]], %[[C_0]] : i32 -// CHECK: %[[IF_RET:.*]]:2 = scf.if %[[COND]] -> (i32, i32) { -// CHECK: scf.yield %[[ARG_ITER]], %[[N_ITER]] : i32, i32 -// CHECK: } else { -// CHECK: %[[N_NEXT:.*]] = arith.addi %[[N_ITER]], %[[C_1I32]] : i32 -// CHECK: %[[ARG_NEXT:.*]] = arith.shli %[[ARG_ITER]], %[[C_1I32]] : i32 -// CHECK: scf.yield %[[ARG_NEXT]], %[[N_NEXT]] : i32, i32 -// CHECK: } -// CHECK: scf.yield %[[IF_RET]]#0, %[[IF_RET]]#1 : i32, i32 -// CHECK: } -// CHECK: scf.yield %[[FOR_RET]]#1 : i32 -// CHECK: } -// CHECK: return %[[OUT]] : i32 -// CHECK: } -// NOCVT-NOT: __mlir_math_ctlz_i32 diff --git a/tests/ctlz_runner.mlir b/tests/ctlz_runner.mlir deleted file mode 100644 index d345c03..0000000 --- a/tests/ctlz_runner.mlir +++ /dev/null @@ -1,33 +0,0 @@ -// RUN: mlir-opt %s \ -// RUN: -pass-pipeline="builtin.module( \ -// RUN: convert-math-to-funcs{convert-ctlz}, \ -// RUN: func.func(convert-scf-to-cf,convert-arith-to-llvm), \ -// RUN: convert-func-to-llvm, \ -// RUN: convert-cf-to-llvm, \ -// RUN: reconcile-unrealized-casts)" \ -// RUN: | mlir-cpu-runner -e test_7i32_to_29 -entry-point-result=i32 > %t -// RUN: FileCheck %s --check-prefix=CHECK_TEST_7i32_TO_29 < %t - -func.func @test_7i32_to_29() -> i32 { - %arg = arith.constant 7 : i32 - %0 = math.ctlz %arg : i32 - func.return %0 : i32 -} -// CHECK_TEST_7i32_TO_29: 29 - - -// RUN: mlir-opt %s \ -// RUN: -pass-pipeline="builtin.module( \ -// RUN: convert-math-to-funcs{convert-ctlz}, \ -// RUN: func.func(convert-scf-to-cf,convert-arith-to-llvm), \ -// RUN: convert-func-to-llvm, \ -// RUN: convert-cf-to-llvm, \ -// RUN: reconcile-unrealized-casts)" \ -// RUN: | mlir-cpu-runner -e test_7i64_to_61 -entry-point-result=i64 > %t -// RUN: FileCheck %s --check-prefix=CHECK_TEST_7i64_TO_61 < %t -func.func @test_7i64_to_61() -> i64 { - %arg = arith.constant 7 : i64 - %0 = math.ctlz %arg : i64 - func.return %0 : i64 -} -// CHECK_TEST_7i64_TO_61: 61 diff --git a/tests/ctlz_simple.mlir b/tests/ctlz_simple.mlir deleted file mode 100644 index 2a9354f..0000000 --- a/tests/ctlz_simple.mlir +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: mlir-opt %s --convert-math-to-funcs=convert-ctlz | FileCheck %s - -func.func @main(%arg0: i32) -> i32 { - // CHECK-NOT: math.ctlz - // CHECK: call - %0 = math.ctlz %arg0 : i32 - func.return %0 : i32 -} diff --git a/tests/mul_to_add.mlir b/tests/mul_to_add.mlir deleted file mode 100644 index 1813003..0000000 --- a/tests/mul_to_add.mlir +++ /dev/null @@ -1,34 +0,0 @@ -// RUN: tutorial-opt %s --mul-to-add > %t -// RUN: FileCheck %s < %t - -func.func @just_power_of_two(%arg: i32) -> i32 { - %0 = arith.constant 8 : i32 - %1 = arith.muli %arg, %0 : i32 - func.return %1 : i32 -} - -// CHECK-LABEL: func.func @just_power_of_two( -// CHECK-SAME: %[[ARG:.*]]: i32 -// CHECK-SAME: ) -> i32 { -// CHECK: %[[SUM_0:.*]] = arith.addi %[[ARG]], %[[ARG]] -// CHECK: %[[SUM_1:.*]] = arith.addi %[[SUM_0]], %[[SUM_0]] -// CHECK: %[[SUM_2:.*]] = arith.addi %[[SUM_1]], %[[SUM_1]] -// CHECK: return %[[SUM_2]] : i32 -// CHECK: } - - -func.func @power_of_two_plus_one(%arg: i32) -> i32 { - %0 = arith.constant 9 : i32 - %1 = arith.muli %arg, %0 : i32 - func.return %1 : i32 -} - -// CHECK-LABEL: func.func @power_of_two_plus_one( -// CHECK-SAME: %[[ARG:.*]]: i32 -// CHECK-SAME: ) -> i32 { -// CHECK: %[[SUM_0:.*]] = arith.addi %[[ARG]], %[[ARG]] -// CHECK: %[[SUM_1:.*]] = arith.addi %[[SUM_0]], %[[SUM_0]] -// CHECK: %[[SUM_2:.*]] = arith.addi %[[SUM_1]], %[[SUM_1]] -// CHECK: %[[SUM_3:.*]] = arith.addi %[[SUM_2]], %[[ARG]] -// CHECK: return %[[SUM_3]] : i32 -// CHECK: } diff --git a/tests/mul_to_add_pdll.mlir b/tests/mul_to_add_pdll.mlir deleted file mode 100644 index e34a1e4..0000000 --- a/tests/mul_to_add_pdll.mlir +++ /dev/null @@ -1,33 +0,0 @@ -// RUN: tutorial-opt %s --mul-to-add-pdll | FileCheck %s - -func.func @just_power_of_two(%arg: i32) -> i32 { - %0 = arith.constant 8 : i32 - %1 = arith.muli %arg, %0 : i32 - func.return %1 : i32 -} - -// CHECK-LABEL: func.func @just_power_of_two( -// CHECK-SAME: %[[ARG:.*]]: i32 -// CHECK-SAME: ) -> i32 { -// CHECK: %[[SUM_0:.*]] = arith.addi %[[ARG]], %[[ARG]] -// CHECK: %[[SUM_1:.*]] = arith.addi %[[SUM_0]], %[[SUM_0]] -// CHECK: %[[SUM_2:.*]] = arith.addi %[[SUM_1]], %[[SUM_1]] -// CHECK: return %[[SUM_2]] : i32 -// CHECK: } - - -func.func @power_of_two_plus_one(%arg: i32) -> i32 { - %0 = arith.constant 9 : i32 - %1 = arith.muli %arg, %0 : i32 - func.return %1 : i32 -} - -// CHECK-LABEL: func.func @power_of_two_plus_one( -// CHECK-SAME: %[[ARG:.*]]: i32 -// CHECK-SAME: ) -> i32 { -// CHECK: %[[SUM_0:.*]] = arith.addi %[[ARG]], %[[ARG]] -// CHECK: %[[SUM_1:.*]] = arith.addi %[[SUM_0]], %[[SUM_0]] -// CHECK: %[[SUM_2:.*]] = arith.addi %[[SUM_1]], %[[SUM_1]] -// CHECK: %[[SUM_3:.*]] = arith.addi %[[SUM_2]], %[[ARG]] -// CHECK: return %[[SUM_3]] : i32 -// CHECK: } diff --git a/tests/noisy_reduce_noise.mlir b/tests/noisy_reduce_noise.mlir deleted file mode 100644 index bd30a0f..0000000 --- a/tests/noisy_reduce_noise.mlir +++ /dev/null @@ -1,160 +0,0 @@ -// RUN: tutorial-opt %s --noisy-reduce-noise-optimizer | FileCheck %s -// Check for syntax - -// CHECK-LABEL: test_insert_noise_reduction_ops_mul -// CHECK: [[V0:%.*]] = arith.constant 3 -// CHECK-NEXT: [[V1:%.*]] = arith.constant 4 -// CHECK-NEXT: [[V2:%.*]] = noisy.encode [[V0]] -// CHECK-NEXT: [[V3:%.*]] = noisy.encode [[V1]] -// CHECK-NEXT: [[V4:%.*]] = noisy.mul [[V2]], [[V3]] -// CHECK-NEXT: [[V4_R:%.*]] = noisy.reduce_noise [[V4]] -// CHECK-NEXT: [[V5:%.*]] = noisy.mul [[V4_R]], [[V4_R]] -// CHECK-NEXT: [[V5_R:%.*]] = noisy.reduce_noise [[V5]] -// CHECK-NEXT: [[V6:%.*]] = noisy.mul [[V5_R]], [[V5_R]] -// CHECK-NEXT: [[V6_R:%.*]] = noisy.reduce_noise [[V6]] -// This last mul does not need to be reduced -// CHECK-NEXT: [[V7:%.*]] = noisy.mul [[V6_R]], [[V6_R]] -// CHECK-NEXT: [[V8:%.*]] = noisy.decode [[V7]] -// CHECK-NEXT: return -func.func @test_insert_noise_reduction_ops_mul() -> i5 { - %0 = arith.constant 3 : i5 - %1 = arith.constant 4 : i5 - %2 = noisy.encode %0 : i5 -> !noisy.i32 - %3 = noisy.encode %1 : i5 -> !noisy.i32 - %4 = noisy.mul %2, %3 : !noisy.i32 - %5 = noisy.mul %4, %4 : !noisy.i32 - %6 = noisy.mul %5, %5 : !noisy.i32 - %7 = noisy.mul %6, %6 : !noisy.i32 - %8 = noisy.decode %7 : !noisy.i32 -> i5 - return %8 : i5 -} - -// CHECK-LABEL: test_insert_noise_reduction_ops_add_none_needed -// CHECK-NOT: noisy.reduce_noise -func.func @test_insert_noise_reduction_ops_add_none_needed() -> i5 { - %0 = arith.constant 3 : i5 - %1 = arith.constant 4 : i5 - %2 = noisy.encode %0 : i5 -> !noisy.i32 - %3 = noisy.encode %1 : i5 -> !noisy.i32 - %4 = noisy.add %2, %3 : !noisy.i32 - %5 = noisy.add %4, %4 : !noisy.i32 - %6 = noisy.add %5, %5 : !noisy.i32 - %7 = noisy.add %6, %6 : !noisy.i32 - %8 = noisy.decode %7 : !noisy.i32 -> i5 - return %8 : i5 -} - - -// CHECK-LABEL: test_add_after_mul -// CHECK: noisy.mul -// CHECK: noisy.reduce_noise -// CHECK: noisy.add -// CHECK: noisy.add -// CHECK: noisy.add -// CHECK: noisy.add -// CHECK: noisy.decode -// CHECK: return -func.func @test_add_after_mul() -> i5 { - %0 = arith.constant 3 : i5 - %1 = arith.constant 4 : i5 - %2 = noisy.encode %0 : i5 -> !noisy.i32 - %3 = noisy.encode %1 : i5 -> !noisy.i32 - // Noise: 12 - %4 = noisy.mul %2, %3 : !noisy.i32 - // Noise: 24 - %5 = noisy.add %4, %3 : !noisy.i32 - // Noise: 25 - %6 = noisy.add %5, %5 : !noisy.i32 - // Noise: 26 - %7 = noisy.add %6, %6 : !noisy.i32 - // Noise: 27 - %8 = noisy.add %7, %7 : !noisy.i32 - %9 = noisy.decode %8 : !noisy.i32 -> i5 - return %9 : i5 -} - -// This test checks that the solver can find a single insertion point -// for a reduce_noise op that handles two branches, each of which would -// also need a reduce_noise op if handled separately. -// CHECK-LABEL: test_single_insertion_branching -// CHECK: noisy.mul -// CHECK-NOT: noisy.add -// CHECK-COUNT-1: noisy.reduce_noise -// CHECK-NOT: noisy.reduce_noise -func.func @test_single_insertion_branching() -> i5 { - %0 = arith.constant 3 : i5 - %1 = arith.constant 4 : i5 - %2 = noisy.encode %0 : i5 -> !noisy.i32 - %3 = noisy.encode %1 : i5 -> !noisy.i32 - // Noise: 12 - %4 = noisy.mul %2, %3 : !noisy.i32 - // Noise: 24 - - // branch 1 - %b1 = noisy.add %4, %3 : !noisy.i32 - // Noise: 25 - %b2 = noisy.add %b1, %3 : !noisy.i32 - // Noise: 25 - %b3 = noisy.add %b2, %3 : !noisy.i32 - // Noise: 26 - %b4 = noisy.add %b3, %3 : !noisy.i32 - // Noise: 27 - - // branch 2 - %c1 = noisy.sub %4, %2 : !noisy.i32 - // Noise: 25 - %c2 = noisy.sub %c1, %3 : !noisy.i32 - // Noise: 25 - %c3 = noisy.sub %c2, %3 : !noisy.i32 - // Noise: 26 - %c4 = noisy.sub %c3, %3 : !noisy.i32 - // Noise: 27 - - %x1 = noisy.decode %b4 : !noisy.i32 -> i5 - %x2 = noisy.decode %c4 : !noisy.i32 -> i5 - %x3 = arith.addi %x1, %x2 : i5 - return %x3 : i5 -} - -// same as test_single_insertion_branching, but because the last two values -// are multiplied, we need two reduce_noise ops, one on each branch. -// CHECK-LABEL: test_double_insertion_branching -// CHECK: noisy.mul -// CHECK: noisy.add -// CHECK-COUNT-2: noisy.reduce_noise -// CHECK-NOT: noisy.reduce_noise -// CHECK: noisy.mul -func.func @test_double_insertion_branching() -> i5 { - %0 = arith.constant 3 : i5 - %1 = arith.constant 4 : i5 - %2 = noisy.encode %0 : i5 -> !noisy.i32 - %3 = noisy.encode %1 : i5 -> !noisy.i32 - // Noise: 12 - %4 = noisy.mul %2, %3 : !noisy.i32 - // Noise: 24 - - // branch 1 - %b1 = noisy.add %4, %3 : !noisy.i32 - // Noise: 25 - %b2 = noisy.add %b1, %3 : !noisy.i32 - // Noise: 25 - %b3 = noisy.add %b2, %3 : !noisy.i32 - // Noise: 26 - %b4 = noisy.add %b3, %3 : !noisy.i32 - // Noise: 27 - - // branch 2 - %c1 = noisy.add %4, %2 : !noisy.i32 - // Noise: 25 - %c2 = noisy.add %c1, %3 : !noisy.i32 - // Noise: 25 - %c3 = noisy.add %c2, %3 : !noisy.i32 - // Noise: 26 - %c4 = noisy.add %c3, %3 : !noisy.i32 - // Noise: 27 - - %exit = noisy.mul %b4, %c4 : !noisy.i32 - - %x1 = noisy.decode %exit : !noisy.i32 -> i5 - return %x1 : i5 -} diff --git a/tests/noisy_syntax.mlir b/tests/noisy_syntax.mlir deleted file mode 100644 index 04f6dc3..0000000 --- a/tests/noisy_syntax.mlir +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: tutorial-opt %s | FileCheck %s -// Check for syntax - -// CHECK-LABEL: test_op_syntax -func.func @test_op_syntax() { - %0 = arith.constant 3 : i5 - %1 = arith.constant 4 : i5 - %2 = noisy.encode %0 : i5 -> !noisy.i32 - %3 = noisy.encode %1 : i5 -> !noisy.i32 - %4 = noisy.add %2, %3 : !noisy.i32 - %5 = noisy.mul %4, %4 : !noisy.i32 - %6 = noisy.reduce_noise %5 : !noisy.i32 - %7 = noisy.decode %6 : !noisy.i32 -> i5 - return -} diff --git a/tests/poly_canonicalize.mlir b/tests/poly_canonicalize.mlir deleted file mode 100644 index a1c4cdf..0000000 --- a/tests/poly_canonicalize.mlir +++ /dev/null @@ -1,58 +0,0 @@ -// RUN: tutorial-opt --canonicalize %s | FileCheck %s - -// CHECK-LABEL: @test_simple -func.func @test_simple() -> !poly.poly<10> { - // CHECK: poly.constant dense<[2, 4, 6]> - // CHECK-NEXT: return - %0 = arith.constant dense<[1, 2, 3]> : tensor<3xi32> - %p0 = poly.from_tensor %0 : tensor<3xi32> -> !poly.poly<10> - %2 = poly.add %p0, %p0 : !poly.poly<10> - %3 = poly.mul %p0, %p0 : !poly.poly<10> - %4 = poly.add %2, %3 : !poly.poly<10> - return %2 : !poly.poly<10> -} - -// CHECK-LABEL: func.func @test_difference_of_squares -// CHECK-SAME: %[[x:.+]]: !poly.poly<3>, -// CHECK-SAME: %[[y:.+]]: !poly.poly<3> -func.func @test_difference_of_squares( - %0: !poly.poly<3>, %1: !poly.poly<3>) -> !poly.poly<3> { - // CHECK: %[[sum:.+]] = poly.add %[[x]], %[[y]] - // CHECK: %[[diff:.+]] = poly.sub %[[x]], %[[y]] - // CHECK: %[[mul:.+]] = poly.mul %[[sum]], %[[diff]] - %2 = poly.mul %0, %0 : !poly.poly<3> - %3 = poly.mul %1, %1 : !poly.poly<3> - %4 = poly.sub %2, %3 : !poly.poly<3> - %5 = poly.add %4, %4 : !poly.poly<3> - return %5 : !poly.poly<3> -} - -// CHECK-LABEL: func.func @test_difference_of_squares_other_uses -// CHECK-SAME: %[[x:.+]]: !poly.poly<3>, -// CHECK-SAME: %[[y:.+]]: !poly.poly<3> -func.func @test_difference_of_squares_other_uses( - %0: !poly.poly<3>, %1: !poly.poly<3>) -> !poly.poly<3> { - // The canonicalization does not occur because x_squared has a second use. - // CHECK: %[[x_squared:.+]] = poly.mul %[[x]], %[[x]] - // CHECK: %[[y_squared:.+]] = poly.mul %[[y]], %[[y]] - // CHECK: %[[diff:.+]] = poly.sub %[[x_squared]], %[[y_squared]] - // CHECK: %[[sum:.+]] = poly.add %[[diff]], %[[x_squared]] - %2 = poly.mul %0, %0 : !poly.poly<3> - %3 = poly.mul %1, %1 : !poly.poly<3> - %4 = poly.sub %2, %3 : !poly.poly<3> - %5 = poly.add %4, %2 : !poly.poly<3> - return %5 : !poly.poly<3> -} - -// CHECK-LABEL: func.func @test_normalize_conj_through_eval -// CHECK-SAME: %[[f:.+]]: !poly.poly<3>, -// CHECK-SAME: %[[z:.+]]: complex -func.func @test_normalize_conj_through_eval( - %f: !poly.poly<3>, %z: complex) -> complex { - // CHECK: %[[evaled:.+]] = poly.eval %[[f]], %[[z]] - // CHECK-NEXT: %[[eval_bar:.+]] = complex.conj %[[evaled]] - // CHECK-NEXT: return %[[eval_bar]] - %z_bar = complex.conj %z : complex - %evaled = poly.eval %f, %z_bar : (!poly.poly<3>, complex) -> complex - return %evaled : complex -} diff --git a/tests/poly_syntax.mlir b/tests/poly_syntax.mlir deleted file mode 100644 index 4b2e39b..0000000 --- a/tests/poly_syntax.mlir +++ /dev/null @@ -1,47 +0,0 @@ -// RUN: tutorial-opt %s > %t -// RUN FileCheck %s < %t - -module { - // CHECK-LABEL: test_type_syntax - func.func @test_type_syntax(%arg0: !poly.poly<10>) -> !poly.poly<10> { - // CHECK: poly.poly - return %arg0 : !poly.poly<10> - } - - // CHECK-LABEL: test_op_syntax - func.func @test_op_syntax(%arg0: !poly.poly<10>, %arg1: !poly.poly<10>) -> !poly.poly<10> { - // CHECK: poly.add - %0 = poly.add %arg0, %arg1 : !poly.poly<10> - // CHECK: poly.sub - %1 = poly.sub %arg0, %arg1 : !poly.poly<10> - // CHECK: poly.mul - %2 = poly.mul %arg0, %arg1 : !poly.poly<10> - - %3 = arith.constant dense<[1, 2, 3]> : tensor<3xi32> - // CHECK: poly.from_tensor - %4 = poly.from_tensor %3 : tensor<3xi32> -> !poly.poly<10> - - %5 = arith.constant 7 : i32 - // CHECK: poly.eval - %6 = poly.eval %4, %5 : (!poly.poly<10>, i32) -> i32 - - %z = complex.constant [1.0, 2.0] : complex - // CHECK: poly.eval - %complex_eval = poly.eval %4, %z : (!poly.poly<10>, complex) -> complex - - %7 = tensor.from_elements %arg0, %arg1 : tensor<2x!poly.poly<10>> - // CHECK: poly.add - %8 = poly.add %7, %7 : tensor<2x!poly.poly<10>> - - // CHECK: poly.constant - %10 = poly.constant dense<[2, 3, 4]> : tensor<3xi32> : !poly.poly<10> - %11 = poly.constant dense<[2, 3, 4]> : tensor<3xi8> : !poly.poly<10> - %12 = poly.constant dense<"0x020304"> : tensor<3xi8> : !poly.poly<10> - %13 = poly.constant dense<4> : tensor<100xi32> : !poly.poly<10> - - // CHECK: poly.to_tensor - %14 = poly.to_tensor %1 : !poly.poly<10> -> tensor<10xi32> - - return %4 : !poly.poly<10> - } -} diff --git a/tests/poly_to_llvm.mlir b/tests/poly_to_llvm.mlir deleted file mode 100644 index 894a352..0000000 --- a/tests/poly_to_llvm.mlir +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: tutorial-opt --poly-to-llvm %s | mlir-translate --mlir-to-llvmir | llc --relocation-model=pic -filetype=obj > %t -// RUN: clang -c %project_source_dir/tests/poly_to_llvm_main.c -// RUN: clang poly_to_llvm_main.o %t -o a.out -// RUN: ./a.out | FileCheck %s - -// CHECK: 351 -func.func @test_poly_fn(%arg : i32) -> i32 { - %tens = tensor.splat %arg : tensor<10xi32> - %input = poly.from_tensor %tens : tensor<10xi32> -> !poly.poly<10> - %0 = poly.constant dense<[2, 3, 4]> : tensor<3xi32> : !poly.poly<10> - %1 = poly.add %0, %input : !poly.poly<10> - %2 = poly.mul %1, %1 : !poly.poly<10> - %3 = poly.sub %2, %input : !poly.poly<10> - %4 = poly.eval %3, %arg: (!poly.poly<10>, i32) -> i32 - return %4 : i32 -} diff --git a/tests/poly_to_llvm_eval.mlir b/tests/poly_to_llvm_eval.mlir deleted file mode 100644 index 46dd61c..0000000 --- a/tests/poly_to_llvm_eval.mlir +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: tutorial-opt --poly-to-llvm %s | mlir-translate --mlir-to-llvmir | llc --relocation-model=pic -filetype=obj > %t -// RUN: clang -c %project_source_dir/tests/poly_to_llvm_main.c -// RUN: clang poly_to_llvm_main.o %t -o eval_test.out -// RUN: ./eval_test.out | FileCheck %s - -// CHECK: 9 -func.func @test_poly_fn(%arg : i32) -> i32 { - // 2 + 3x + 4x^2 evaluated at x=1, should be 2+3+4 - %input = poly.constant dense<[2, 3, 4]> : tensor<3xi32> : !poly.poly<3> - %0 = poly.eval %input, %arg: (!poly.poly<3>, i32) -> i32 - return %0 : i32 -} diff --git a/tests/poly_to_llvm_main.c b/tests/poly_to_llvm_main.c deleted file mode 100644 index 88202ea..0000000 --- a/tests/poly_to_llvm_main.c +++ /dev/null @@ -1,12 +0,0 @@ -#include - -// This is the function we want to call from LLVM -int test_poly_fn(int x); - -int main(int argc, char *argv[]) { - int i = 1; - int result = test_poly_fn(i); - printf("Result: %d\n", result); - - return 0; -} diff --git a/tests/poly_to_standard.mlir b/tests/poly_to_standard.mlir deleted file mode 100644 index f692527..0000000 --- a/tests/poly_to_standard.mlir +++ /dev/null @@ -1,112 +0,0 @@ -// RUN: tutorial-opt --poly-to-standard %s | FileCheck %s - -// CHECK-LABEL: test_lower_add -func.func @test_lower_add(%0 : !poly.poly<10>, %1 : !poly.poly<10>) -> !poly.poly<10> { - // CHECK: arith.addi - %2 = poly.add %0, %1: !poly.poly<10> - return %2 : !poly.poly<10> -} - -// CHECK-LABEL: test_lower_sub -func.func @test_lower_sub(%0 : !poly.poly<10>, %1 : !poly.poly<10>) -> !poly.poly<10> { - // CHECK: arith.subi - %2 = poly.sub %0, %1: !poly.poly<10> - return %2 : !poly.poly<10> -} - -// CHECK-LABEL: test_lower_to_tensor( -// CHECK-SAME: %[[V0:.*]]: [[T:tensor<10xi32>]]) -> [[T]] { -// CHECK-NEXT: return %[[V0]] : [[T]] -func.func @test_lower_to_tensor(%0: !poly.poly<10>) -> tensor<10xi32> { - %2 = poly.to_tensor %0: !poly.poly<10> -> tensor<10xi32> - return %2 : tensor<10xi32> -} - -// CHECK-LABEL: test_lower_from_tensor( -// CHECK-SAME: %[[V0:.*]]: [[T:tensor<10xi32>]]) -> [[T]] { -// CHECK-NEXT: return %[[V0]] : [[T]] -func.func @test_lower_from_tensor(%0 : tensor<10xi32>) -> !poly.poly<10> { - %2 = poly.from_tensor %0: tensor<10xi32> -> !poly.poly<10> - return %2 : !poly.poly<10> -} - -// CHECK-LABEL: test_lower_from_tensor_extend( -// CHECK-SAME: %[[V0:.*]]: [[T:tensor<10xi32>]]) -> [[T2:tensor<20xi32>]] { -// CHECK: %[[V1:.*]] = tensor.pad %[[V0]] low[0] high[10] -// CHECK: return %[[V1]] : [[T2]] -func.func @test_lower_from_tensor_extend(%0 : tensor<10xi32>) -> !poly.poly<20> { - %2 = poly.from_tensor %0: tensor<10xi32> -> !poly.poly<20> - return %2 : !poly.poly<20> -} - -// CHECK-LABEL: test_lower_add_and_fold -func.func @test_lower_add_and_fold() { - // CHECK: arith.constant dense<[2, 3, 4]> : tensor<3xi32> - %0 = poly.constant dense<[2, 3, 4]> : tensor<3xi32> : !poly.poly<10> - // CHECK: arith.constant dense<[3, 4, 5]> : tensor<3xi32> - %1 = poly.constant dense<[3, 4, 5]> : tensor<3xi32> : !poly.poly<10> - // would be an addi, but it was folded - // CHECK: arith.constant - %2 = poly.add %0, %1: !poly.poly<10> - return -} - -// CHECK-LABEL: test_lower_mul -// CHECK-SAME: (%[[p0:.*]]: [[T:tensor<10xi32>]], %[[p1:.*]]: [[T]]) -> [[T]] { -// CHECK: %[[cst:.*]] = arith.constant dense<0> : [[T]] -// CHECK: %[[c0:.*]] = arith.constant 0 : index -// CHECK: %[[c10:.*]] = arith.constant 10 : index -// CHECK: %[[c1:.*]] = arith.constant 1 : index -// CHECK: %[[outer:.*]] = scf.for %[[outer_iv:.*]] = %[[c0]] to %[[c10]] step %[[c1]] iter_args(%[[outer_iter_arg:.*]] = %[[cst]]) -> ([[T]]) { -// CHECK: %[[inner:.*]] = scf.for %[[inner_iv:.*]] = %[[c0]] to %[[c10]] step %[[c1]] iter_args(%[[inner_iter_arg:.*]] = %[[outer_iter_arg]]) -> ([[T]]) { -// CHECK: %[[index_sum:.*]] = arith.addi %arg2, %arg4 -// CHECK: %[[dest_index:.*]] = arith.remui %[[index_sum]], %[[c10]] -// CHECK-DAG: %[[p0_extracted:.*]] = tensor.extract %[[p0]][%[[outer_iv]]] -// CHECK-DAG: %[[p1_extracted:.*]] = tensor.extract %[[p1]][%[[inner_iv]]] -// CHECK: %[[coeff_mul:.*]] = arith.muli %[[p0_extracted]], %[[p1_extracted]] -// CHECK: %[[accum:.*]] = tensor.extract %[[inner_iter_arg]][%[[dest_index]]] -// CHECK: %[[to_insert:.*]] = arith.addi %[[coeff_mul]], %[[accum]] -// CHECK: %[[inserted:.*]] = tensor.insert %[[to_insert]] into %[[inner_iter_arg]][%[[dest_index]]] -// CHECK: scf.yield %[[inserted]] -// CHECK: } -// CHECK: scf.yield %[[inner]] -// CHECK: } -// CHECK: return %[[outer]] -// CHECK: } -func.func @test_lower_mul(%0 : !poly.poly<10>, %1 : !poly.poly<10>) -> !poly.poly<10> { - %2 = poly.mul %0, %1: !poly.poly<10> - return %2 : !poly.poly<10> -} - - -// CHECK-LABEL: test_lower_eval -// CHECK-SAME: (%[[poly:.*]]: [[T:tensor<10xi32>]], %[[point:.*]]: i32) -> i32 { -// CHECK: %[[c1:.*]] = arith.constant 1 : index -// CHECK: %[[c10:.*]] = arith.constant 10 : index -// CHECK: %[[c11:.*]] = arith.constant 11 : index -// CHECK: %[[accum:.*]] = arith.constant 0 : i32 -// CHECK: %[[loop:.*]] = scf.for %[[iv:.*]] = %[[c1]] to %[[c11]] step %[[c1]] iter_args(%[[iter_arg:.*]] = %[[accum]]) -> (i32) { -// CHECK: %[[coeffIndex:.*]] = arith.subi %[[c10]], %[[iv]] -// CHECK: %[[mulOp:.*]] = arith.muli %[[point]], %[[iter_arg]] -// CHECK: %[[nextCoeff:.*]] = tensor.extract %[[poly]][%[[coeffIndex]]] -// CHECK: %[[next:.*]] = arith.addi %[[mulOp]], %[[nextCoeff]] -// CHECK: scf.yield %[[next]] -// CHECK: } -// CHECK: return %[[loop]] -// CHECK: } -func.func @test_lower_eval(%0 : !poly.poly<10>, %1 : i32) -> i32 { - %2 = poly.eval %0, %1: (!poly.poly<10>, i32) -> i32 - return %2 : i32 -} - - -// CHECK-LABEL: test_lower_many -// CHECK-NOT: poly -func.func @test_lower_many(%arg : !poly.poly<10>, %point : i32) -> i32 { - %0 = poly.constant dense<[2, 3, 4]> : tensor<3xi32> : !poly.poly<10> - %1 = poly.add %0, %arg : !poly.poly<10> - %2 = poly.mul %1, %1 : !poly.poly<10> - %3 = poly.sub %2, %arg : !poly.poly<10> - %4 = poly.eval %3, %point: (!poly.poly<10>, i32) -> i32 - return %4 : i32 -} diff --git a/tests/poly_verifier.mlir b/tests/poly_verifier.mlir deleted file mode 100644 index fadca35..0000000 --- a/tests/poly_verifier.mlir +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: tutorial-opt %s 2>%t; FileCheck %s < %t - -func.func @test_invalid_evalop(%arg0: !poly.poly<10>, %cst: i64) -> i64 { - // This is a little brittle, since it matches both the error message - // emitted by Has32BitArguments as well as that of EvalOp::verify. - // I manually tested that they both fire when the input is as below. - // CHECK: to be a 32-bit integer - %0 = poly.eval %arg0, %cst : (!poly.poly<10>, i64) -> i64 - return %0 : i64 -} diff --git a/tests/sccp.mlir b/tests/sccp.mlir deleted file mode 100644 index 2243119..0000000 --- a/tests/sccp.mlir +++ /dev/null @@ -1,35 +0,0 @@ -// RUN: tutorial-opt -pass-pipeline="builtin.module(func.func(sccp))" %s | FileCheck %s - -// Note how sscp creates new constants for the computed values, -// though it does not remove the dead code. - -// CHECK-LABEL: @test_arith_sccp -// CHECK-NEXT: %[[v0:.*]] = arith.constant 63 : i32 -// CHECK-NEXT: %[[v1:.*]] = arith.constant 49 : i32 -// CHECK-NEXT: %[[v2:.*]] = arith.constant 14 : i32 -// CHECK-NEXT: %[[v3:.*]] = arith.constant 8 : i32 -// CHECK-NEXT: %[[v4:.*]] = arith.constant 7 : i32 -// CHECK-NEXT: return %[[v2]] : i32 -func.func @test_arith_sccp() -> i32 { - %0 = arith.constant 7 : i32 - %1 = arith.constant 8 : i32 - %2 = arith.addi %0, %0 : i32 - %3 = arith.muli %0, %0 : i32 - %4 = arith.addi %2, %3 : i32 - return %2 : i32 -} - -// CHECK-LABEL: @test_poly_sccp -func.func @test_poly_sccp() -> !poly.poly<10> { - %0 = arith.constant dense<[1, 2, 3]> : tensor<3xi32> - %p0 = poly.from_tensor %0 : tensor<3xi32> -> !poly.poly<10> - // CHECK: poly.constant dense<[2, 8, 20, 24, 18]> - // CHECK: poly.constant dense<[1, 4, 10, 12, 9]> - // CHECK: poly.constant dense<[1, 2, 3]> - // CHECK-NOT: poly.mul - // CHECK-NOT: poly.add - %2 = poly.mul %p0, %p0 : !poly.poly<10> - %3 = poly.mul %p0, %p0 : !poly.poly<10> - %4 = poly.add %2, %3 : !poly.poly<10> - return %2 : !poly.poly<10> -} diff --git a/tools/BUILD b/tools/BUILD index d4397b0..4d561ad 100644 --- a/tools/BUILD +++ b/tools/BUILD @@ -11,12 +11,7 @@ cc_binary( srcs = ["tutorial-opt.cpp"], includes = ["include"], deps = [ - "//lib/Conversion/PolyToStandard", - "//lib/Dialect/Noisy", - "//lib/Dialect/Poly", "//lib/Transform/Affine:Passes", - "//lib/Transform/Arith:Passes", - "//lib/Transform/Noisy:Passes", "@llvm-project//mlir:AllPassesAndDialects", "@llvm-project//mlir:ArithToLLVM", "@llvm-project//mlir:BufferizationPipelines", diff --git a/tools/tutorial-opt.cpp b/tools/tutorial-opt.cpp index 87f213d..7141986 100644 --- a/tools/tutorial-opt.cpp +++ b/tools/tutorial-opt.cpp @@ -1,9 +1,4 @@ -#include "lib/Conversion/PolyToStandard/PolyToStandard.h" -#include "lib/Dialect/Noisy/NoisyDialect.h" -#include "lib/Dialect/Poly/PolyDialect.h" #include "lib/Transform/Affine/Passes.h" -#include "lib/Transform/Arith/Passes.h" -#include "lib/Transform/Noisy/Passes.h" #include "mlir/include/mlir/Conversion/ArithToLLVM/ArithToLLVM.h" #include "mlir/include/mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h" #include "mlir/include/mlir/Conversion/FuncToLLVM/ConvertFuncToLLVMPass.h" @@ -19,60 +14,12 @@ #include "mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h" #include "mlir/include/mlir/Transforms/Passes.h" -void polyToLLVMPipelineBuilder(mlir::OpPassManager &manager) { - // Poly - manager.addPass(mlir::tutorial::poly::createPolyToStandard()); - manager.addPass(mlir::createCanonicalizerPass()); - - manager.addPass(mlir::createConvertElementwiseToLinalgPass()); - manager.addPass(mlir::createConvertTensorToLinalgPass()); - - // One-shot bufferize, from - // https://mlir.llvm.org/docs/Bufferization/#ownership-based-buffer-deallocation - mlir::bufferization::OneShotBufferizationOptions bufferizationOptions; - bufferizationOptions.bufferizeFunctionBoundaries = true; - manager.addPass( - mlir::bufferization::createOneShotBufferizePass(bufferizationOptions)); - mlir::bufferization::BufferDeallocationPipelineOptions deallocationOptions; - mlir::bufferization::buildBufferDeallocationPipeline(manager, - deallocationOptions); - - manager.addPass(mlir::createConvertLinalgToLoopsPass()); - - // Needed to lower memref.subview - manager.addPass(mlir::memref::createExpandStridedMetadataPass()); - - manager.addPass(mlir::createConvertSCFToCFPass()); - manager.addPass(mlir::createConvertControlFlowToLLVMPass()); - manager.addPass(mlir::createArithToLLVMConversionPass()); - manager.addPass(mlir::createConvertFuncToLLVMPass()); - manager.addPass(mlir::createFinalizeMemRefToLLVMConversionPass()); - manager.addPass(mlir::createReconcileUnrealizedCastsPass()); - - // Cleanup - manager.addPass(mlir::createCanonicalizerPass()); - manager.addPass(mlir::createSCCPPass()); - manager.addPass(mlir::createCSEPass()); - manager.addPass(mlir::createSymbolDCEPass()); -} - int main(int argc, char **argv) { mlir::DialectRegistry registry; - registry.insert(); - registry.insert(); mlir::registerAllDialects(registry); mlir::registerAllPasses(); mlir::tutorial::registerAffinePasses(); - mlir::tutorial::registerArithPasses(); - mlir::tutorial::noisy::registerNoisyPasses(); - - // Dialect conversion passes - mlir::tutorial::poly::registerPolyToStandardPasses(); - - mlir::PassPipelineRegistration<>( - "poly-to-llvm", "Run passes to lower the poly dialect to LLVM", - polyToLLVMPipelineBuilder); return mlir::asMainReturnCode( mlir::MlirOptMain(argc, argv, "Tutorial Pass Driver", registry));