Files
paddlepaddle--paddle/paddle/cinn/optim/ir_simplify.h
T
2026-07-13 12:40:42 +08:00

197 lines
6.1 KiB
C++

// Copyright (c) 2021 CINN 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 "paddle/cinn/ir/ir.h"
namespace cinn {
namespace optim {
/**
* Simplify the expression on Cast, Ramp, Load, Store, IfThenElse and Select
* operations.
*
* This pass is applicable in scenarios where expressions contain redundant
* operations or constants that can be simplified. This is common in
* mathematical computations where certain patterns, such as adding zero or
* multiplying by zero, occur frequently.
* When applied, this pass will traverse the expression and simplify it by
* applying mathematical identities, such as removing zero in addition or
* multiplication, and combining terms in polynomial expressions.
* Performance impact: This pass addresses the performance issues related to
* unnecessary computations in expressions, which can lead to reduced execution
* time and improved efficiency in code generation.
* Examples:
* 1. Basic simplification:
* Input IR:
* A + 0
* Output IR:
* A
*
* 2. Polynomial simplification:
* Input IR:
* A[i * 0 + 2 * a + 3 * a + 1 + 2]
* Output IR:
* A[5 * a + 3]
*
* 3. Ramp simplification:
* Input IR:
* Add([1, 3, 5, 7], [2, 4, 6, 8])
* Output IR:
* [3, 7, 11, 15]
*
* 4. Load simplification:
* Input IR:
* Load(buffer, {i + 0, j * 1})
* Output IR:
* Load(buffer, {i, j})
*
* 5. Store simplification:
* Input IR:
* Store(buffer, value, {i + 0, j * 1})
* Output IR:
* Store(buffer, value, {i, j})
*
* 6. IfThenElse simplification:
* Input IR:
* If(1+2):
* If(false):
* ... (true_case_1)
* Else:
* ... (false_case_1)
* Else:
* ... (false_case_2)
* Output IR:
* ... (false_case_1)
*
* 7. Select simplification:
* Input IR:
* Select(1+2, true_value, false_value)
* Output IR:
* true_value
*/
void Simplify(Expr *expr);
/**
* Simplify type casting expressions.
*
* This pass is applicable when type casting operations in the IR is possible to
* be simplified or eliminated. It is particularly useful in scenarios where
* the type of the expression being cast is already known and can be directly
* used.
* When applied, this pass will check if the cast type matches the type of the
* value to be be cast. If they are the same, the cast will be removed to
* simplify the cast expression. Additionally, if the value being cast is a
* constant, the cast expression will be simplified to the cast type as well.
* Performance impact: This pass addresses performance issues related to
* unnecessary type casting, which can lead to improved runtime efficiency by
* reducing overhead.
* Examples:
* 1. Redundant cast removal:
* Input IR:
* Cast<int>(5)
* Output IR:
* 5
*
* 2. Type mismatch:
* Input IR:
* int x = 5
* Cast<float>(x)
* Cast<float>(5)
* Output IR:
* Cast<float>(x) (Type mismatch, remains unchanged)
* 5.0 (Constant value will be cast)
*/
void SimplifyCast(Expr *expr);
/**
* Simplify for loop structures in the IR.
*
* This pass is applicable in scenarios where for loops are trivial, such as
* loops that iterate exactly once. This simplification is important for
* optimizing loops in high-performance computing scenarios.
* When applied, this pass will check for for loops that have a constant extent
* of 1 and will replace them with their body, effectively removing the loop
* and simplifying the IR.
* Performance impact: This pass can lead to significant performance
* improvements by eliminating unnecessary loop overhead and allowing
* for better optimization of the loop body.
* Examples:
* 1. Trivial loop simplification:
* Input IR:
* for (int i = 1; i < 2; ++i) { doSomething(i); }
* Output IR:
* doSomething(1)
*
* 2. Non-trivial loop:
* Input IR:
* for (int i = 0; i < 2; ++i) { doSomething(i); }
* Output IR:
* for (int i = 0; i < 2; ++i) { doSomething(i); } (remains unchanged)
*/
void SimplifyUnitLoop(Expr *expr);
/**
* Simplify block structures in the IR.
*
* This pass is applicable in scenarios where blocks contain redundant or nested
* blocks that can be flattened. This is useful in optimizing the structure of
* the IR for better performance.
* When applied, this pass will recursively check and simplify blocks of three
* kinds: 1) block(s) containing only a single statement or block will be
* replaced by the inner body; 2) nested block will be flattened by
* extracting the child or current statements into current block; 3) iterative
* variables and buffer regions of ScheduleBlock will be replaced by block body
* when the body is single.
* Performance impact: This pass can improve performance by reducing the
* overhead of block management and enabling better optimization opportunities.
* Examples:
* 1. Single statement block:
* Input IR:
* Block { Block { stmt0 } }
* Output IR:
* Block { stmt0 }
*
* 2. Nested blocks:
* Input IR:
* Block { Block { stmt1 }, Block { stmt2 }, stmt3 }
* Output IR:
* Block { stmt1, stmt2, stmt3 }
*/
void SimplifyUnitBlock(Expr *expr);
void SimplifyLogical(Expr *expr);
void SimplifyNoPureMath(Expr *expr,
const ir::IndexExpr::OptLevel &opt_level =
ir::IndexExpr::OptLevel::kLevel1);
Expr ArithSimplify(const Expr &u,
const ir::IndexExpr::OptLevel &opt_level =
ir::IndexExpr::OptLevel::kLevel1);
} // namespace optim
} // namespace cinn