diff --git a/compiler/include/byteir/Dialect/Byre/Passes.h b/compiler/include/byteir/Dialect/Byre/Passes.h index aa6fb03ec..c384e38ab 100644 --- a/compiler/include/byteir/Dialect/Byre/Passes.h +++ b/compiler/include/byteir/Dialect/Byre/Passes.h @@ -18,7 +18,6 @@ #ifndef BYTEIR_DIALECT_BYRE_PASSES_H #define BYTEIR_DIALECT_BYRE_PASSES_H -#include "byteir/Dialect/Byre/Transforms/Fold.h" #include "byteir/Dialect/Byre/Transforms/Serial.h" namespace mlir { diff --git a/compiler/include/byteir/Dialect/Byre/Passes.td b/compiler/include/byteir/Dialect/Byre/Passes.td index 7c1569be4..6347b60fe 100644 --- a/compiler/include/byteir/Dialect/Byre/Passes.td +++ b/compiler/include/byteir/Dialect/Byre/Passes.td @@ -21,15 +21,6 @@ include "mlir/Pass/PassBase.td" -//===----------------------------------------------------------------------===// -// ByreFold -//===----------------------------------------------------------------------===// - -def ByreFold : Pass<"byre-fold", "func::FuncOp"> { - let summary = "Fold Byre Ops"; - let constructor = "mlir::createByreFoldPass()"; -} - //===----------------------------------------------------------------------===// // DumpByre //===----------------------------------------------------------------------===// diff --git a/compiler/include/byteir/Dialect/Byre/Transforms/Fold.h b/compiler/include/byteir/Dialect/Byre/Transforms/Fold.h deleted file mode 100644 index 4c439872d..000000000 --- a/compiler/include/byteir/Dialect/Byre/Transforms/Fold.h +++ /dev/null @@ -1,33 +0,0 @@ -//===- Fold.h -------------------------------------------------*--- C++ -*-===// -// -// Copyright 2022 ByteDance Ltd. and/or its affiliates. All rights reserved. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -//===----------------------------------------------------------------------===// - -#ifndef BYTEIR_DIALECT_BYRE_TRANSFORMS_FOLD_H -#define BYTEIR_DIALECT_BYRE_TRANSFORMS_FOLD_H - -#include "mlir/Pass/Pass.h" -#include - -namespace mlir { -namespace func { -class FuncOp; -} // namespace func - -std::unique_ptr> createByreFoldPass(); - -} // namespace mlir - -#endif // BYTEIR_DIALECT_BYRE_TRANSFORMS_FOLD_H \ No newline at end of file diff --git a/compiler/lib/Dialect/Byre/CMakeLists.txt b/compiler/lib/Dialect/Byre/CMakeLists.txt index c6f6af240..f79814214 100644 --- a/compiler/lib/Dialect/Byre/CMakeLists.txt +++ b/compiler/lib/Dialect/Byre/CMakeLists.txt @@ -39,7 +39,6 @@ add_mlir_dialect_library(MLIRByreSerialization add_mlir_dialect_library(ByteIRByrePasses Transforms/BufferizableOpInterfaceImpl.cpp - Transforms/Fold.cpp Transforms/Serial.cpp ADDITIONAL_HEADER_DIRS diff --git a/compiler/lib/Dialect/Byre/IR/ByreDialect.cpp b/compiler/lib/Dialect/Byre/IR/ByreDialect.cpp index f43b56bd3..36f7cd348 100644 --- a/compiler/lib/Dialect/Byre/IR/ByreDialect.cpp +++ b/compiler/lib/Dialect/Byre/IR/ByreDialect.cpp @@ -459,6 +459,10 @@ struct CollapseAliasChain : public OpRewritePattern { cast(sourceOp.getSource().getType()).getElementType()); auto curElemBitwidth = canonicalizeTypeBitWidth( cast(aliasOp.getSource().getType()).getElementType()); + + if (aliasOp.getOffset() * curElemBitwidth % srcElemBitwidth != 0) { + return failure(); + } auto newOffset = aliasOp.getOffset() * curElemBitwidth / srcElemBitwidth + sourceOp.getOffset(); rewriter.replaceOpWithNewOp(aliasOp, diff --git a/compiler/lib/Dialect/Byre/Transforms/Fold.cpp b/compiler/lib/Dialect/Byre/Transforms/Fold.cpp deleted file mode 100644 index e1fe5c5f9..000000000 --- a/compiler/lib/Dialect/Byre/Transforms/Fold.cpp +++ /dev/null @@ -1,166 +0,0 @@ -//===- Fold.cpp -----------------------------------------------*--- C++ -*-===// -// -// Copyright 2022 ByteDance Ltd. and/or its affiliates. All rights reserved. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -//===----------------------------------------------------------------------===// - -#include "byteir/Dialect/Byre/Transforms/Fold.h" - -#include "byteir/Analysis/Alias.h" -#include "byteir/Dialect/Byre/ByreDialect.h" -#include "byteir/Dialect/Byre/Common.h" -#include "mlir/Dialect/Func/IR/FuncOps.h" -#include "mlir/IR/Builders.h" -#include "llvm/ADT/EquivalenceClasses.h" -#include - -#include "PassDetail.h" - -using namespace byteir; -using namespace llvm; -using namespace mlir; -using namespace mlir::byre; - -namespace { - -struct ByreAliasAnalysis : public AliasAnalysis { - ByreAliasAnalysis(mlir::Block *b, llvm::ArrayRef initials, - std::function checkAlias) - : AliasAnalysis(b, initials, checkAlias) { - offsets.resize(values.size(), 0); - } - - int getOrCreateIndex(mlir::Value val) override { - if (valueToIndex.count(val) == 0) { - int count = values.size(); - valueToIndex[val] = count; - values.push_back(val); - leaderToIndex.insert(count); - offsets.push_back(0); - } - return valueToIndex[val]; - } - - void runOnBlock() override { - if (block->empty()) - return; - - for (auto &op : block->without_terminator()) { - if (isAlias(op)) { - int in_idx = getOrCreateIndex(op.getOperand(0)); - int in_leader = leaderToIndex.getLeaderValue(in_idx); - int out_idx = getOrCreateIndex(op.getOperand(1)); - int out_leader = leaderToIndex.getLeaderValue(out_idx); - - if (in_leader <= out_idx) { - leaderToIndex.unionSets(in_leader, out_leader); - } else { - leaderToIndex.unionSets(out_leader, in_leader); - } - - int in_offset = offsets[in_idx]; - int op_offset = op.getAttrOfType("offset").getInt(); - int out_offset = in_offset + op_offset; - offsets[out_idx] = out_offset; - } - } - } - - // track offset - SmallVector offsets; -}; - -static bool isAliasOp(Operation &op) { - if (auto compute_op = dyn_cast(op)) { - return compute_op.getCallee() == "AliasOp"; - } - return false; -}; - -static void foldAlias(func::FuncOp func) { - auto ctx = func.getContext(); - // use all args as initials for alias - SmallVector initialCopy; - for (auto val : func.getArguments()) { - initialCopy.push_back(val); - } - - auto &funcBlock = func.getBody().front(); - ByreAliasAnalysis byreAlias(&funcBlock, initialCopy, isAliasOp); - byreAlias.runOnBlock(); - - SmallVector remove_ops; - - for (auto computeOp : func.getOps()) { - if (computeOp.getCallee() == "AliasOp") { - auto inVal = computeOp.getOperand(0); - int inIdx = byreAlias.getOrCreateIndex(inVal); - - int leaderIdx = byreAlias.leaderToIndex.getLeaderValue(inIdx); - if (leaderIdx != inIdx) { - auto leaderVal = byreAlias.values[leaderIdx]; - // override operand and attr - auto outVal = computeOp.getOperand(1); - int outIdx = byreAlias.getOrCreateIndex(outVal); - auto offset = byreAlias.offsets[outIdx]; - computeOp.setOperand(0, leaderVal); - computeOp->setAttr("offset", - IntegerAttr::get(IntegerType::get(ctx, 32), offset)); - - if (leaderVal.getDefiningOp() == nullptr) { - computeOp->setAttr("arg_alias", UnitAttr::get(ctx)); - } - } - } - } - - for (auto computeOp : func.getOps()) { - if (computeOp.getCallee() == "AliasOp") { - auto inVal = computeOp.getOperand(0); - auto outVal = computeOp.getOperand(1); - if (inVal.getType() == outVal.getType() && - computeOp->getAttrOfType("offset").getInt() == 0) { - outVal.replaceAllUsesExcept(inVal, computeOp); - } - } - } - - for (auto op : func.getOps()) { - if (op.getCallee() == "AliasOp") { - auto value = op->getOperand(1); - if (value.hasOneUse()) { - remove_ops.emplace_back(op); - } - } - }; - - for (auto op : remove_ops) { - op->erase(); - } -} - -struct ByreHoldPass : public ByreFoldBase { - - ByreHoldPass() : ByreFoldBase() {} - - void runOnOperation() override { - func::FuncOp func = getOperation(); - foldAlias(func); - } -}; -} // namespace - -std::unique_ptr> mlir::createByreFoldPass() { - return std::make_unique(); -} diff --git a/compiler/python/version.txt b/compiler/python/version.txt index 36497cb44..84311494f 100644 --- a/compiler/python/version.txt +++ b/compiler/python/version.txt @@ -1 +1 @@ -1.9.0.0 \ No newline at end of file +1.9.1.0 \ No newline at end of file diff --git a/compiler/test/Dialect/Byre/byreFold.mlir b/compiler/test/Dialect/Byre/byreFold.mlir deleted file mode 100644 index 920666f6e..000000000 --- a/compiler/test/Dialect/Byre/byreFold.mlir +++ /dev/null @@ -1,45 +0,0 @@ -// RUN: byteir-opt -byre-fold %s | FileCheck %s - -module attributes {byre.container_module} { - func.func @fold_alias(%arg0: memref<512xf32> {byre.argtype = 1: i32, byre.argname = "A"}, %arg1: memref<512xf32> {byre.argtype = 2: i32, byre.argname = "B"}) attributes {byre.entry_point} { -// CHECK-LABEL: func.func @fold_alias - %0 = memref.alloc() : memref<256xf32> - %1 = memref.alloc() : memref<128xf32> - %2 = memref.alloc() : memref<256xf32> - %3 = memref.alloc() : memref<128xf32> - %4 = memref.alloc() : memref<512xf32> - %5 = memref.alloc() : memref<256xf32> - %6 = memref.alloc() : memref<128xf32> - %7 = memref.alloc() : memref<512xf32> - byre.compute @AliasOp(%arg0, %0) {arg_alias, offset = 128 : i32} : memref<512xf32>, memref<256xf32> - byre.compute @AliasOp(%0, %1) {offset = 32 : i32} : memref<256xf32>, memref<128xf32> -// CHECK: byre.compute @AliasOp(%arg0, %alloc_0) {arg_alias, offset = 160 : i32} - byre.compute @AliasOp(%arg1, %2) {arg_alias, offset = 128 : i32} : memref<512xf32>, memref<256xf32> - byre.compute @AliasOp(%2, %3) {offset = 32 : i32} : memref<256xf32>, memref<128xf32> -// CHECK: byre.compute @AliasOp(%arg1, %alloc_2) {arg_alias, offset = 160 : i32} - byre.compute @AliasOp(%4, %5) {offset = 128 : i32} : memref<512xf32>, memref<256xf32> - byre.compute @AliasOp(%5, %6) {offset = 32 : i32} : memref<256xf32>, memref<128xf32> -// CHECK: byre.compute @AliasOp(%alloc_3, %alloc_5) {offset = 160 : i32} - byre.compute @SomeOp(%1, %3, %6) : memref<128xf32>, memref<128xf32>, memref<128xf32> - return - } - - func.func @fold_identity_alias(%arg0: memref<256xf32> {byre.argtype = 1: i32, byre.argname = "A"}, %arg1: memref<256xf32> {byre.argtype = 2: i32, byre.argname = "B"}) attributes {byre.entry_point} { -// CHECK-LBAEL: func.func @fold_identity_alias - %0 = memref.alloc() : memref<256xf32> - byre.compute @AliasOp(%arg0, %0) {arg_alias, offset = 0 : i32} : memref<256xf32>, memref<256xf32> - byre.compute @SomeOp(%0, %arg1) : memref<256xf32>, memref<256xf32> -// CHECK: byre.compute @SomeOp(%arg0, %arg1) - return - } - - func.func @remove_unused_alias(%arg0: memref<256xf32> {byre.argtype = 1: i32, byre.argname = "A"}, %arg1: memref<256xf32> {byre.argtype = 2: i32, byre.argname = "B"}) attributes {byre.entry_point} { -// CHECK-LABEL: func.func @remove_unused_alias - %0 = memref.alloc() : memref<128xf32> - byre.compute @AliasOp(%arg0, %0) {arg_alias, offset = 128 : i32} : memref<256xf32>, memref<128xf32> - byre.compute @SomeOp(%arg0, %arg1) : memref<256xf32>, memref<256xf32> -// CHECK-NOT: byre.compute @AliasOp -// CHECK: byre.compute @SomeOp(%arg0, %arg1) - return - } -} diff --git a/compiler/test/Dialect/Byre/canonicalize.mlir b/compiler/test/Dialect/Byre/canonicalize.mlir index 2dc6a26ab..131f92598 100644 --- a/compiler/test/Dialect/Byre/canonicalize.mlir +++ b/compiler/test/Dialect/Byre/canonicalize.mlir @@ -44,10 +44,23 @@ module attributes {byre.container_module} { // CHECK-LABEL: func.func @remove_identity_alias %0 = "byre.alias"(%arg0) {offset = 0 : i64} : (memref<256xf32>) -> memref<256xf32> byre.compute @SomeOp(%0, %arg1) : memref<256xf32>, memref<256xf32> +// CHECK-NOT: byre.alias // CHECK-NEXT: byre.compute @SomeOp(%arg0, %arg1) return } + func.func @not_fold_alias(%arg0: memref<256xf32> {byre.argtype = 1: i32, byre.argname = "A"}) attributes {byre.entry_point} { +// CHECK-LABEL: func.func @not_fold_alias + %0 = "byre.alias"(%arg0) {offset = 0 : i64} : (memref<256xf32>) -> memref<256xi8> + %1 = "byre.alias"(%0) {offset = 3 : i64} : (memref<256xi8>) -> memref<253xi8> + byre.compute @SomeOp(%1) : memref<253xi8> +// CHECK-NEXT: byre.alias +// CHECK-NEXT: byre.alias +// CHECK-NEXT: byre.compute @SomeOp +// CHECK-NEXT: return + return + } + func.func @test_group_copy(%arg0 : memref<100x?xf32> {byre.argtype = 1: i32, byre.argname = "A"}, %arg1 : memref<100x?xf32> {byre.argtype = 2: i32, byre.argname = "B"}, %arg2 : memref<200x?xf32> {byre.argtype = 1: i32, byre.argname = "C"}, %arg3 : memref<200x?xf32> {byre.argtype = 2: i32, byre.argname = "D"}) attributes {byre.entry_point} { // CHECK-LABEL: func.func @test_group_copy "byre.group_copy"(%arg0, %arg2, %arg1, %arg2) {callee = "d2h_array"} : (memref<100x?xf32>, memref<200x?xf32>, memref<100x?xf32>, memref<200x?xf32>) -> () diff --git a/runtime/VERSION_NUMBER b/runtime/VERSION_NUMBER index dcafa494c..84e81b161 100644 --- a/runtime/VERSION_NUMBER +++ b/runtime/VERSION_NUMBER @@ -1 +1 @@ -1.9.0.0 +1.9.1.0