diff --git a/mlir/include/mlir/Conversion/Normalize/Normalize.h b/mlir/include/mlir/Conversion/Normalize/Normalize.h new file mode 100644 index 0000000000000..650cfe734aeac --- /dev/null +++ b/mlir/include/mlir/Conversion/Normalize/Normalize.h @@ -0,0 +1,22 @@ +//===- Normalize.h - Conversion from MLIR to its canonical form -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_CONVERSION_NORMALIZE_NORMALIZE_H +#define MLIR_CONVERSION_NORMALIZE_NORMALIZE_H + +#include + +namespace mlir { +class Pass; + +#define GEN_PASS_DECL_NORMALIZE +#include "mlir/Conversion/Passes.h.inc" + +} // namespace mlir + +#endif // MLIR_CONVERSION_NORMALIZE_NORMALIZE_H diff --git a/mlir/include/mlir/Conversion/Passes.h b/mlir/include/mlir/Conversion/Passes.h index da061b269daf7..aa20e97bf31fe 100644 --- a/mlir/include/mlir/Conversion/Passes.h +++ b/mlir/include/mlir/Conversion/Passes.h @@ -54,6 +54,7 @@ #include "mlir/Conversion/MemRefToSPIRV/MemRefToSPIRVPass.h" #include "mlir/Conversion/NVGPUToNVVM/NVGPUToNVVM.h" #include "mlir/Conversion/NVVMToLLVM/NVVMToLLVM.h" +#include "mlir/Conversion/Normalize/Normalize.h" #include "mlir/Conversion/OpenACCToSCF/ConvertOpenACCToSCF.h" #include "mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h" #include "mlir/Conversion/PDLToPDLInterp/PDLToPDLInterp.h" diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td index 3c18ecc753d0f..d00b212053177 100644 --- a/mlir/include/mlir/Conversion/Passes.td +++ b/mlir/include/mlir/Conversion/Passes.td @@ -943,6 +943,24 @@ def ConvertShardToMPIPass : Pass<"convert-shard-to-mpi"> { ]; } +//===----------------------------------------------------------------------===// +// Normalize +//===----------------------------------------------------------------------===// +def Normalize : Pass<"normalize", "ModuleOp"> { + let summary = "normalize."; + let description = [{ + just normalize bro + }]; + let dependentDialects = [ + "arith::ArithDialect", + "cf::ControlFlowDialect", + "func::FuncDialect", + "scf::SCFDialect", + "vector::VectorDialect", + "LLVM::LLVMDialect", + ]; +} + //===----------------------------------------------------------------------===// // NVVMToLLVM //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Conversion/CMakeLists.txt b/mlir/lib/Conversion/CMakeLists.txt index 71986f83c4870..759e0a092e2d3 100644 --- a/mlir/lib/Conversion/CMakeLists.txt +++ b/mlir/lib/Conversion/CMakeLists.txt @@ -45,6 +45,7 @@ add_subdirectory(MemRefToLLVM) add_subdirectory(MemRefToSPIRV) add_subdirectory(ShardToMPI) add_subdirectory(MPIToLLVM) +add_subdirectory(Normalize) add_subdirectory(NVGPUToNVVM) add_subdirectory(NVVMToLLVM) add_subdirectory(OpenACCToSCF) diff --git a/mlir/lib/Conversion/Normalize/CMakeLists.txt b/mlir/lib/Conversion/Normalize/CMakeLists.txt new file mode 100644 index 0000000000000..a9944349714e3 --- /dev/null +++ b/mlir/lib/Conversion/Normalize/CMakeLists.txt @@ -0,0 +1,24 @@ +add_mlir_conversion_library(MLIRNormalize + Normalize.cpp + + ADDITIONAL_HEADER_DIRS + ${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/Normalize + + DEPENDS + MLIRConversionPassIncGen + + LINK_COMPONENTS + Core + + LINK_LIBS PUBLIC + MLIRArithDialect + MLIRControlFlowDialect + MLIRFuncDialect + MLIRLLVMDialect + MLIRMathDialect + MLIRPass + MLIRSCFDialect + MLIRTransforms + MLIRVectorDialect + MLIRVectorUtils +) diff --git a/mlir/lib/Conversion/Normalize/Normalize.cpp b/mlir/lib/Conversion/Normalize/Normalize.cpp new file mode 100644 index 0000000000000..9cab5b3bd7edf --- /dev/null +++ b/mlir/lib/Conversion/Normalize/Normalize.cpp @@ -0,0 +1,436 @@ +//===- Normalize.cpp - Conversion from MLIR to its canonical form ---------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "mlir/Conversion/Normalize/Normalize.h" + +#include "mlir/Dialect/Arith/IR/Arith.h" +#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h" +#include "mlir/Dialect/Func/IR/FuncOps.h" +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" +#include "mlir/Dialect/SCF/IR/SCF.h" +#include "mlir/Dialect/Vector/Utils/VectorUtils.h" +#include "mlir/IR/AsmState.h" +#include "mlir/IR/TypeUtilities.h" +#include "mlir/Pass/Pass.h" +#include "llvm/ADT/Hashing.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/raw_ostream.h" + +#include +#include + +namespace mlir { +#define GEN_PASS_DEF_NORMALIZE +#include "mlir/Conversion/Passes.h.inc" +} // namespace mlir + +using namespace mlir; + +#define DEBUG_TYPE "normalize" + +namespace { +struct NormalizePass : public impl::NormalizeBase { + NormalizePass() = default; + + void runOnOperation() override; + +private: + const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL; + void + collectOutputOperations(Block &block, + SmallVector &Output) const noexcept; + bool isOutput(mlir::Operation &op) const noexcept; + + void reorderOperations(const SmallVector &Outputs); + void + reorderOperation(mlir::Operation *used, mlir::Operation *user, + llvm::SmallPtrSet &visited); + + void renameOperations(const SmallVector &Outputs); + void RenameOperation(mlir::Operation *op, + SmallPtrSet &visited); + + bool isInitialOperation(mlir::Operation *const op) const noexcept; + void nameAsInitialOperation( + mlir::Operation *op, + llvm::SmallPtrSet &visited); + void nameAsRegularOperation( + mlir::Operation *op, + llvm::SmallPtrSet &visited); + bool hasOnlyImmediateOperands(mlir::Operation *const op) const noexcept; + llvm::SetVector getOutputFootprint( + mlir::Operation *op, + llvm::SmallPtrSet &visited) const; + void foldOperation(mlir::Operation *op); + void reorderOperationOperandsByName(mlir::Operation *op); + mlir::OpPrintingFlags flags{}; +}; +} // namespace + +void NormalizePass::runOnOperation() { + flags.printNameLocAsPrefix(true); + + ModuleOp module = getOperation(); + + for (auto &op : module.getOps()) { + SmallVector Outputs; + + for (auto ®ion : op.getRegions()) + for (auto &block : region) + collectOutputOperations(block, Outputs); + + reorderOperations(Outputs); + renameOperations(Outputs); + } +} + +void NormalizePass::renameOperations( + const SmallVector &Outputs) { + llvm::SmallPtrSet visited; + + for (auto *op : Outputs) + RenameOperation(op, visited); +} + +void NormalizePass::RenameOperation( + Operation *op, SmallPtrSet &visited) { + if (!visited.count(op)) { + visited.insert(op); + + if (isInitialOperation(op)) { + nameAsInitialOperation(op, visited); + } else { + nameAsRegularOperation(op, visited); + } + foldOperation(op); + reorderOperationOperandsByName(op); + } +} + +bool NormalizePass::isInitialOperation( + mlir::Operation *const op) const noexcept { + return !op->use_empty() and hasOnlyImmediateOperands(op); +} + +bool NormalizePass::hasOnlyImmediateOperands( + mlir::Operation *const op) const noexcept { + for (mlir::Value operand : op->getOperands()) + if (mlir::Operation *defOp = operand.getDefiningOp()) + if (!(defOp->hasTrait())) + return false; + return true; +} + +std::string inline to_string(uint64_t const hash) noexcept { + std::ostringstream oss; + oss << std::hex << std::setw(5) << std::setfill('0') << hash; + std::string tmp = oss.str(); + return tmp.size() > 5 ? tmp.substr(tmp.size() - 5, 5) : tmp; +} + +uint64_t inline strHash(std::string_view data) noexcept { + const static uint64_t FNV_OFFSET = 0xcbf29ce484222325ULL; + const static uint64_t FNV_PRIME = 0x100000001b3ULL; + uint64_t hash = FNV_OFFSET; + for (const auto &c : data) { + hash ^= static_cast(c); + hash *= FNV_PRIME; + } + return hash; +} + +std::string inline split(std::string_view str, const char &delimiter, + int indx = 0) noexcept { + std::stringstream ss{std::string{str}}; + std::string item; + int cnt = 0; + while (std::getline(ss, item, delimiter)) { + if (cnt == indx) { + std::replace(item.begin(), item.end(), ':', '_'); + return item; + } else { + cnt++; + } + } + return nullptr; +} + +void NormalizePass::nameAsInitialOperation( + mlir::Operation *op, + llvm::SmallPtrSet &visited) { + + for (mlir::Value operand : op->getOperands()) + if (mlir::Operation *defOp = operand.getDefiningOp()) + RenameOperation(defOp, visited); + + uint64_t Hash = MagicHashConstant; + + uint64_t opcodeHash = strHash(op->getName().getStringRef().str()); + Hash = llvm::hashing::detail::hash_16_bytes(Hash, opcodeHash); + + SmallPtrSet Visited; + SetVector OutputFootprint = getOutputFootprint(op, Visited); + + for (const int &Output : OutputFootprint) + Hash = llvm::hashing::detail::hash_16_bytes(Hash, Output); + + std::string Name{""}; + Name.append("vl" + std::to_string(Hash).substr(0, 5)); + + if (auto call = mlir::dyn_cast(op)) { + llvm::StringRef callee = call.getCallee(); + Name.append(callee.str()); + } + + if (op->getNumOperands() == 0) { + Name.append("$"); + if (auto call = mlir::dyn_cast(op)) { + Name.append("void"); + } else { + std::string TextRepresentation; + mlir::AsmState state(op, flags); + llvm::raw_string_ostream Stream(TextRepresentation); + op->print(Stream, state); + std::string hash = to_string(strHash(split(Stream.str(), '=', 1))); + Name.append(hash); + } + Name.append("$"); + } + + mlir::OpBuilder b(op->getContext()); + mlir::StringAttr sat = b.getStringAttr(Name); + mlir::Location newLoc = mlir::NameLoc::get(sat, op->getLoc()); + op->setLoc(newLoc); +} + +void NormalizePass::nameAsRegularOperation( + mlir::Operation *op, + llvm::SmallPtrSet &visited) { + + for (mlir::Value operand : op->getOperands()) + if (mlir::Operation *defOp = operand.getDefiningOp()) + RenameOperation(defOp, visited); + + uint64_t Hash = MagicHashConstant; + + uint64_t opcodeHash = strHash(op->getName().getStringRef().str()); + Hash = llvm::hashing::detail::hash_16_bytes(Hash, opcodeHash); + + SmallVector OperandsOpcodes; + + for (mlir::Value operand : op->getOperands()) + if (mlir::Operation *defOp = operand.getDefiningOp()) + OperandsOpcodes.push_back(strHash(defOp->getName().getStringRef().str())); + + if (op->hasTrait()) + llvm::sort(OperandsOpcodes.begin(), OperandsOpcodes.end()); + + for (const uint64_t Code : OperandsOpcodes) + Hash = llvm::hashing::detail::hash_16_bytes(Hash, Code); + + SmallString<512> Name; + Name.append("op" + std::to_string(Hash).substr(0, 5)); + + if (auto call = mlir::dyn_cast(op)) { + llvm::StringRef callee = call.getCallee(); + Name.append(callee.str()); + } + + mlir::OpBuilder b(op->getContext()); + mlir::StringAttr sat = b.getStringAttr(Name); + mlir::Location newLoc = mlir::NameLoc::get(sat, op->getLoc()); + op->setLoc(newLoc); +} + +bool inline starts_with(std::string_view base, + std::string_view check) noexcept { + return base.size() >= check.size() && + std::equal(check.begin(), check.end(), base.begin()); +} + +void NormalizePass::foldOperation(mlir::Operation *op) { + if (isOutput(*op) || op->getNumOperands() == 0) + return; + + std::string TextRepresentation; + mlir::AsmState state(op, flags); + llvm::raw_string_ostream Stream(TextRepresentation); + op->print(Stream, state); + + auto opName = split(Stream.str(), '=', 0); + if (!starts_with(opName, "%op") && !starts_with(opName, "%vl")) + return; + + SmallVector Operands; + + for (mlir::Value operand : op->getOperands()) { + if (mlir::Operation *defOp = operand.getDefiningOp()) { + std::string TextRepresentation; + mlir::AsmState state(defOp, flags); + llvm::raw_string_ostream Stream(TextRepresentation); + defOp->print(Stream, state); + auto name = split(Stream.str(), '=', 0); + + bool hasNormalName = + (starts_with(name, "%op") || starts_with(name, "%vl")); + + if (hasNormalName) { + Operands.push_back(name.substr(1, 7)); + } else { + Operands.push_back(name); + } + } else if (auto ba = dyn_cast(operand)) { + mlir::Block *ownerBlock = ba.getOwner(); + unsigned argIndex = ba.getArgNumber(); + if (auto func = dyn_cast(ownerBlock->getParentOp())) { + if (&func.front() == ownerBlock) { + Operands.push_back(std::string("funcArg" + std::to_string(argIndex))); + } else { + Operands.push_back( + std::string("blockArg" + std::to_string(argIndex))); + } + } else { + Operands.push_back(std::string("blockArg" + std::to_string(argIndex))); + } + } + } + + if (op->hasTrait()) + llvm::sort(Operands.begin(), Operands.end()); + + SmallString<512> Name; + Name.append(opName.substr(1, 7)); + + Name.append("$"); + for (unsigned long i = 0; i < Operands.size(); ++i) { + Name.append(Operands[i]); + + if (i < Operands.size() - 1) + Name.append("-"); + } + Name.append("$"); + + mlir::OpBuilder b(op->getContext()); + mlir::StringAttr sat = b.getStringAttr(Name); + mlir::Location newLoc = mlir::NameLoc::get(sat, op->getLoc()); + op->setLoc(newLoc); +} + +void NormalizePass::reorderOperationOperandsByName(mlir::Operation *op) { + if (op->getNumOperands() == 0) + return; + + SmallVector, 4> Operands; + + for (mlir::Value operand : op->getOperands()) { + std::string TextRepresentation; + llvm::raw_string_ostream Stream(TextRepresentation); + operand.printAsOperand(Stream, flags); + Operands.push_back({Stream.str(), operand}); + } + + if (op->hasTrait()) { + llvm::sort( + Operands.begin(), Operands.end(), [](const auto &a, const auto &b) { + return llvm::StringRef(a.first).compare_insensitive(b.first) < 0; + }); + } + + for (size_t i = 0; i < Operands.size(); i++) { + op->setOperand(i, Operands[i].second); + } +} + +void NormalizePass::reorderOperations( + const SmallVector &Outputs) { + llvm::SmallPtrSet visited; + for (auto *const op : Outputs) + for (mlir::Value operand : op->getOperands()) + if (mlir::Operation *defOp = operand.getDefiningOp()) + reorderOperation(defOp, op, visited); +} + +void NormalizePass::reorderOperation( + mlir::Operation *used, mlir::Operation *user, + llvm::SmallPtrSet &visited) { + if (!visited.count(used)) { + visited.insert(used); + + mlir::Block *usedBlock = used->getBlock(); + mlir::Block *userBlock = user->getBlock(); + + if (usedBlock == userBlock) + used->moveBefore(user); + else + used->moveBefore(&usedBlock->back()); + + for (mlir::Value operand : used->getOperands()) + if (mlir::Operation *defOp = operand.getDefiningOp()) + reorderOperation(defOp, used, visited); + } +} + +void NormalizePass::collectOutputOperations( + Block &block, SmallVector &Outputs) const noexcept { + for (auto &innerOp : block) + if (isOutput(innerOp)) + Outputs.emplace_back(&innerOp); +} + +bool NormalizePass::isOutput(Operation &op) const noexcept { + if (op.hasTrait()) + return true; + + if (auto memOp = dyn_cast(&op)) { + SmallVector effects; + memOp.getEffects(effects); + for (auto &effect : effects) + if (isa(effect.getEffect())) + return true; + } + + if (auto call = mlir::dyn_cast(op)) + return true; + + return false; +} + +llvm::SetVector NormalizePass::getOutputFootprint( + mlir::Operation *op, + llvm::SmallPtrSet &visited) const { + llvm::SetVector Outputs; + if (!visited.count(op)) { + visited.insert(op); + + if (isOutput(*op)) { + mlir::func::FuncOp func = op->getParentOfType(); + + unsigned Count = 0; + for (Block &block : func.getRegion()) + for (mlir::Operation &innerOp : block) { + if (&innerOp == op) + Outputs.insert(Count); + Count++; + } + + return Outputs; + } + + for (mlir::OpOperand &use : op->getUses()) { + mlir::Operation *useOp = use.getOwner(); + if (useOp) { + llvm::SetVector OutputsUsingUop = + getOutputFootprint(useOp, visited); + + Outputs.insert(OutputsUsingUop.begin(), OutputsUsingUop.end()); + } + } + } + + return Outputs; +} diff --git a/mlir/test/Conversion/Normalize/infinite-loop.mlir b/mlir/test/Conversion/Normalize/infinite-loop.mlir new file mode 100644 index 0000000000000..2ec50853046b2 --- /dev/null +++ b/mlir/test/Conversion/Normalize/infinite-loop.mlir @@ -0,0 +1,203 @@ +// RUN: mlir-opt %s --normalize --mlir-use-nameloc-as-prefix 2>&1 | FileCheck %s + +// CHECK-LABEL: module { +// CHECK: func.func @infinte_loop(%[[ARG0:.*]]: memref, %[[ARG1:.*]]: i32) { +// CHECK: %vl15969$e5677$ = arith.constant 1 : i32 +// CHECK: %vl15390$funcArg1-vl15969$ = arith.addi %[[ARG1:.*]], %vl15969$e5677$ : i32 +// CHECK: cf.br ^bb1(%vl15390$funcArg1-vl15969$, %vl15390$funcArg1-vl15969$ : i32, i32) +// CHECK: ^bb1(%[[VAL_0:.*]]: i32, %[[VAL_1:.*]]: i32): // 2 preds: ^bb0, ^bb1 +// CHECK: %vl22288$20b04$ = arith.constant 0 : i32 +// CHECK: %vl13736$blockArg0-vl22288$ = arith.muli %[[VAL_0:.*]], %vl22288$20b04$ : i32 +// CHECK: %vl22288$ded78$ = arith.constant -1 : i32 +// CHECK: %op51214$vl13736-vl22288$ = arith.xori %vl13736$blockArg0-vl22288$, %vl22288$ded78$ : i32 +// CHECK: %op12693$blockArg0-op51214$ = arith.addi %[[VAL_0:.*]], %op51214$vl13736-vl22288$ : i32 +// CHECK: %vl15894$blockArg1-vl22288$ = arith.addi %[[VAL_1:.*]], %vl22288$ded78$ : i32 +// CHECK: %op15672$op12693-vl15894$ = arith.addi %op12693$blockArg0-op51214$, %vl15894$blockArg1-vl22288$ : i32 +// CHECK: %op97825$op15672-vl13736$ = arith.muli %op15672$op12693-vl15894$, %vl13736$blockArg0-vl22288$ : i32 +// CHECK: %op51214$op97825-vl22288$ = arith.xori %op97825$op15672-vl13736$, %vl22288$ded78$ : i32 +// CHECK: %op12343$op15672-op51214$ = arith.addi %op15672$op12693-vl15894$, %op51214$op97825-vl22288$ : i32 +// CHECK: %op27844$op12343-vl22288$ = arith.addi %op12343$op15672-op51214$, %vl22288$20b04$ : i32 +// CHECK: %op97825$op27844-op97825$ = arith.muli %op27844$op12343-vl22288$, %op97825$op15672-vl13736$ : i32 +// CHECK: %op51214$op97825-vl22288$_0 = arith.xori %op97825$op27844-op97825$, %vl22288$ded78$ : i32 +// CHECK: %op12343$op27844-op51214$ = arith.addi %op27844$op12343-vl22288$, %op51214$op97825-vl22288$_0 : i32 +// CHECK: %op27844$op12343-vl22288$_1 = arith.addi %op12343$op27844-op51214$, %vl22288$20b04$ : i32 +// CHECK: %op27844$op27844-vl22288$ = arith.addi %op27844$op12343-vl22288$_1, %vl22288$20b04$ : i32 +// CHECK: %op27844$op27844-vl22288$_2 = arith.addi %op27844$op27844-vl22288$, %vl22288$20b04$ : i32 +// CHECK: %op97825$op27844-op97825$_3 = arith.muli %op27844$op12343-vl22288$_1, %op97825$op27844-op97825$ : i32 +// CHECK: %op97825$op27844-op97825$_4 = arith.muli %op27844$op27844-vl22288$_2, %op97825$op27844-op97825$_3 : i32 +// CHECK: %op51214$op97825-vl22288$_5 = arith.xori %op97825$op27844-op97825$_4, %vl22288$ded78$ : i32 +// CHECK: %op12343$op27844-op51214$_6 = arith.addi %op27844$op27844-vl22288$_2, %op51214$op97825-vl22288$_5 : i32 +// CHECK: %op27844$op12343-vl22288$_7 = arith.addi %op12343$op27844-op51214$_6, %vl22288$20b04$ : i32 +// CHECK: %op97825$op27844-op97825$_8 = arith.muli %op27844$op12343-vl22288$_7, %op97825$op27844-op97825$_4 : i32 +// CHECK: %op51214$op97825-vl22288$_9 = arith.xori %op97825$op27844-op97825$_8, %vl22288$ded78$ : i32 +// CHECK: %op12343$op27844-op51214$_10 = arith.addi %op27844$op12343-vl22288$_7, %op51214$op97825-vl22288$_9 : i32 +// CHECK: %op27844$op12343-vl22288$_11 = arith.addi %op12343$op27844-op51214$_10, %vl22288$20b04$ : i32 +// CHECK: %op97825$op27844-op97825$_12 = arith.muli %op27844$op12343-vl22288$_11, %op97825$op27844-op97825$_8 : i32 +// CHECK: %op51214$op97825-vl22288$_13 = arith.xori %op97825$op27844-op97825$_12, %vl22288$ded78$ : i32 +// CHECK: %op12343$op27844-op51214$_14 = arith.addi %op27844$op12343-vl22288$_11, %op51214$op97825-vl22288$_13 : i32 +// CHECK: %op27844$op12343-vl22288$_15 = arith.addi %op12343$op27844-op51214$_14, %vl22288$20b04$ : i32 +// CHECK: %op97825$op27844-op97825$_16 = arith.muli %op27844$op12343-vl22288$_15, %op97825$op27844-op97825$_12 : i32 +// CHECK: %op51214$op97825-vl22288$_17 = arith.xori %op97825$op27844-op97825$_16, %vl22288$ded78$ : i32 +// CHECK: %op12343$op27844-op51214$_18 = arith.addi %op27844$op12343-vl22288$_15, %op51214$op97825-vl22288$_17 : i32 +// CHECK: %op27844$op12343-vl22288$_19 = arith.addi %op12343$op27844-op51214$_18, %vl22288$20b04$ : i32 +// CHECK: %op97825$op27844-op97825$_20 = arith.muli %op27844$op12343-vl22288$_19, %op97825$op27844-op97825$_16 : i32 +// CHECK: %op51214$op97825-vl22288$_21 = arith.xori %op97825$op27844-op97825$_20, %vl22288$ded78$ : i32 +// CHECK: %op12343$op27844-op51214$_22 = arith.addi %op27844$op12343-vl22288$_19, %op51214$op97825-vl22288$_21 : i32 +// CHECK: %vl22288$51850$ = arith.constant -9 : i32 +// CHECK: %vl15894$blockArg1-vl22288$_23 = arith.addi %[[VAL_1:.*]], %vl22288$51850$ : i32 +// CHECK: %op15672$op12343-vl15894$ = arith.addi %op12343$op27844-op51214$_22, %vl15894$blockArg1-vl22288$_23 : i32 +// CHECK: %op97825$op15672-op97825$ = arith.muli %op15672$op12343-vl15894$, %op97825$op27844-op97825$_20 : i32 +// CHECK: %op51214$op97825-vl22288$_24 = arith.xori %op97825$op15672-op97825$, %vl22288$ded78$ : i32 +// CHECK: %op12343$op15672-op51214$_25 = arith.addi %op15672$op12343-vl15894$, %op51214$op97825-vl22288$_24 : i32 +// CHECK: %op27844$op12343-vl22288$_26 = arith.addi %op12343$op15672-op51214$_25, %vl22288$20b04$ : i32 +// CHECK: %op97825$op27844-op97825$_27 = arith.muli %op27844$op12343-vl22288$_26, %op97825$op15672-op97825$ : i32 +// CHECK: %op51214$op97825-vl22288$_28 = arith.xori %op97825$op27844-op97825$_27, %vl22288$ded78$ : i32 +// CHECK: %op12343$op27844-op51214$_29 = arith.addi %op27844$op12343-vl22288$_26, %op51214$op97825-vl22288$_28 : i32 +// CHECK: %op27844$op12343-vl22288$_30 = arith.addi %op12343$op27844-op51214$_29, %vl22288$20b04$ : i32 +// CHECK: %op97825$op27844-op97825$_31 = arith.muli %op27844$op12343-vl22288$_30, %op97825$op27844-op97825$_27 : i32 +// CHECK: %op51214$op97825-vl22288$_32 = arith.xori %op97825$op27844-op97825$_31, %vl22288$ded78$ : i32 +// CHECK: %op12343$op27844-op51214$_33 = arith.addi %op27844$op12343-vl22288$_30, %op51214$op97825-vl22288$_32 : i32 +// CHECK: %op27844$op12343-vl22288$_34 = arith.addi %op12343$op27844-op51214$_33, %vl22288$20b04$ : i32 +// CHECK: %op97825$op27844-op97825$_35 = arith.muli %op27844$op12343-vl22288$_34, %op97825$op27844-op97825$_31 : i32 +// CHECK: %op51214$op97825-vl22288$_36 = arith.xori %op97825$op27844-op97825$_35, %vl22288$ded78$ : i32 +// CHECK: %op12343$op27844-op51214$_37 = arith.addi %op27844$op12343-vl22288$_34, %op51214$op97825-vl22288$_36 : i32 +// CHECK: %op27844$op12343-vl22288$_38 = arith.addi %op12343$op27844-op51214$_37, %vl22288$20b04$ : i32 +// CHECK: %op97825$op27844-op97825$_39 = arith.muli %op27844$op12343-vl22288$_38, %op97825$op27844-op97825$_35 : i32 +// CHECK: %op51214$op97825-vl22288$_40 = arith.xori %op97825$op27844-op97825$_39, %vl22288$ded78$ : i32 +// CHECK: %op12343$op27844-op51214$_41 = arith.addi %op27844$op12343-vl22288$_38, %op51214$op97825-vl22288$_40 : i32 +// CHECK: %vl22288$7b7de$ = arith.constant -14 : i32 +// CHECK: %vl15894$blockArg1-vl22288$_42 = arith.addi %[[VAL_1:.*]], %vl22288$7b7de$ : i32 +// CHECK: %op15672$op12343-vl15894$_43 = arith.addi %op12343$op27844-op51214$_41, %vl15894$blockArg1-vl22288$_42 : i32 +// CHECK: %op97825$op15672-op97825$_44 = arith.muli %op15672$op12343-vl15894$_43, %op97825$op27844-op97825$_39 : i32 +// CHECK: %op51214$op97825-vl22288$_45 = arith.xori %op97825$op15672-op97825$_44, %vl22288$ded78$ : i32 +// CHECK: %op12343$op15672-op51214$_46 = arith.addi %op15672$op12343-vl15894$_43, %op51214$op97825-vl22288$_45 : i32 +// CHECK: %op27844$op12343-vl22288$_47 = arith.addi %op12343$op15672-op51214$_46, %vl22288$20b04$ : i32 +// CHECK: %op97825$op27844-op97825$_48 = arith.muli %op27844$op12343-vl22288$_47, %op97825$op15672-op97825$_44 : i32 +// CHECK: %op51214$op97825-vl22288$_49 = arith.xori %op97825$op27844-op97825$_48, %vl22288$ded78$ : i32 +// CHECK: %op12343$op27844-op51214$_50 = arith.addi %op27844$op12343-vl22288$_47, %op51214$op97825-vl22288$_49 : i32 +// CHECK: %op27844$op12343-vl22288$_51 = arith.addi %op12343$op27844-op51214$_50, %vl22288$20b04$ : i32 +// CHECK: %op97825$op27844-op97825$_52 = arith.muli %op27844$op12343-vl22288$_51, %op97825$op27844-op97825$_48 : i32 +// CHECK: %op51214$op97825-vl22288$_53 = arith.xori %op97825$op27844-op97825$_52, %vl22288$ded78$ : i32 +// CHECK: %op12343$op27844-op51214$_54 = arith.addi %op27844$op12343-vl22288$_51, %op51214$op97825-vl22288$_53 : i32 +// CHECK: %op27844$op12343-vl22288$_55 = arith.addi %op12343$op27844-op51214$_54, %vl22288$20b04$ : i32 +// CHECK: %op97825$op27844-op97825$_56 = arith.muli %op27844$op12343-vl22288$_55, %op97825$op27844-op97825$_52 : i32 +// CHECK: %op51214$op97825-vl22288$_57 = arith.xori %op97825$op27844-op97825$_56, %vl22288$ded78$ : i32 +// CHECK: %op12343$op27844-op51214$_58 = arith.addi %op27844$op12343-vl22288$_55, %op51214$op97825-vl22288$_57 : i32 +// CHECK: %op27844$op12343-vl22288$_59 = arith.addi %op12343$op27844-op51214$_58, %vl22288$20b04$ : i32 +// CHECK: %op97825$op27844-op97825$_60 = arith.muli %op27844$op12343-vl22288$_59, %op97825$op27844-op97825$_56 : i32 +// CHECK: %op51214$op97825-vl22288$_61 = arith.xori %op97825$op27844-op97825$_60, %vl22288$ded78$ : i32 +// CHECK: %op12343$op27844-op51214$_62 = arith.addi %op27844$op12343-vl22288$_59, %op51214$op97825-vl22288$_61 : i32 +// CHECK: %op27844$op12343-vl22288$_63 = arith.addi %op12343$op27844-op51214$_62, %vl22288$20b04$ : i32 +// CHECK: %op97825$op27844-op97825$_64 = arith.muli %op27844$op12343-vl22288$_63, %op97825$op27844-op97825$_60 : i32 +// CHECK: %op51214$op97825-vl22288$_65 = arith.xori %op97825$op27844-op97825$_64, %vl22288$ded78$ : i32 +// CHECK: %op12343$op27844-op51214$_66 = arith.addi %op27844$op12343-vl22288$_63, %op51214$op97825-vl22288$_65 : i32 +// CHECK: %op27844$op12343-vl22288$_67 = arith.addi %op12343$op27844-op51214$_66, %vl22288$20b04$ : i32 +// CHECK: %op27844$op27844-vl22288$_68 = arith.addi %op27844$op12343-vl22288$_67, %vl22288$20b04$ : i32 +// CHECK: %vl22288$1e72e$ = arith.constant -21 : i32 +// CHECK: %vl15894$blockArg1-vl22288$_69 = arith.addi %[[VAL_1:.*]], %vl22288$1e72e$ : i32 +// CHECK: %op15672$op27844-vl15894$ = arith.addi %op27844$op27844-vl22288$_68, %vl15894$blockArg1-vl22288$_69 : i32 +// CHECK: %vl48856$e527e$ = arith.constant 0 : index +// CHECK: memref.store %op15672$op27844-vl15894$, %[[ARG0:.*]][%vl48856$e527e$] : memref +// CHECK: cf.br ^bb1(%op15672$op27844-vl15894$, %vl15894$blockArg1-vl22288$_69 : i32, i32) +// CHECK: } +// CHECK: } +func.func @infinte_loop(%arg0: memref, %arg1: i32) { + %c1 = arith.constant 1 : i32 + %a = arith.addi %arg1, %c1 : i32 + cf.br ^bb1(%a, %a : i32, i32) + + ^bb1(%tmp: i32, %tmp2: i32): + %c0 = arith.constant 0 : i32 + %tmp3 = arith.muli %tmp, %c0 : i32 + %cneg1 = arith.constant -1 : i32 + %tmp4 = arith.xori %tmp3, %cneg1 : i32 + %tmp5 = arith.addi %tmp, %tmp4 : i32 + %tmp6 = arith.addi %tmp2, %cneg1 : i32 + %tmp7 = arith.addi %tmp5, %tmp6 : i32 + %tmp8 = arith.muli %tmp7, %tmp3 : i32 + %tmp9 = arith.xori %tmp8, %cneg1 : i32 + %tmp10 = arith.addi %tmp7, %tmp9 : i32 + %tmp11 = arith.addi %tmp10, %c0 : i32 + %tmp12 = arith.muli %tmp11, %tmp8 : i32 + %tmp13 = arith.xori %tmp12, %cneg1 : i32 + %tmp14 = arith.addi %tmp11, %tmp13 : i32 + %tmp15 = arith.addi %tmp14, %c0 : i32 + %tmp16 = arith.muli %tmp15, %tmp12 : i32 + %tmp17 = arith.addi %tmp15, %c0 : i32 + %tmp18 = arith.addi %tmp17, %c0 : i32 + %tmp19 = arith.muli %tmp18, %tmp16 : i32 + %tmp20 = arith.xori %tmp19, %cneg1 : i32 + %tmp21 = arith.addi %tmp18, %tmp20 : i32 + %tmp22 = arith.addi %tmp21, %c0 : i32 + %tmp23 = arith.muli %tmp22, %tmp19 : i32 + %tmp24 = arith.xori %tmp23, %cneg1 : i32 + %tmp25 = arith.addi %tmp22, %tmp24 : i32 + %tmp26 = arith.addi %tmp25, %c0 : i32 + %tmp27 = arith.muli %tmp26, %tmp23 : i32 + %tmp28 = arith.xori %tmp27, %cneg1 : i32 + %tmp29 = arith.addi %tmp26, %tmp28 : i32 + %tmp30 = arith.addi %tmp29, %c0 : i32 + %tmp31 = arith.muli %tmp30, %tmp27 : i32 + %tmp32 = arith.xori %tmp31, %cneg1 : i32 + %tmp33 = arith.addi %tmp30, %tmp32 : i32 + %tmp34 = arith.addi %tmp33, %c0 : i32 + %tmp35 = arith.muli %tmp34, %tmp31 : i32 + %tmp36 = arith.xori %tmp35, %cneg1 : i32 + %tmp37 = arith.addi %tmp34, %tmp36 : i32 + %cneg9 = arith.constant -9 : i32 + %tmp38 = arith.addi %tmp2, %cneg9 : i32 + %tmp39 = arith.addi %tmp37, %tmp38 : i32 + %tmp40 = arith.muli %tmp39, %tmp35 : i32 + %tmp41 = arith.xori %tmp40, %cneg1 : i32 + %tmp42 = arith.addi %tmp39, %tmp41 : i32 + %tmp43 = arith.addi %tmp42, %c0 : i32 + %tmp44 = arith.muli %tmp43, %tmp40 : i32 + %tmp45 = arith.xori %tmp44, %cneg1 : i32 + %tmp46 = arith.addi %tmp43, %tmp45 : i32 + %tmp47 = arith.addi %tmp46, %c0 : i32 + %tmp48 = arith.muli %tmp47, %tmp44 : i32 + %tmp49 = arith.xori %tmp48, %cneg1 : i32 + %tmp50 = arith.addi %tmp47, %tmp49 : i32 + %tmp51 = arith.addi %tmp50, %c0 : i32 + %tmp52 = arith.muli %tmp51, %tmp48 : i32 + %tmp53 = arith.xori %tmp52, %cneg1 : i32 + %tmp54 = arith.addi %tmp51, %tmp53 : i32 + %tmp55 = arith.addi %tmp54, %c0 : i32 + %tmp56 = arith.muli %tmp55, %tmp52 : i32 + %tmp57 = arith.xori %tmp56, %cneg1 : i32 + %tmp58 = arith.addi %tmp55, %tmp57 : i32 + %cneg14 = arith.constant -14 : i32 + %tmp59 = arith.addi %tmp2, %cneg14 : i32 + %tmp60 = arith.addi %tmp58, %tmp59 : i32 + %tmp61 = arith.muli %tmp60, %tmp56 : i32 + %tmp62 = arith.xori %tmp61, %cneg1 : i32 + %tmp63 = arith.addi %tmp60, %tmp62 : i32 + %tmp64 = arith.addi %tmp63, %c0 : i32 + %tmp65 = arith.muli %tmp64, %tmp61 : i32 + %tmp66 = arith.xori %tmp65, %cneg1 : i32 + %tmp67 = arith.addi %tmp64, %tmp66 : i32 + %tmp68 = arith.addi %tmp67, %c0 : i32 + %tmp69 = arith.muli %tmp68, %tmp65 : i32 + %tmp70 = arith.xori %tmp69, %cneg1 : i32 + %tmp71 = arith.addi %tmp68, %tmp70 : i32 + %tmp72 = arith.addi %tmp71, %c0 : i32 + %tmp73 = arith.muli %tmp72, %tmp69 : i32 + %tmp74 = arith.xori %tmp73, %cneg1 : i32 + %tmp75 = arith.addi %tmp72, %tmp74 : i32 + %tmp76 = arith.addi %tmp75, %c0 : i32 + %tmp77 = arith.muli %tmp76, %tmp73 : i32 + %tmp78 = arith.xori %tmp77, %cneg1 : i32 + %tmp79 = arith.addi %tmp76, %tmp78 : i32 + %tmp80 = arith.addi %tmp79, %c0 : i32 + %tmp81 = arith.muli %tmp80, %tmp77 : i32 + %tmp82 = arith.xori %tmp81, %cneg1 : i32 + %tmp83 = arith.addi %tmp80, %tmp82 : i32 + %tmp84 = arith.addi %tmp83, %c0 : i32 + %tmp85 = arith.addi %tmp84, %c0 : i32 + %cneg21 = arith.constant -21 : i32 + %tmp86 = arith.addi %tmp2, %cneg21 : i32 + %tmp87 = arith.addi %tmp85, %tmp86 : i32 + %c0_idx = arith.constant 0 : index + memref.store %tmp87, %arg0[%c0_idx] : memref + cf.br ^bb1(%tmp87, %tmp86 : i32, i32) +} diff --git a/mlir/test/Conversion/Normalize/reorder.mlir b/mlir/test/Conversion/Normalize/reorder.mlir new file mode 100644 index 0000000000000..aa698a5ae04d2 --- /dev/null +++ b/mlir/test/Conversion/Normalize/reorder.mlir @@ -0,0 +1,21 @@ +// RUN: mlir-opt %s --normalize --mlir-use-nameloc-as-prefix 2>&1 | FileCheck %s + +// CHECK-LABEL: func.func @reorder( +// CHECK-SAME: %[[ARG0:.*]]: i32) -> i32 { +// CHECK: %vl14084$51356$ = arith.constant 2 : i32 +// CHECK: %vl15831$funcArg0-vl14084$ = arith.addi %[[ARG0]], %vl14084$51356$ : i32 +// CHECK: %vl14084$187c2$ = arith.constant 6 : i32 +// CHECK: %op27844$vl14084-vl15831$ = arith.addi %vl14084$187c2$, %vl15831$funcArg0-vl14084$ : i32 +// CHECK: %vl14084$4c6ac$ = arith.constant 8 : i32 +// CHECK: %op27844$op27844-vl14084$ = arith.addi %op27844$vl14084-vl15831$, %vl14084$4c6ac$ : i32 +// CHECK: return %op27844$op27844-vl14084$ : i32 +// CHECK: } +func.func @reorder(%a0: i32) -> i32 { + %c2 = arith.constant 2 : i32 + %c6 = arith.constant 6 : i32 + %c8 = arith.constant 8 : i32 + %a = arith.addi %a0, %c2 : i32 + %b = arith.addi %a, %c6 : i32 + %c = arith.addi %b, %c8 : i32 + func.return %c : i32 +} diff --git a/mlir/test/Conversion/Normalize/usedef.mlir b/mlir/test/Conversion/Normalize/usedef.mlir new file mode 100644 index 0000000000000..2af5e55d64787 --- /dev/null +++ b/mlir/test/Conversion/Normalize/usedef.mlir @@ -0,0 +1,35 @@ +// RUN: mlir-opt %s --normalize --mlir-use-nameloc-as-prefix 2>&1 | FileCheck %s + +// CHECK-LABEL: func.func @use_def( +// CHECK-SAME: %arg0: i32) -> i32 { +// CHECK: %vl36495$eafb0$ = arith.constant 4 : i32 +// CHECK: %vl43392$funcArg0-vl36495$ = arith.addi %arg0, %vl36495$eafb0$ : i32 +// CHECK: %vl36495$20b04$ = arith.constant 0 : i32 +// CHECK: %op27844$vl36495-vl43392$ = arith.addi %vl36495$20b04$, %vl43392$funcArg0-vl36495$ : i32 +// CHECK: %op27844$op27844-vl36495$ = arith.addi %op27844$vl36495-vl43392$, %vl36495$eafb0$ : i32 +// CHECK: %op15672$op27844-op27844$ = arith.addi %op27844$op27844-vl36495$, %op27844$vl36495-vl43392$ : i32 +// CHECK: %op15672$op15672-op27844$ = arith.addi %op15672$op27844-op27844$, %op27844$op27844-vl36495$ : i32 +// CHECK: %op15672$op15672-op15672$ = arith.addi %op15672$op15672-op27844$, %op15672$op27844-op27844$ : i32 +// CHECK: %op15672$op15672-op15672$_0 = arith.addi %op15672$op15672-op15672$, %op15672$op15672-op27844$ : i32 +// CHECK: %op15672$op15672-op15672$_1 = arith.addi %op15672$op15672-op15672$, %op15672$op15672-op15672$_0 : i32 +// CHECK: %op15672$op15672-op15672$_2 = arith.addi %op15672$op15672-op15672$, %op15672$op15672-op15672$_1 : i32 +// CHECK: %op15672$op15672-op15672$_3 = arith.addi %op15672$op15672-op15672$_1, %op15672$op15672-op15672$_2 : i32 +// CHECK: return %op15672$op15672-op15672$_3 : i32 +// CHECK: } +module { + func.func @use_def(%arg0: i32) -> i32 { + %c0 = arith.constant 4 : i32 + %t = arith.addi %arg0, %c0 : i32 + %zero = arith.constant 0 : i32 + %t2 = arith.addi %t, %zero : i32 + %t3 = arith.addi %t2, %c0 : i32 + %t4 = arith.addi %t3, %t2 : i32 + %t5 = arith.addi %t4, %t3 : i32 + %t6 = arith.addi %t5, %t4 : i32 + %t7 = arith.addi %t6, %t5 : i32 + %t8 = arith.addi %t7, %t6 : i32 + %t9 = arith.addi %t8, %t6 : i32 + %t10 = arith.addi %t9, %t8 : i32 + return %t10 : i32 + } +}