14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#ifndef MPL2MPL_INCLUDE_CONSTANTFOLD_H 174514f5e3Sopenharmony_ci#define MPL2MPL_INCLUDE_CONSTANTFOLD_H 184514f5e3Sopenharmony_ci#include "mir_nodes.h" 194514f5e3Sopenharmony_ci#include "phase_impl.h" 204514f5e3Sopenharmony_ci 214514f5e3Sopenharmony_ci#include <optional> 224514f5e3Sopenharmony_ci 234514f5e3Sopenharmony_cinamespace maple { 244514f5e3Sopenharmony_ciclass ConstantFold : public FuncOptimizeImpl { 254514f5e3Sopenharmony_cipublic: 264514f5e3Sopenharmony_ci ConstantFold(MIRModule &mod, bool trace) : FuncOptimizeImpl(mod, trace), mirModule(&mod) {} 274514f5e3Sopenharmony_ci 284514f5e3Sopenharmony_ci explicit ConstantFold(MIRModule &mod) : FuncOptimizeImpl(mod, false), mirModule(&mod) {} 294514f5e3Sopenharmony_ci 304514f5e3Sopenharmony_ci // Fold an expression. 314514f5e3Sopenharmony_ci // It returns a new expression if there was something to fold, or 324514f5e3Sopenharmony_ci // nullptr otherwise. 334514f5e3Sopenharmony_ci BaseNode *Fold(BaseNode *node); 344514f5e3Sopenharmony_ci 354514f5e3Sopenharmony_ci FuncOptimizeImpl *Clone() override 364514f5e3Sopenharmony_ci { 374514f5e3Sopenharmony_ci return new ConstantFold(*this); 384514f5e3Sopenharmony_ci } 394514f5e3Sopenharmony_ci 404514f5e3Sopenharmony_ci ~ConstantFold() override 414514f5e3Sopenharmony_ci { 424514f5e3Sopenharmony_ci mirModule = nullptr; 434514f5e3Sopenharmony_ci } 444514f5e3Sopenharmony_ci 454514f5e3Sopenharmony_ci template <class T> 464514f5e3Sopenharmony_ci T CalIntValueFromFloatValue(T value, const MIRType &resultType) const; 474514f5e3Sopenharmony_ci MIRConst *FoldFloorMIRConst(const MIRConst &cst, PrimType fromType, PrimType toType, bool isFloor = true) const; 484514f5e3Sopenharmony_ci MIRConst *FoldRoundMIRConst(const MIRConst &cst, PrimType fromType, PrimType toType) const; 494514f5e3Sopenharmony_ci MIRConst *FoldTypeCvtMIRConst(const MIRConst &cst, PrimType fromType, PrimType toType) const; 504514f5e3Sopenharmony_ci MIRConst *FoldSignExtendMIRConst(Opcode opcode, PrimType resultType, uint8 size, const IntVal &val) const; 514514f5e3Sopenharmony_ci static MIRConst *FoldIntConstBinaryMIRConst(Opcode opcode, PrimType resultType, const MIRIntConst &intConst0, 524514f5e3Sopenharmony_ci const MIRIntConst &intConst1); 534514f5e3Sopenharmony_ci MIRConst *FoldConstComparisonMIRConst(Opcode opcode, PrimType resultType, PrimType opndType, 544514f5e3Sopenharmony_ci const MIRConst &const0, const MIRConst &const1) const; 554514f5e3Sopenharmony_ci static bool IntegerOpIsOverflow(Opcode op, PrimType primType, int64 cstA, int64 cstB); 564514f5e3Sopenharmony_ci static MIRIntConst *FoldIntConstUnaryMIRConst(Opcode opcode, PrimType resultType, const MIRIntConst *constNode); 574514f5e3Sopenharmony_ciprivate: 584514f5e3Sopenharmony_ci std::pair<BaseNode*, std::optional<IntVal>> FoldBase(BaseNode *node) const; 594514f5e3Sopenharmony_ci std::pair<BaseNode*, std::optional<IntVal>> FoldBinary(BinaryNode *node); 604514f5e3Sopenharmony_ci std::pair<BaseNode*, std::optional<IntVal>> FoldCompare(CompareNode *node); 614514f5e3Sopenharmony_ci std::pair<BaseNode*, std::optional<IntVal>> FoldExtractbits(ExtractbitsNode *node); 624514f5e3Sopenharmony_ci ConstvalNode *FoldSignExtend(Opcode opcode, PrimType resultType, uint8 size, const ConstvalNode &cst) const; 634514f5e3Sopenharmony_ci std::pair<BaseNode*, std::optional<IntVal>> FoldIread(IreadNode *node); 644514f5e3Sopenharmony_ci std::pair<BaseNode*, std::optional<IntVal>> FoldRetype(RetypeNode *node); 654514f5e3Sopenharmony_ci std::pair<BaseNode*, std::optional<IntVal>> FoldUnary(UnaryNode *node); 664514f5e3Sopenharmony_ci std::pair<BaseNode*, std::optional<IntVal>> FoldTypeCvt(TypeCvtNode *node); 674514f5e3Sopenharmony_ci ConstvalNode *FoldCeil(const ConstvalNode &cst, PrimType fromType, PrimType toType) const; 684514f5e3Sopenharmony_ci ConstvalNode *FoldFloor(const ConstvalNode &cst, PrimType fromType, PrimType toType) const; 694514f5e3Sopenharmony_ci ConstvalNode *FoldRound(const ConstvalNode &cst, PrimType fromType, PrimType toType) const; 704514f5e3Sopenharmony_ci ConstvalNode *FoldTrunc(const ConstvalNode &cst, PrimType fromType, PrimType toType) const; 714514f5e3Sopenharmony_ci ConstvalNode *FoldTypeCvt(const ConstvalNode &cst, PrimType fromType, PrimType toType) const; 724514f5e3Sopenharmony_ci ConstvalNode *FoldConstComparison(Opcode opcode, PrimType resultType, PrimType opndType, const ConstvalNode &const0, 734514f5e3Sopenharmony_ci const ConstvalNode &const1) const; 744514f5e3Sopenharmony_ci ConstvalNode *FoldConstBinary(Opcode opcode, PrimType resultType, const ConstvalNode &const0, 754514f5e3Sopenharmony_ci const ConstvalNode &const1) const; 764514f5e3Sopenharmony_ci ConstvalNode *FoldIntConstComparison(Opcode opcode, PrimType resultType, PrimType opndType, 774514f5e3Sopenharmony_ci const ConstvalNode &const0, const ConstvalNode &const1) const; 784514f5e3Sopenharmony_ci MIRIntConst *FoldIntConstComparisonMIRConst(Opcode opcode, PrimType resultType, PrimType opndType, 794514f5e3Sopenharmony_ci const MIRIntConst &intConst0, const MIRIntConst &intConst1) const; 804514f5e3Sopenharmony_ci ConstvalNode *FoldIntConstBinary(Opcode opcode, PrimType resultType, const ConstvalNode &const0, 814514f5e3Sopenharmony_ci const ConstvalNode &const1) const; 824514f5e3Sopenharmony_ci ConstvalNode *FoldFPConstComparison(Opcode opcode, PrimType resultType, PrimType opndType, 834514f5e3Sopenharmony_ci const ConstvalNode &const0, const ConstvalNode &const1) const; 844514f5e3Sopenharmony_ci bool ConstValueEqual(int64 leftValue, int64 rightValue) const; 854514f5e3Sopenharmony_ci bool ConstValueEqual(float leftValue, float rightValue) const; 864514f5e3Sopenharmony_ci bool ConstValueEqual(double leftValue, double rightValue) const; 874514f5e3Sopenharmony_ci template<typename T> 884514f5e3Sopenharmony_ci bool FullyEqual(T leftValue, T rightValue) const; 894514f5e3Sopenharmony_ci template<typename T> 904514f5e3Sopenharmony_ci int64 ComparisonResult(Opcode op, T *leftConst, T *rightConst) const; 914514f5e3Sopenharmony_ci MIRIntConst *FoldFPConstComparisonMIRConst(Opcode opcode, PrimType resultType, PrimType opndType, 924514f5e3Sopenharmony_ci const MIRConst &leftConst, const MIRConst &rightConst) const; 934514f5e3Sopenharmony_ci ConstvalNode *FoldFPConstBinary(Opcode opcode, PrimType resultType, const ConstvalNode &const0, 944514f5e3Sopenharmony_ci const ConstvalNode &const1) const; 954514f5e3Sopenharmony_ci ConstvalNode *FoldConstUnary(Opcode opcode, PrimType resultType, ConstvalNode &constNode) const; 964514f5e3Sopenharmony_ci template <typename T> 974514f5e3Sopenharmony_ci ConstvalNode *FoldFPConstUnary(Opcode opcode, PrimType resultType, ConstvalNode *constNode) const; 984514f5e3Sopenharmony_ci BaseNode *NegateTree(BaseNode *node) const; 994514f5e3Sopenharmony_ci BaseNode *Negate(BaseNode *node) const; 1004514f5e3Sopenharmony_ci BaseNode *Negate(UnaryNode *node) const; 1014514f5e3Sopenharmony_ci BaseNode *Negate(const ConstvalNode *node) const; 1024514f5e3Sopenharmony_ci BinaryNode *NewBinaryNode(BinaryNode *old, Opcode op, PrimType primType, BaseNode *lhs, BaseNode *rhs) const; 1034514f5e3Sopenharmony_ci UnaryNode *NewUnaryNode(UnaryNode *old, Opcode op, PrimType primType, BaseNode *expr) const; 1044514f5e3Sopenharmony_ci std::pair<BaseNode*, std::optional<IntVal>> DispatchFold(BaseNode *node); 1054514f5e3Sopenharmony_ci BaseNode *PairToExpr(PrimType resultType, const std::pair<BaseNode*, std::optional<IntVal>> &pair) const; 1064514f5e3Sopenharmony_ci BaseNode *SimplifyDoubleConstvalCompare(CompareNode &node, bool isRConstval, bool isGtOrLt = false) const; 1074514f5e3Sopenharmony_ci BaseNode *SimplifyDoubleCompare(CompareNode &compareNode) const; 1084514f5e3Sopenharmony_ci CompareNode *FoldConstComparisonReverse(Opcode opcode, PrimType resultType, PrimType opndType, BaseNode &l, 1094514f5e3Sopenharmony_ci BaseNode &r) const; 1104514f5e3Sopenharmony_ci MIRModule *mirModule; 1114514f5e3Sopenharmony_ci}; 1124514f5e3Sopenharmony_ci 1134514f5e3Sopenharmony_ci} // namespace maple 1144514f5e3Sopenharmony_ci#endif // MPL2MPL_INCLUDE_CONSTANTFOLD_H 115