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