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