• 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);
41 
Clone()42     FuncOptimizeImpl *Clone()
43     {
44         return new ConstantFold(*this);
45     }
46 
47     void ProcessFunc(MIRFunction *func);
48     virtual ~ConstantFold() = default;
49 
50     template <class T>
51     T CalIntValueFromFloatValue(T value, const MIRType &resultType) const;
52     MIRConst *FoldFloorMIRConst(const MIRConst &, PrimType, PrimType, bool isFloor = true) const;
53     MIRConst *FoldRoundMIRConst(const MIRConst &, PrimType, PrimType) const;
54     MIRConst *FoldTypeCvtMIRConst(const MIRConst &, PrimType, PrimType) const;
55     MIRConst *FoldSignExtendMIRConst(Opcode, PrimType, uint8, const IntVal &) const;
56     MIRConst *FoldIntConstBinaryMIRConst(Opcode opcode, PrimType resultType, const MIRIntConst *intConst0,
57                                          const MIRIntConst *intConst1) const;
58     MIRConst *FoldConstComparisonMIRConst(Opcode, PrimType, PrimType, const MIRConst &, const MIRConst &);
59     static bool IntegerOpIsOverflow(Opcode op, PrimType primType, int64 cstA, int64 cstB);
60 
61 private:
62     StmtNode *SimplifyBinary(BinaryStmtNode *node);
63     StmtNode *SimplifyBlock(BlockNode *node);
64     StmtNode *SimplifyCondGoto(CondGotoNode *node);
65     StmtNode *SimplifyCondGotoSelect(CondGotoNode *node) const;
66     StmtNode *SimplifyDassign(DassignNode *node);
67     StmtNode *SimplifyIassignWithIaddrofBaseNode(IassignNode &node, const IaddrofNode &base);
68     StmtNode *SimplifyIassign(IassignNode *node);
69     StmtNode *SimplifyNary(NaryStmtNode *node);
70     StmtNode *SimplifyIcall(IcallNode *node);
71     StmtNode *SimplifyIf(IfStmtNode *node);
72     StmtNode *SimplifySwitch(SwitchNode *node);
73     StmtNode *SimplifyUnary(UnaryStmtNode *node);
74     StmtNode *SimplifyAsm(AsmNode *node);
75     StmtNode *SimplifyWhile(WhileStmtNode *node);
76     std::pair<BaseNode *, std::optional<IntVal>> FoldArray(ArrayNode *node);
77     std::pair<BaseNode *, std::optional<IntVal>> FoldBase(BaseNode *node) const;
78     std::pair<BaseNode *, std::optional<IntVal>> FoldBinary(BinaryNode *node);
79     std::pair<BaseNode *, std::optional<IntVal>> FoldCompare(CompareNode *node);
80     std::pair<BaseNode *, std::optional<IntVal>> FoldDepositbits(DepositbitsNode *node);
81     std::pair<BaseNode *, std::optional<IntVal>> FoldExtractbits(ExtractbitsNode *node);
82     ConstvalNode *FoldSignExtend(Opcode opcode, PrimType resultType, uint8 size, const ConstvalNode &cst) const;
83     std::pair<BaseNode *, std::optional<IntVal>> FoldIread(IreadNode *node);
84     std::pair<BaseNode *, std::optional<IntVal>> FoldSizeoftype(SizeoftypeNode *node) const;
85     std::pair<BaseNode *, std::optional<IntVal>> FoldRetype(RetypeNode *node);
86     std::pair<BaseNode *, std::optional<IntVal>> FoldGcmallocjarray(JarrayMallocNode *node);
87     std::pair<BaseNode *, std::optional<IntVal>> FoldUnary(UnaryNode *node);
88     std::pair<BaseNode *, std::optional<IntVal>> FoldTernary(TernaryNode *node);
89     std::pair<BaseNode *, std::optional<IntVal>> FoldTypeCvt(TypeCvtNode *node);
90     ConstvalNode *FoldCeil(const ConstvalNode &cst, PrimType fromType, PrimType toType) const;
91     ConstvalNode *FoldFloor(const ConstvalNode &cst, PrimType fromType, PrimType toType) const;
92     ConstvalNode *FoldRound(const ConstvalNode &cst, PrimType fromType, PrimType toType) const;
93     ConstvalNode *FoldTrunk(const ConstvalNode &cst, PrimType fromType, PrimType toType) const;
94     ConstvalNode *FoldTypeCvt(const ConstvalNode &cst, PrimType fromType, PrimType toType) const;
95     ConstvalNode *FoldConstComparison(Opcode opcode, PrimType resultType, PrimType opndType, const ConstvalNode &const0,
96                                       const ConstvalNode &const1) const;
97     ConstvalNode *FoldConstBinary(Opcode opcode, PrimType resultType, const ConstvalNode &const0,
98                                   const ConstvalNode &const1) const;
99     ConstvalNode *FoldIntConstComparison(Opcode opcode, PrimType resultType, PrimType opndType,
100                                          const ConstvalNode &const0, const ConstvalNode &const1) const;
101     MIRIntConst *FoldIntConstComparisonMIRConst(Opcode, PrimType, PrimType, const MIRIntConst &,
102                                                 const MIRIntConst &) const;
103     ConstvalNode *FoldIntConstBinary(Opcode opcode, PrimType resultType, const ConstvalNode &const0,
104                                      const ConstvalNode &const1) const;
105     ConstvalNode *FoldFPConstComparison(Opcode opcode, PrimType resultType, PrimType opndType,
106                                         const ConstvalNode &const0, const ConstvalNode &const1) const;
107     bool ConstValueEqual(int64 leftValue, int64 rightValue) const;
108     bool ConstValueEqual(float leftValue, float rightValue) const;
109     bool ConstValueEqual(double leftValue, double rightValue) const;
110     template <typename T>
111     bool FullyEqual(T leftValue, T rightValue) const;
112     template <typename T>
113     int64 ComparisonResult(Opcode op, T *leftConst, T *rightConst) const;
114     MIRIntConst *FoldFPConstComparisonMIRConst(Opcode opcode, PrimType resultType, PrimType opndType,
115                                                const MIRConst &leftConst, const MIRConst &rightConst) const;
116     ConstvalNode *FoldFPConstBinary(Opcode opcode, PrimType resultType, const ConstvalNode &const0,
117                                     const ConstvalNode &const1) const;
118     ConstvalNode *FoldConstUnary(Opcode opcode, PrimType resultType, ConstvalNode *constNode) const;
119     ConstvalNode *FoldIntConstUnary(Opcode opcode, PrimType resultType, const ConstvalNode *constNode) const;
120     template <typename T>
121     ConstvalNode *FoldFPConstUnary(Opcode opcode, PrimType resultType, ConstvalNode *constNode) const;
122     BaseNode *NegateTree(BaseNode *node) const;
123     BaseNode *Negate(BaseNode *node) const;
124     BaseNode *Negate(UnaryNode *node) const;
125     BaseNode *Negate(const ConstvalNode *node) const;
126     BinaryNode *NewBinaryNode(BinaryNode *old, Opcode op, PrimType primeType, BaseNode *lhs, BaseNode *rhs) const;
127     UnaryNode *NewUnaryNode(UnaryNode *old, Opcode op, PrimType primeType, BaseNode *expr) const;
128     std::pair<BaseNode *, std::optional<IntVal>> DispatchFold(BaseNode *node);
129     BaseNode *PairToExpr(PrimType resultType, const std::pair<BaseNode *, std::optional<IntVal>> &pair) const;
130     BaseNode *SimplifyDoubleCompare(CompareNode &node) const;
131     CompareNode *FoldConstComparisonReverse(Opcode opcode, PrimType resultType, PrimType opndType, BaseNode &l,
132                                             BaseNode &r);
133     MIRModule *mirModule;
134 };
135 
136 }  // namespace maple
137 #endif  // MPL2MPL_INCLUDE_CONSTANTFOLD_H
138