• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef MPL2MPL_INCLUDE_CONSTANTFOLD_H
17 #define MPL2MPL_INCLUDE_CONSTANTFOLD_H
18 #include "mir_nodes.h"
19 #include "phase_impl.h"
20 
21 #include <optional>
22 
23 namespace maple {
24 class ConstantFold : public FuncOptimizeImpl {
25 public:
ConstantFold(MIRModule & mod,KlassHierarchy * kh,bool trace)26     ConstantFold(MIRModule &mod, KlassHierarchy *kh, bool trace) : FuncOptimizeImpl(mod, kh, trace), mirModule(&mod) {}
27 
ConstantFold(MIRModule & mod)28     explicit ConstantFold(MIRModule &mod) : FuncOptimizeImpl(mod, nullptr, false), mirModule(&mod) {}
29 
30     // Fold an expression.
31     // It returns a new expression if there was something to fold, or
32     // nullptr otherwise.
33     BaseNode *Fold(BaseNode *node);
34 
35     // Simplify a statement
36     // It returns the original statement or the changed statement if a
37     // simplification happened. If the statement can be deleted after a
38     // simplification, it returns nullptr.
39     StmtNode *Simplify(StmtNode *node);
40     StmtNode *SimplifyIassignWithAddrofBaseNode(IassignNode &node, const AddrofNode &base) const;
41 
Clone()42     FuncOptimizeImpl *Clone() override
43     {
44         return new ConstantFold(*this);
45     }
46 
47     void ProcessFunc(MIRFunction *func) override;
~ConstantFold()48     ~ConstantFold() override
49     {
50         mirModule = nullptr;
51     }
52 
53     template <class T>
54     T CalIntValueFromFloatValue(T value, const MIRType &resultType) const;
55     MIRConst *FoldFloorMIRConst(const MIRConst &cst, PrimType fromType, PrimType toType, bool isFloor = true) const;
56     MIRConst *FoldRoundMIRConst(const MIRConst &cst, PrimType fromType, PrimType toType) const;
57     MIRConst *FoldTypeCvtMIRConst(const MIRConst &cst, PrimType fromType, PrimType toType) const;
58     MIRConst *FoldSignExtendMIRConst(Opcode opcode, PrimType resultType, uint8 size, const IntVal &val) const;
59     static MIRConst *FoldIntConstBinaryMIRConst(Opcode opcode, PrimType resultType, const MIRIntConst &intConst0,
60                                                 const MIRIntConst &intConst1);
61     MIRConst *FoldConstComparisonMIRConst(Opcode opcode, PrimType resultType, PrimType opndType,
62                                           const MIRConst &const0, const MIRConst &const1) const;
63     static bool IntegerOpIsOverflow(Opcode op, PrimType primType, int64 cstA, int64 cstB);
64     static MIRIntConst *FoldIntConstUnaryMIRConst(Opcode opcode, PrimType resultType, const MIRIntConst *constNode);
65 private:
66     StmtNode *SimplifyBinary(BinaryStmtNode *node);
67     StmtNode *SimplifyBlock(BlockNode *node);
68     StmtNode *SimplifyCondGoto(CondGotoNode *node);
69     StmtNode *SimplifyCondGotoSelect(CondGotoNode *node) const;
70     StmtNode *SimplifyDassign(DassignNode *node);
71     StmtNode *SimplifyIassignWithIaddrofBaseNode(IassignNode &node, const IaddrofNode &base);
72     StmtNode *SimplifyIassign(IassignNode *node);
73     StmtNode *SimplifyNary(NaryStmtNode *node);
74     StmtNode *SimplifyIcall(IcallNode *node);
75     StmtNode *SimplifyIf(IfStmtNode *node);
76     StmtNode *SimplifySwitch(SwitchNode *node);
77     StmtNode *SimplifyUnary(UnaryStmtNode *node);
78     StmtNode *SimplifyAsm(AsmNode *node);
79     StmtNode *SimplifyWhile(WhileStmtNode *node);
80     std::pair<BaseNode*, std::optional<IntVal>> FoldArray(ArrayNode *node);
81     std::pair<BaseNode*, std::optional<IntVal>> FoldBase(BaseNode *node) const;
82     std::pair<BaseNode*, std::optional<IntVal>> FoldBinary(BinaryNode *node);
83     std::pair<BaseNode*, std::optional<IntVal>> FoldCompare(CompareNode *node);
84     std::pair<BaseNode*, std::optional<IntVal>> FoldDepositbits(DepositbitsNode *node);
85     std::pair<BaseNode*, std::optional<IntVal>> FoldExtractbits(ExtractbitsNode *node);
86     ConstvalNode *FoldSignExtend(Opcode opcode, PrimType resultType, uint8 size, const ConstvalNode &cst) const;
87     std::pair<BaseNode*, std::optional<IntVal>> FoldIread(IreadNode *node);
88     std::pair<BaseNode*, std::optional<IntVal>> FoldSizeoftype(SizeoftypeNode *node) const;
89     std::pair<BaseNode*, std::optional<IntVal>> FoldRetype(RetypeNode *node);
90     std::pair<BaseNode*, std::optional<IntVal>> FoldGcmallocjarray(JarrayMallocNode *node);
91     std::pair<BaseNode*, std::optional<IntVal>> FoldUnary(UnaryNode *node);
92     std::pair<BaseNode*, std::optional<IntVal>> FoldTernary(TernaryNode *node);
93     std::pair<BaseNode*, std::optional<IntVal>> FoldTypeCvt(TypeCvtNode *node);
94     ConstvalNode *FoldCeil(const ConstvalNode &cst, PrimType fromType, PrimType toType) const;
95     ConstvalNode *FoldFloor(const ConstvalNode &cst, PrimType fromType, PrimType toType) const;
96     ConstvalNode *FoldRound(const ConstvalNode &cst, PrimType fromType, PrimType toType) const;
97     ConstvalNode *FoldTrunc(const ConstvalNode &cst, PrimType fromType, PrimType toType) const;
98     ConstvalNode *FoldTypeCvt(const ConstvalNode &cst, PrimType fromType, PrimType toType) const;
99     ConstvalNode *FoldConstComparison(Opcode opcode, PrimType resultType, PrimType opndType, const ConstvalNode &const0,
100                                       const ConstvalNode &const1) const;
101     ConstvalNode *FoldConstBinary(Opcode opcode, PrimType resultType, const ConstvalNode &const0,
102                                   const ConstvalNode &const1) const;
103     ConstvalNode *FoldIntConstComparison(Opcode opcode, PrimType resultType, PrimType opndType,
104                                          const ConstvalNode &const0, const ConstvalNode &const1) const;
105     MIRIntConst *FoldIntConstComparisonMIRConst(Opcode opcode, PrimType resultType, PrimType opndType,
106                                                 const MIRIntConst &intConst0, const MIRIntConst &intConst1) const;
107     ConstvalNode *FoldIntConstBinary(Opcode opcode, PrimType resultType, const ConstvalNode &const0,
108                                      const ConstvalNode &const1) const;
109     ConstvalNode *FoldFPConstComparison(Opcode opcode, PrimType resultType, PrimType opndType,
110                                         const ConstvalNode &const0, const ConstvalNode &const1) const;
111     bool ConstValueEqual(int64 leftValue, int64 rightValue) const;
112     bool ConstValueEqual(float leftValue, float rightValue) const;
113     bool ConstValueEqual(double leftValue, double rightValue) const;
114     template<typename T>
115     bool FullyEqual(T leftValue, T rightValue) const;
116     template<typename T>
117     int64 ComparisonResult(Opcode op, T *leftConst, T *rightConst) const;
118     MIRIntConst *FoldFPConstComparisonMIRConst(Opcode opcode, PrimType resultType, PrimType opndType,
119                                                const MIRConst &leftConst, const MIRConst &rightConst) const;
120     ConstvalNode *FoldFPConstBinary(Opcode opcode, PrimType resultType, const ConstvalNode &const0,
121                                     const ConstvalNode &const1) const;
122     ConstvalNode *FoldConstUnary(Opcode opcode, PrimType resultType, ConstvalNode &constNode) const;
123     template <typename T>
124     ConstvalNode *FoldFPConstUnary(Opcode opcode, PrimType resultType, ConstvalNode *constNode) const;
125     BaseNode *NegateTree(BaseNode *node) const;
126     BaseNode *Negate(BaseNode *node) const;
127     BaseNode *Negate(UnaryNode *node) const;
128     BaseNode *Negate(const ConstvalNode *node) const;
129     BinaryNode *NewBinaryNode(BinaryNode *old, Opcode op, PrimType primType, BaseNode *lhs, BaseNode *rhs) const;
130     UnaryNode *NewUnaryNode(UnaryNode *old, Opcode op, PrimType primType, BaseNode *expr) const;
131     std::pair<BaseNode*, std::optional<IntVal>> DispatchFold(BaseNode *node);
132     BaseNode *PairToExpr(PrimType resultType, const std::pair<BaseNode*, std::optional<IntVal>> &pair) const;
133     BaseNode *SimplifyDoubleConstvalCompare(CompareNode &node, bool isRConstval, bool isGtOrLt = false) const;
134     BaseNode *SimplifyDoubleCompare(CompareNode &compareNode) const;
135     CompareNode *FoldConstComparisonReverse(Opcode opcode, PrimType resultType, PrimType opndType, BaseNode &l,
136                                             BaseNode &r) const;
137     MIRModule *mirModule;
138 };
139 
140 }  // namespace maple
141 #endif  // MPL2MPL_INCLUDE_CONSTANTFOLD_H
142