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