diff --git a/paddle/ir/CMakeLists.txt b/paddle/ir/CMakeLists.txt index ae7211226dd594b4ffa46c83a78986154cadc7c0..6536a2fe0183fd2a996861272116df520ed7fea6 100644 --- a/paddle/ir/CMakeLists.txt +++ b/paddle/ir/CMakeLists.txt @@ -40,6 +40,7 @@ endif() add_subdirectory(core) add_subdirectory(pass) add_subdirectory(pattern_rewrite) +add_subdirectory(transforms) if(WIN32) if(WITH_SHARED_IR) diff --git a/paddle/ir/transforms/CMakeLists.txt b/paddle/ir/transforms/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..2b9f63a64d4f94f7a050b5d94b3053d3a08efee9 --- /dev/null +++ b/paddle/ir/transforms/CMakeLists.txt @@ -0,0 +1,10 @@ +file(GLOB PATTERN_SRCS "*.cc") + +ir_library( + ir_builtin_transforms + SRCS + ${PATTERN_SRCS} + DEPS + ir_core + ir_pattern_rewrite + ir_pass) diff --git a/paddle/ir/transforms/dce.cc b/paddle/ir/transforms/dce.cc new file mode 100644 index 0000000000000000000000000000000000000000..31d8a1951fbddfdf1e0d83769f61773953b8c28e --- /dev/null +++ b/paddle/ir/transforms/dce.cc @@ -0,0 +1,61 @@ +// Copyright (c) 2023 PaddlePaddle Authors. 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 "paddle/ir/transforms/dce.h" +#include +#include "paddle/ir/core/builtin_op.h" +#include "paddle/ir/pass/pass.h" + +namespace { + +// TODO(wilber): After support SideEffectTrait, Only NoSideEffectTrait op can be +// removed by dce pass. +// Now just a naive implementation. +class DCEPass : public ir::Pass { + public: + DCEPass() : ir::Pass("DCEPass", 0) {} + + void Run(ir::Operation *op) override { + auto module_op = op->dyn_cast(); + IR_ENFORCE(module_op, "DCEPass should run on module op."); + auto *block = module_op.block(); + std::vector erased_op; + for (auto it = block->begin(); it != block->end(); ++it) { + // TODO(wilber): Support NoSideEffect trait. + // if (!(*it)->HasTrait()) continue; + + bool use_empty = true; + for (uint32_t i = 0; i < (*it)->num_results(); ++i) { + use_empty &= (*it)->result(i).use_empty(); + } + if (use_empty && (*it)->name() != "pd.fetch") { + erased_op.push_back(**it); + } + } + + for (auto ep : erased_op) block->erase(ep); + } + + bool CanApplyOn(ir::Operation *op) const override { + return op->name() == "builtin.module" && op->num_regions() > 0; + } +}; + +} // namespace + +namespace ir { + +std::unique_ptr CreateDCEPass() { return std::make_unique(); } + +} // namespace ir diff --git a/paddle/ir/transforms/dce.h b/paddle/ir/transforms/dce.h new file mode 100644 index 0000000000000000000000000000000000000000..061fc04ceb9e28fcd0b0e916e756814f770ec49b --- /dev/null +++ b/paddle/ir/transforms/dce.h @@ -0,0 +1,25 @@ +// Copyright (c) 2023 PaddlePaddle Authors. 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. + +#pragma once + +#include +#include "paddle/ir/core/dll_decl.h" + +namespace ir { +class Pass; + +IR_API std::unique_ptr CreateDCEPass(); + +} // namespace ir diff --git a/test/cpp/ir/pattern_rewrite/pattern_rewrite_test.cc b/test/cpp/ir/pattern_rewrite/pattern_rewrite_test.cc index dc3b716a4953f2d486da30f9c2fd51dcdbb1b93a..068a78be5e510c683f298f4095a501c40894ec14 100644 --- a/test/cpp/ir/pattern_rewrite/pattern_rewrite_test.cc +++ b/test/cpp/ir/pattern_rewrite/pattern_rewrite_test.cc @@ -22,6 +22,7 @@ #include "paddle/ir/core/builder.h" #include "paddle/ir/core/builtin_attribute.h" #include "paddle/ir/core/builtin_dialect.h" +#include "paddle/ir/core/builtin_op.h" #include "paddle/ir/core/cast_utils.h" #include "paddle/ir/core/dialect.h" #include "paddle/ir/core/enforce.h" @@ -34,6 +35,7 @@ #include "paddle/ir/pattern_rewrite/pattern_applicator.h" #include "paddle/ir/pattern_rewrite/pattern_match.h" #include "paddle/ir/pattern_rewrite/pattern_rewrite_driver.h" +#include "paddle/ir/transforms/dce.h" // NOTE(zhangbo9674): File pd_op.h is generated by op_gen.py, see details in // paddle/fluid/ir/dialect/CMakeLists.txt. @@ -235,7 +237,7 @@ class TestPass : public ir::Pass { ir::FrozenRewritePatternSet frozen_ps(std::move(ps)); ir::GreedyRewriteConfig cfg; cfg.use_top_down_traversal = true; - cfg.max_iterations = 1; + cfg.max_iterations = 10; ir::ApplyPatternsGreedily(op->region(0), frozen_ps, cfg); } @@ -255,10 +257,10 @@ void BuildProgram(ir::Builder &builder) { // NOLINT auto transpose1_op = builder.Build( full_op_output, std::vector{0, 2, 3, 1}); - builder.Build(transpose1_op.out(), - std::vector{0, 3, 1, 2}); + auto transpose2_op = builder.Build( + transpose1_op.out(), std::vector{0, 3, 1, 2}); - // builder.Build(transpose2_op.out()); + builder.Build(transpose2_op.out(), "out"); } // TODO(wilber): Add a normal test. @@ -268,10 +270,11 @@ TEST(PatternRewrite, GreedyPatternRewriteDriver) { ir::Program program(ctx); ir::Builder builder = ir::Builder(ctx, program.block()); BuildProgram(builder); - EXPECT_EQ(program.block()->size(), 3u); + EXPECT_EQ(program.block()->size(), 4u); ir::PassManager pm(ctx); pm.AddPass(std::make_unique()); + pm.AddPass(ir::CreateDCEPass()); std::stringstream o1, o2; program.Print(o1); LOG(INFO) << o1.str();