diff --git a/src/mapleall/maple_me/include/irmap.h b/src/mapleall/maple_me/include/irmap.h index a389039090b92cdc37fb926e4c8c349687111828..59e649e293e66b744d3d67e0c842e8854773a943 100644 --- a/src/mapleall/maple_me/include/irmap.h +++ b/src/mapleall/maple_me/include/irmap.h @@ -105,6 +105,9 @@ class IRMap : public AnalysisResult { TyIdx tyIdx = TyIdx()); IntrinsiccallMeStmt *CreateIntrinsicCallAssignedMeStmt(MIRIntrinsicID idx, std::vector &opnds, MeExpr *ret, TyIdx tyIdx = TyIdx()); + MeExpr *SimplifyOpMeExpr(OpMeExpr *opmeexpr); + MeExpr *SimplifyMeExpr(MeExpr *x); + template T *NewInPool(Arguments&&... args) { return irMapAlloc.GetMemPool()->New(&irMapAlloc, std::forward(args)...); diff --git a/src/mapleall/maple_me/include/irmap_build.h b/src/mapleall/maple_me/include/irmap_build.h index 78469d58193b9c50e0ec76d7ca48f6cfa87e5228..2e826461c0af2eb4a996b49ded9c24170ab95f0e 100644 --- a/src/mapleall/maple_me/include/irmap_build.h +++ b/src/mapleall/maple_me/include/irmap_build.h @@ -19,15 +19,18 @@ #include "dominance.h" namespace maple { +class Prop; + // This class contains methods to convert Maple IR to MeIR. class IRMapBuild { public: - IRMapBuild(IRMap *hmap, Dominance *dom) + IRMapBuild(IRMap *hmap, Dominance *dom, Prop *prop) : irMap(hmap), mirModule(hmap->GetMIRModule()), ssaTab(irMap->GetSSATab()), dominance(*dom), - curBB(nullptr) { + curBB(nullptr), + propagater(prop) { InitMeExprBuildFactory(); InitMeStmtFactory(); } @@ -44,7 +47,7 @@ class IRMapBuild { void BuildMustDefList(MeStmt &meStmt, TypeOfMustDefList&, MapleVector&); void BuildMuList(TypeOfMayUseList&, MapleMap&); void BuildPhiMeNode(BB&); - void SetMeExprOpnds(MeExpr &meExpr, BaseNode &mirNode); + void SetMeExprOpnds(MeExpr &meExpr, BaseNode &mirNode, bool atparm, bool noProp); OpMeExpr *BuildOpMeExpr(const BaseNode &mirNode) const { auto meExpr = new OpMeExpr(kInvalidExprID, mirNode.GetOpCode(), mirNode.GetPrimType(), mirNode.GetNumOpnds()); @@ -71,7 +74,7 @@ class IRMapBuild { MeExpr *BuildNaryMeExprForArray(const BaseNode &mirNode) const; MeExpr *BuildNaryMeExprForIntrinsicop(const BaseNode &mirNode) const; MeExpr *BuildNaryMeExprForIntrinsicWithType(const BaseNode &mirNode) const; - MeExpr *BuildExpr(BaseNode&); + MeExpr *BuildExpr(BaseNode&, bool atParm, bool noProp); static void InitMeExprBuildFactory(); MeStmt *BuildMeStmtWithNoSSAPart(StmtNode &stmt); @@ -94,6 +97,7 @@ class IRMapBuild { SSATab &ssaTab; Dominance &dominance; BB *curBB; // current mapleme::BB being visited + Prop *propagater; }; } // namespace maple #endif // MAPLE_ME_INCLUDE_IRMAP_BUILD_H diff --git a/src/mapleall/maple_me/include/me_ir.h b/src/mapleall/maple_me/include/me_ir.h index c9c4ec48504a37e09e22dc8c5c9db665a4cd30c5..3051f62e7b4188b0bed0618ec0635ee7c34ea88a 100644 --- a/src/mapleall/maple_me/include/me_ir.h +++ b/src/mapleall/maple_me/include/me_ir.h @@ -92,10 +92,6 @@ class MeExpr { return exprID; } - uint8 GetDepth() const { - return depth; - } - uint32 GetTreeID() const { return treeID; } @@ -108,6 +104,10 @@ class MeExpr { (void)indent; } + virtual size_t GetDepth() const { + return 0; + } + virtual bool IsZero() const { return false; } @@ -145,7 +145,6 @@ class MeExpr { return nullptr; } - void UpdateDepth(); // update the depth, suppose all sub nodes have already depth done. MeExpr &GetAddrExprBase(); // get the base of the address expression // in the expression; nullptr otherwise bool SymAppears(OStIdx oidx); // check if symbol appears in the expression @@ -172,7 +171,6 @@ class MeExpr { uint8 numOpnds; MeExprOp meOp; int32 exprID; - uint8 depth = 0; uint32 treeID = 0; // for bookkeeping purpose during SSAPRE MeExpr *next = nullptr; }; @@ -762,6 +760,7 @@ class OpMeExpr : public MeExpr { opndType(opMeExpr.opndType), bitsOffset(opMeExpr.bitsOffset), bitsSize(opMeExpr.bitsSize), + depth(opMeExpr.depth), tyIdx(opMeExpr.tyIdx), fieldID(opMeExpr.fieldID) {} @@ -777,14 +776,23 @@ class OpMeExpr : public MeExpr { bool IsUseSameSymbol(const MeExpr&) const override; MeExpr *GetIdenticalExpr(MeExpr &expr, bool) const override; BaseNode &EmitExpr(SSATab&) override; + size_t GetDepth() const override { + return depth; + } MeExpr *GetOpnd(size_t i) const override { CHECK_FATAL(i < kOperandNumTernary, "OpMeExpr cannot have more than 3 operands"); return opnds[i]; } - void SetOpnd(size_t idx, MeExpr *opndsVal) override { + void SetOpnd(size_t idx, MeExpr *x) override { CHECK_FATAL(idx < kOperandNumTernary, "out of range in OpMeExpr::SetOpnd"); - opnds[idx] = opndsVal; + opnds[idx] = x; + if (depth <= x->GetDepth()) { + depth = x->GetDepth(); + if (depth != UINT8_MAX) { + depth++; + } + } } PrimType GetOpndType() { @@ -848,6 +856,7 @@ class OpMeExpr : public MeExpr { PrimType opndType = kPtyInvalid; // from type uint8 bitsOffset = 0; uint8 bitsSize = 0; + uint8 depth = 0; TyIdx tyIdx; FieldID fieldID = 0; // this is also used to store puIdx }; @@ -862,13 +871,17 @@ class IvarMeExpr : public MeExpr { defStmt(ivarme.defStmt), base(ivarme.base), tyIdx(ivarme.tyIdx), - fieldID(ivarme.fieldID) { + fieldID(ivarme.fieldID), + volatileFromBaseSymbol(ivarme.volatileFromBaseSymbol) { mu = ivarme.mu; } ~IvarMeExpr() = default; void Dump(const IRMap*, int32 indent = 0) const override; + size_t GetDepth() const override { + return base->GetDepth() + 1; + } BaseNode &EmitExpr(SSATab&) override; bool IsVolatile() const override; bool IsFinal(); @@ -932,6 +945,14 @@ class IvarMeExpr : public MeExpr { maybeNull = maybeNullVal; } + bool GetVolatileFromBaseSymbol() const { + return volatileFromBaseSymbol; + } + + void SetVolatileFromBaseSymbol(bool value) { + volatileFromBaseSymbol = value; + } + VarMeExpr *GetMu() { return mu; } @@ -954,6 +975,7 @@ class IvarMeExpr : public MeExpr { TyIdx inferredTyIdx{ 0 }; // may be a subclass of above tyIdx FieldID fieldID = 0; bool maybeNull = true; // false if definitely not null + bool volatileFromBaseSymbol = false; // volatile due to its base symbol being volatile VarMeExpr *mu = nullptr; // use of mu, only one for IvarMeExpr }; @@ -973,6 +995,7 @@ class NaryMeExpr : public MeExpr { tyIdx(meExpr.tyIdx), intrinsic(meExpr.intrinsic), opnds(alloc->Adapter()), + depth(meExpr.depth), boundCheck(meExpr.boundCheck) { for (size_t i = 0; i < meExpr.opnds.size(); ++i) { opnds.push_back(meExpr.opnds[i]); @@ -982,6 +1005,9 @@ class NaryMeExpr : public MeExpr { ~NaryMeExpr() = default; void Dump(const IRMap*, int32 indent = 0) const override; + size_t GetDepth() const override { + return depth; + } bool IsIdentical(NaryMeExpr&) const; bool IsUseSameSymbol(const MeExpr&) const override; BaseNode &EmitExpr(SSATab&) override; @@ -1007,14 +1033,25 @@ class NaryMeExpr : public MeExpr { return opnds; } - void SetOpnds(MapleVector &newOpnds) { - ASSERT(newOpnds.size() == GetNumOpnds(), "inconsistent operand numbers"); - opnds = newOpnds; - } - void SetOpnd(size_t idx, MeExpr *val) override { ASSERT(idx < opnds.size(), "out of range in NaryMeStmt::GetOpnd"); opnds[idx] = val; + if (depth <= val->GetDepth()) { + depth = val->GetDepth(); + if (depth != UINT8_MAX) { + depth++; + } + } + } + + void PushOpnd(MeExpr *x) { + opnds.push_back(x); + if (depth <= x->GetDepth()) { + depth = x->GetDepth(); + if (depth != UINT8_MAX) { + depth++; + } + } } bool GetBoundCheck() { @@ -1043,6 +1080,7 @@ class NaryMeExpr : public MeExpr { TyIdx tyIdx; MIRIntrinsicID intrinsic; MapleVector opnds; + uint8 depth = 0; bool boundCheck; }; @@ -1831,7 +1869,7 @@ class IassignMeStmt : public MeStmt { } void Dump(const IRMap*) const; - MeExpr *GetLHS() const { + IvarMeExpr *GetLHS() const { return lhsVar; } diff --git a/src/mapleall/maple_me/include/me_prop.h b/src/mapleall/maple_me/include/me_prop.h index 4468eda67c32a047e0f503f50a0ffdc381d7b990..0712615c7fcbe20e108b3cfe1feb3e8cbf4959b1 100644 --- a/src/mapleall/maple_me/include/me_prop.h +++ b/src/mapleall/maple_me/include/me_prop.h @@ -23,11 +23,16 @@ namespace maple { class MeProp : public Prop { public: MeProp(MeIRMap &irMap, Dominance &dom, MemPool &memPool, const PropConfig &config) - : Prop(irMap, dom, memPool, std::vector(irMap.GetFunc().GetAllBBs().begin(), - irMap.GetFunc().GetAllBBs().end()), - *irMap.GetFunc().GetCommonEntryBB(), config) {} + : Prop(irMap, dom, memPool, irMap.GetFunc().GetAllBBs().size(), config), + func(&irMap.GetFunc()) {} virtual ~MeProp() = default; + private: + MeFunction *func; + + BB *GetBB(BBId id) { + return func->GetAllBBs()[id]; + } }; class MeDoMeProp : public MeFuncPhase { diff --git a/src/mapleall/maple_me/include/prop.h b/src/mapleall/maple_me/include/prop.h index e20c3795c7706adb5981d3219095d1a60e07aeb1..00852cd9ca1ceffb2c0d0a1edbd2b4fdf286dcee 100644 --- a/src/mapleall/maple_me/include/prop.h +++ b/src/mapleall/maple_me/include/prop.h @@ -35,10 +35,27 @@ class Prop { bool propagateAtPhi; }; - Prop(IRMap&, Dominance&, MemPool&, std::vector &&bbVec, BB &commonEntryBB, const PropConfig &config); + Prop(IRMap&, Dominance&, MemPool&, uint32 bbvecsize, const PropConfig &config); virtual ~Prop() = default; - - void DoProp(); + virtual BB *GetBB(BBId id) { + return nullptr; + } + MeExpr &PropVar(VarMeExpr &varmeExpr, bool atParm, bool checkPhi) const; + MeExpr &PropReg(RegMeExpr ®meExpr, bool atParm) const; + MeExpr &PropIvar(IvarMeExpr &ivarMeExpr) const; + void PropUpdateDef(MeExpr &meExpr); + void PropUpdateChiListDef(const MapleMap &chiList); + void PropUpdateMustDefList(MeStmt *mestmt); + void TraversalBB(BB &bb); + uint32 GetVstLiveStackVecSize() const { + return vstLiveStackVec.size(); + } + MapleStack *GetVstLiveStackVec(uint32 i) { + return vstLiveStackVec[i]; + } + void SetCurBB(BB *bb) { + curBB = bb; + } protected: virtual void UpdateCurFunction(BB&) const { @@ -51,37 +68,20 @@ class Prop { Dominance &dom; private: - using SafeMeExprPtr = utils::SafePtr; - void TraversalBB(BB &bb); - void PropUpdateDef(MeExpr &meExpr); void TraversalMeStmt(MeStmt &meStmt); - void PropUpdateChiListDef(const MapleMap &chiList); void CollectSubVarMeExpr(const MeExpr &expr, std::vector &exprVec) const; bool IsVersionConsistent(const std::vector &vstVec, - const std::vector> &vstLiveStack) const; + const MapleVector *> &vstLiveStack) const; bool IvarIsFinalField(const IvarMeExpr &ivarMeExpr) const; bool Propagatable(const MeExpr &expr, const BB &fromBB, bool atParm) const; - MeExpr &PropVar(VarMeExpr &varmeExpr, bool atParm, bool checkPhi) const; - MeExpr &PropReg(RegMeExpr ®meExpr, bool atParm) const; - MeExpr &PropIvar(IvarMeExpr &ivarMeExpr) const; MeExpr &PropMeExpr(MeExpr &meExpr, bool &isproped, bool atParm); - MeExpr *SimplifyMeExpr(OpMeExpr &opMeExpr) const; - MeExpr *SimplifyCvtMeExpr(const OpMeExpr &opMeExpr) const; - MeExpr *SimplifyCompareConstWithConst(OpMeExpr &opMeExpr) const; - MeExpr *SimplifyCompareConstWithAddress(const OpMeExpr &opMeExpr) const; - MeExpr *SimplifyCompareWithZero(const OpMeExpr &opMeExpr) const; - MeExpr *SimplifyCompareMeExpr(OpMeExpr &opMeExpr) const; - MeExpr *SimplifyCompareSelectConstMeExpr(const OpMeExpr &opMeExpr, const MeExpr &opMeOpnd0, MeExpr &opnd1, - MeExpr &opnd01, MeExpr &opnd02) const; IRMap &irMap; SSATab &ssaTab; MIRModule &mirModule; MapleAllocator propMapAlloc; - std::vector bbVec; - BB &commonEntryBB; - std::vector> vstLiveStackVec; - std::vector bbVisited; // needed because dominator tree is a DAG in wpo + MapleVector *> vstLiveStackVec; + MapleVector bbVisited; // needed because dominator tree is a DAG in wpo BB *curBB = nullptr; // gives the bb of the traversal PropConfig config; }; diff --git a/src/mapleall/maple_me/src/irmap.cpp b/src/mapleall/maple_me/src/irmap.cpp index 216ea48f43b8e46945a76671b5f70cf41eaf5782..f0417e0cd116ea9d18b6d02bb15c05ee97d1023a 100644 --- a/src/mapleall/maple_me/src/irmap.cpp +++ b/src/mapleall/maple_me/src/irmap.cpp @@ -16,6 +16,7 @@ #include #include "ssa.h" #include "mir_builder.h" +#include "constantfold.h" namespace maple { VarMeExpr *IRMap::CreateVarMeExprVersion(const VarMeExpr &origExpr) { @@ -221,7 +222,9 @@ IvarMeExpr *IRMap::BuildIvarFromOpMeExpr(OpMeExpr &opMeExpr) { } IvarMeExpr *IRMap::BuildLHSIvarFromIassMeStmt(IassignMeStmt &iassignMeStmt) { - return BuildLHSIvar(*iassignMeStmt.GetLHSVal()->GetBase(), iassignMeStmt, iassignMeStmt.GetLHSVal()->GetFieldID()); + IvarMeExpr *ivarx = BuildLHSIvar(*iassignMeStmt.GetLHSVal()->GetBase(), iassignMeStmt, iassignMeStmt.GetLHSVal()->GetFieldID()); + ivarx->SetVolatileFromBaseSymbol(iassignMeStmt.GetLHS()->GetVolatileFromBaseSymbol()); + return ivarx; } void IRMap::PutToBucket(uint32 hashIdx, MeExpr &meExpr) { @@ -291,9 +294,6 @@ MeExpr *IRMap::HashMeExpr(MeExpr &meExpr) { CHECK_FATAL(false, "not yet implement"); } ++exprID; - if (meExpr.GetMeOp() == kMeOpOp || meExpr.GetMeOp() == kMeOpNary) { - resultExpr->UpdateDepth(); - } PutToBucket(hashIdx, *resultExpr); } return resultExpr; @@ -554,4 +554,260 @@ MeExpr *IRMap::CreateAddrofMeExprFromSymbol(MIRSymbol &st, PUIdx puIdx) { AddrofMeExpr addrOfMe(kInvalidExprID, PTY_ptr, baseOst->GetIndex()); return HashMeExpr(addrOfMe); } + +// (typeA -> typeB -> typeC) => (typeA -> typeC) +static bool IgnoreInnerTypeCvt(PrimType typeA, PrimType typeB, PrimType typeC) { + if (IsPrimitiveInteger(typeA)) { + if (IsPrimitiveInteger(typeB)) { + if (IsPrimitiveInteger(typeC)) { + return GetPrimTypeSize(typeB) >= GetPrimTypeSize(typeA) || GetPrimTypeSize(typeB) >= GetPrimTypeSize(typeC); + } else if (IsPrimitiveFloat(typeC)) { + return GetPrimTypeSize(typeB) >= GetPrimTypeSize(typeA); + } + } else if (IsPrimitiveFloat(typeB)) { + if (IsPrimitiveFloat(typeC)) { + return GetPrimTypeSize(typeB) >= GetPrimTypeSize(typeC); + } + } + } else if (IsPrimitiveFloat(typeA)) { + if (IsPrimitiveFloat(typeB) && IsPrimitiveFloat(typeC)) { + return GetPrimTypeSize(typeB) >= GetPrimTypeSize(typeA) || GetPrimTypeSize(typeB) >= GetPrimTypeSize(typeC); + } + } + return false; +} + +MeExpr *IRMap::SimplifyOpMeExpr(OpMeExpr *opmeexpr) { + Opcode opop = opmeexpr->GetOp(); + switch (opop) { + case OP_cvt: { + // return nullptr; + OpMeExpr *cvtmeexpr = static_cast(opmeexpr); + MeExpr *opnd0 = cvtmeexpr->GetOpnd(0); + if (opnd0->GetMeOp() == kMeOpConst) { + ConstantFold cf(mirModule); + MIRConst *tocvt = + cf.FoldTypeCvtMIRConst(*static_cast(opnd0)->GetConstVal(), opnd0->GetPrimType(), cvtmeexpr->GetPrimType()); + if (tocvt) { + return CreateConstMeExpr(cvtmeexpr->GetPrimType(), *tocvt); + } + } + if (opnd0->GetOp() == OP_cvt) { + OpMeExpr *cvtopnd0 = static_cast(opnd0); + // cvtopnd0 should have tha same type as cvtopnd0->GetOpnd(0) or cvtmeexpr, + // and the type size of cvtopnd0 should be ge(>=) one of them. + // Otherwise, deleting the cvt of cvtopnd0 may result in information loss. + if (maple::GetPrimTypeSize(cvtopnd0->GetPrimType()) >= maple::GetPrimTypeSize(cvtopnd0->GetOpnd(0)->GetPrimType())) { + if ((maple::IsPrimitiveInteger(cvtopnd0->GetPrimType()) && maple::IsPrimitiveInteger(cvtopnd0->GetOpnd(0)->GetPrimType())) || + (maple::IsPrimitiveFloat(cvtopnd0->GetPrimType()) && maple::IsPrimitiveFloat(cvtopnd0->GetOpnd(0)->GetPrimType()))) { + return CreateMeExprTypeCvt(cvtmeexpr->GetPrimType(), cvtopnd0->GetOpndType(), *cvtopnd0->GetOpnd(0)); + } + } + if (maple::GetPrimTypeSize(cvtopnd0->GetPrimType()) >= maple::GetPrimTypeSize(cvtmeexpr->GetPrimType())) { + if ((maple::IsPrimitiveInteger(cvtopnd0->GetPrimType()) && maple::IsPrimitiveInteger(cvtmeexpr->GetPrimType())) || + (maple::IsPrimitiveFloat(cvtopnd0->GetPrimType()) && maple::IsPrimitiveFloat(cvtmeexpr->GetPrimType()))) { + return CreateMeExprTypeCvt(cvtmeexpr->GetPrimType(), cvtopnd0->GetOpndType(), *cvtopnd0->GetOpnd(0)); + } + } + // simplify "cvt type1 type2 (cvt type2 type3 (expr ))" to "cvt type1 type3 expr" + auto typeA = cvtopnd0->GetOpnd(0)->GetPrimType(); + auto typeB = cvtopnd0->GetPrimType(); + auto typeC = opmeexpr->GetPrimType(); + if (IgnoreInnerTypeCvt(typeA, typeB, typeC)) { + return CreateMeExprTypeCvt(typeC, typeA, utils::ToRef(cvtopnd0->GetOpnd(0))); + } + } + return nullptr; + } + case OP_add: + case OP_sub: + case OP_mul: + case OP_div: + case OP_rem: + case OP_ashr: + case OP_lshr: + case OP_shl: + case OP_max: + case OP_min: + case OP_band: + case OP_bior: + case OP_bxor: + case OP_cand: + case OP_land: + case OP_cior: + case OP_lior: + case OP_depositbits: { + if (!IsPrimitiveInteger(opmeexpr->GetPrimType())) { + return nullptr; + } + MeExpr *opnd0 = opmeexpr->GetOpnd(0); + MeExpr *opnd1 = opmeexpr->GetOpnd(1); + if (opop == OP_sub && opnd0 == opnd1) { + return CreateIntConstMeExpr(0, opmeexpr->GetPrimType()); + } + if (opnd0->GetMeOp() != kMeOpConst || opnd1->GetMeOp() != kMeOpConst) { + return nullptr; + } + maple::ConstantFold cf(mirModule); + MIRIntConst *opnd0const = static_cast(static_cast(opnd0)->GetConstVal()); + MIRIntConst *opnd1const = static_cast(static_cast(opnd1)->GetConstVal()); + if ((opop == OP_div || opop == OP_rem)) { + int64 opnd0constValue = opnd0const->GetValue(); + int64 opnd1constValue = opnd1const->GetValue(); + PrimType resPtyp = opmeexpr->GetPrimType(); + if (opnd1constValue == 0 || + (opnd1constValue == -1 && ((resPtyp == PTY_i32 && opnd0constValue == INT32_MIN) || + (resPtyp == PTY_i64 && opnd0constValue == INT64_MIN)))) { + return nullptr; + } + } + MIRConst *resconst = cf.FoldIntConstBinaryMIRConst(opmeexpr->GetOp(), + opmeexpr->GetPrimType(), opnd0const, opnd1const); + return CreateConstMeExpr(opmeexpr->GetPrimType(), *resconst); + } + case OP_ne: + case OP_eq: + case OP_lt: + case OP_le: + case OP_ge: + case OP_gt: + case OP_cmp: + case OP_cmpl: + case OP_cmpg: { + MeExpr *opnd0 = opmeexpr->GetOpnd(0); + MeExpr *opnd1 = opmeexpr->GetOpnd(1); + bool isneeq = (opop == OP_ne || opop == OP_eq); + if (opnd0->GetMeOp() == kMeOpConst && opnd1->GetMeOp() == kMeOpConst) { + maple::ConstantFold cf(mirModule); + MIRConst *opnd0const = static_cast(opnd0)->GetConstVal(); + MIRConst *opnd1const = static_cast(opnd1)->GetConstVal(); + MIRConst *resconst = cf.FoldConstComparisonMIRConst(opmeexpr->GetOp(), opmeexpr->GetPrimType(), opmeexpr->GetOpndType(), + *opnd0const, *opnd1const); + return CreateConstMeExpr(opmeexpr->GetPrimType(), *resconst); + } else if (isneeq && ((opnd0->GetMeOp() == kMeOpAddrof && opnd1->GetMeOp() == kMeOpConst) || + (opnd0->GetMeOp() == kMeOpConst && opnd1->GetMeOp() == kMeOpAddrof))) { + MIRConst *resconst = nullptr; + if (opnd0->GetMeOp() == kMeOpAddrof) { + MIRConst *constopnd1 = static_cast(opnd1)->GetConstVal(); + if (constopnd1->IsZero()) { + // addrof will not be zero, so this comparison can be replaced with a constant + resconst = mirModule.GetMemPool()->New((opop == OP_ne), *GlobalTables::GetTypeTable().GetTypeTable()[PTY_u1]); + } + } else { + MIRConst *constopnd0 = static_cast(opnd0)->GetConstVal(); + if (constopnd0->IsZero()) { + // addrof will not be zero, so this comparison can be replaced with a constant + resconst = mirModule.GetMemPool()->New((opop == OP_ne), *GlobalTables::GetTypeTable().GetTypeTable()[PTY_u1]); + } + } + if (resconst) { + return CreateConstMeExpr(opmeexpr->GetPrimType(), *resconst); + } + } else if (isneeq && opnd0->GetOp() == OP_select && + (opnd1->GetMeOp() == kMeOpConst && IsPrimitivePureScalar(opnd1->GetPrimType()))) { + OpMeExpr *opmeopnd0 = static_cast(opnd0); + if (opmeopnd0->GetOp() == OP_select) { + MeExpr *opnd01 = opmeopnd0->GetOpnd(1); + MeExpr *opnd02 = opmeopnd0->GetOpnd(2); + if (opnd01->GetMeOp() == kMeOpConst && IsPrimitivePureScalar(opnd01->GetPrimType()) && opnd02->GetMeOp() == kMeOpConst && + IsPrimitivePureScalar(opnd02->GetPrimType())) { + MIRConst *constopnd1 = static_cast(opnd1)->GetConstVal(); + MIRConst *constopnd01 = static_cast(opnd01)->GetConstVal(); + MIRConst *constopnd02 = static_cast(opnd02)->GetConstVal(); + bool needswapopnd = false; + bool canbereplaced = false; + bool isne = opmeexpr->GetOp() == OP_ne; + if (isne && constopnd1->IsZero() && constopnd01->IsOne() && constopnd02->IsZero()) { + canbereplaced = true; + } else if (isne && constopnd1->IsZero() && constopnd01->IsZero() && constopnd02->IsOne()) { + canbereplaced = true; + } else if (isne && constopnd1->IsOne() && constopnd01->IsOne() && constopnd02->IsZero()) { + needswapopnd = true; + canbereplaced = true; + } else if (isne && constopnd1->IsOne() && constopnd01->IsZero() && constopnd02->IsOne()) { + needswapopnd = true; + canbereplaced = true; + } else if (!isne && constopnd1->IsZero() && constopnd01->IsOne() && constopnd02->IsZero()) { + needswapopnd = true; + canbereplaced = true; + } else if (!isne && constopnd1->IsZero() && constopnd01->IsZero() && constopnd02->IsOne()) { + needswapopnd = true; + canbereplaced = true; + } else if (!isne && constopnd1->IsOne() && constopnd01->IsOne() && constopnd02->IsZero()) { + canbereplaced = true; + } else if (!isne && constopnd1->IsOne() && constopnd01->IsZero() && constopnd02->IsOne()) { + canbereplaced = true; + } + if (canbereplaced) { + OpMeExpr newopmeexpr(-1, OP_select, PTY_u1, 3); + newopmeexpr.SetOpnd(0, opmeopnd0->GetOpnd(0)); + ConstMeExpr xnewopnd01(-1, constopnd01, PTY_u1); + MeExpr *newopnd01 = HashMeExpr(xnewopnd01); + ConstMeExpr xnewopnd02(-1, constopnd02, PTY_u1); + MeExpr *newopnd02 = HashMeExpr(xnewopnd02); + if (needswapopnd) { + newopmeexpr.SetOpnd(1, newopnd02); + newopmeexpr.SetOpnd(2, newopnd01); + } else { + newopmeexpr.SetOpnd(1, newopnd01); + newopmeexpr.SetOpnd(2, newopnd02); + } + return HashMeExpr(newopmeexpr); + } + } + } + } else if (isneeq && opnd0->GetOp() == OP_cmp && opnd1->GetMeOp() == kMeOpConst) { + auto *constVal = static_cast(opnd1)->GetConstVal(); + if (constVal->GetKind() == kConstInt && constVal->IsZero()) { + auto *subOpnd0 = opnd0->GetOpnd(0); + auto *subOpnd1 = opnd0->GetOpnd(1); + return CreateMeExprCompare(opop, PTY_u1, subOpnd0->GetPrimType(), *subOpnd0, *subOpnd1); + } + } + return nullptr; + } + default: + return nullptr; + } +} + +MeExpr *IRMap::SimplifyMeExpr(MeExpr *x) { + switch (x->GetMeOp()) { + case kMeOpAddrof: + case kMeOpAddroffunc: + case kMeOpConst: + case kMeOpConststr: + case kMeOpConststr16: + case kMeOpSizeoftype: + case kMeOpFieldsDist: + case kMeOpVar: + case kMeOpReg: + case kMeOpIvar: return x; + case kMeOpOp: { + OpMeExpr *opexp = static_cast(x); + opexp->SetOpnd(0, SimplifyMeExpr(opexp->GetOpnd(0))); + if (opexp->GetNumOpnds() > 1) { + opexp->SetOpnd(1, SimplifyMeExpr(opexp->GetOpnd(1))); + if (opexp->GetNumOpnds() > 2) { + opexp->SetOpnd(2, SimplifyMeExpr(opexp->GetOpnd(2))); + } + } + MeExpr *newexp = SimplifyOpMeExpr(opexp); + if (newexp) { + return newexp; + } + return opexp; + } + case kMeOpNary: { + NaryMeExpr *opexp = static_cast(x); + for (uint32 i = 0; i < opexp->GetNumOpnds(); i++) { + opexp->SetOpnd(i, SimplifyMeExpr(opexp->GetOpnd(i))); + } + // TODO do the simplification of this op + return opexp; + } + default: ; + } + return x; +} } // namespace maple diff --git a/src/mapleall/maple_me/src/irmap_build.cpp b/src/mapleall/maple_me/src/irmap_build.cpp index 5575a21b8b2116b519f79409b60292185ea15e47..5633fce7f3d22603ee0731e4f8e76768182d7c33 100644 --- a/src/mapleall/maple_me/src/irmap_build.cpp +++ b/src/mapleall/maple_me/src/irmap_build.cpp @@ -15,6 +15,7 @@ #include "factory.h" #include "irmap_build.h" +#include "prop.h" // Methods to convert Maple IR to MeIR @@ -129,26 +130,26 @@ void IRMapBuild::BuildMuList(TypeOfMayUseList &mayUseList, MapleMap(meExpr); if (mirNode.IsUnaryNode()) { if (mirNode.GetOpCode() != OP_iread) { - opMeExpr.SetOpnd(0, BuildExpr(*static_cast(mirNode).Opnd(0))); + opMeExpr.SetOpnd(0, BuildExpr(*static_cast(mirNode).Opnd(0), atParm, noProp)); } } else if (mirNode.IsBinaryNode()) { auto &binaryNode = static_cast(mirNode); - opMeExpr.SetOpnd(0, BuildExpr(*binaryNode.Opnd(0))); - opMeExpr.SetOpnd(1, BuildExpr(*binaryNode.Opnd(1))); + opMeExpr.SetOpnd(0, BuildExpr(*binaryNode.Opnd(0), atParm, noProp)); + opMeExpr.SetOpnd(1, BuildExpr(*binaryNode.Opnd(1), atParm, noProp)); } else if (mirNode.IsTernaryNode()) { auto &ternaryNode = static_cast(mirNode); - opMeExpr.SetOpnd(0, BuildExpr(*ternaryNode.Opnd(0))); - opMeExpr.SetOpnd(1, BuildExpr(*ternaryNode.Opnd(1))); - opMeExpr.SetOpnd(2, BuildExpr(*ternaryNode.Opnd(2))); + opMeExpr.SetOpnd(0, BuildExpr(*ternaryNode.Opnd(0), atParm, noProp)); + opMeExpr.SetOpnd(1, BuildExpr(*ternaryNode.Opnd(1), atParm, noProp)); + opMeExpr.SetOpnd(2, BuildExpr(*ternaryNode.Opnd(2), atParm, noProp)); } else if (mirNode.IsNaryNode()) { auto &naryMeExpr = static_cast(meExpr); auto &naryNode = static_cast(mirNode); for (size_t i = 0; i < naryNode.NumOpnds(); ++i) { - naryMeExpr.GetOpnds().push_back(BuildExpr(*naryNode.Opnd(i))); + naryMeExpr.GetOpnds().push_back(BuildExpr(*naryNode.Opnd(i), atParm, noProp)); } } else { // No need to do anything @@ -288,7 +289,7 @@ MeExpr *IRMapBuild::BuildNaryMeExprForIntrinsicWithType(const BaseNode &mirNode) return meExpr; } -MeExpr *IRMapBuild::BuildExpr(BaseNode &mirNode) { +MeExpr *IRMapBuild::BuildExpr(BaseNode &mirNode, bool atParm, bool noProp) { Opcode op = mirNode.GetOpCode(); if (op == OP_dread) { auto &addrOfNode = static_cast(mirNode); @@ -296,7 +297,31 @@ MeExpr *IRMapBuild::BuildExpr(BaseNode &mirNode) { VarMeExpr *varMeExpr = GetOrCreateVarFromVerSt(*vst); ASSERT(!vst->GetOrigSt()->IsPregOst(), "not expect preg symbol here"); varMeExpr->SetPtyp(GlobalTables::GetTypeTable().GetTypeFromTyIdx(vst->GetOrigSt()->GetTyIdx())->GetPrimType()); - return varMeExpr; + varMeExpr->GetOst()->SetFieldID(addrOfNode.GetFieldID()); + MeExpr *retmeexpr; + if (propagater && !noProp) { + MeExpr *propedMeExpr = &propagater->PropVar(*varMeExpr, atParm, true); + MeExpr *simplifiedMeexpr = nullptr; + if (propedMeExpr->GetMeOp() == kMeOpOp) { + simplifiedMeexpr = irMap->SimplifyOpMeExpr(static_cast(propedMeExpr)); + } + retmeexpr = simplifiedMeexpr ? simplifiedMeexpr : propedMeExpr; + } else { + retmeexpr = varMeExpr; + } + uint32 typesize = GetPrimTypeSize(retmeexpr->GetPrimType()); + if (typesize < GetPrimTypeSize(addrOfNode.GetPrimType()) && typesize != 0) { + // need to insert a convert + if (typesize < 4) { + OpMeExpr opmeexpr(-1, IsSignedInteger(addrOfNode.GetPrimType()) ? OP_sext : OP_zext, addrOfNode.GetPrimType(), 1); + opmeexpr.SetBitsSize(typesize * 8); + opmeexpr.SetOpnd(0, retmeexpr); + retmeexpr = irMap->HashMeExpr(opmeexpr); + } else { + retmeexpr = irMap->CreateMeExprTypeCvt(addrOfNode.GetPrimType(), retmeexpr->GetPrimType(), *retmeexpr); + } + } + return retmeexpr; } if (op == OP_regread) { @@ -310,26 +335,52 @@ MeExpr *IRMapBuild::BuildExpr(BaseNode &mirNode) { auto func = CreateProductFunction(mirNode.GetOpCode()); ASSERT(func != nullptr, "NIY BuildExpe"); MeExpr *meExpr = func(this, mirNode); - SetMeExprOpnds(*meExpr, mirNode); + SetMeExprOpnds(*meExpr, mirNode, atParm, noProp); if (op == OP_iread) { - auto *ivarMeExpr = static_cast(meExpr); - auto &iReadSSANode = static_cast(mirNode); - ivarMeExpr->SetBase(BuildExpr(*iReadSSANode.Opnd(0))); + IvarMeExpr *ivarMeExpr = static_cast(meExpr); + IreadSSANode &iReadSSANode = static_cast(mirNode); + ivarMeExpr->SetBase(BuildExpr(*iReadSSANode.Opnd(0), atParm, true)); VersionSt *verSt = iReadSSANode.GetSSAVar(); if (verSt != nullptr) { VarMeExpr *varMeExpr = GetOrCreateVarFromVerSt(*verSt); ivarMeExpr->SetMuVal(varMeExpr); + if (verSt->GetOrigSt()->IsVolatile()) { + ivarMeExpr->SetVolatileFromBaseSymbol(true); + } + } + IvarMeExpr *canIvar = static_cast(irMap->HashMeExpr(*ivarMeExpr)); + delete ivarMeExpr; + ASSERT(static_cast(canIvar)->GetMu() != nullptr, "BuildExpr: ivar node cannot have mu == nullptr"); + MeExpr *retmeexpr; + if (propagater && !noProp) { + MeExpr *propedMeExpr = &propagater->PropIvar(*canIvar); + MeExpr *simplifiedMeexpr = nullptr; + if (propedMeExpr->GetMeOp() == kMeOpOp) { + simplifiedMeexpr = irMap->SimplifyOpMeExpr(static_cast(propedMeExpr)); + } + retmeexpr = simplifiedMeexpr ? simplifiedMeexpr : propedMeExpr; + } else { + retmeexpr = canIvar; } + uint32 typesize = GetPrimTypeSize(retmeexpr->GetPrimType()); + if (typesize < GetPrimTypeSize(iReadSSANode.GetPrimType()) && typesize != 0) { + // need to insert a convert + if (typesize < 4) { + OpMeExpr opmeexpr(-1, IsSignedInteger(iReadSSANode.GetPrimType()) ? OP_sext : OP_zext, iReadSSANode.GetPrimType(), 1); + opmeexpr.SetBitsSize(typesize * 8); + opmeexpr.SetOpnd(0, retmeexpr); + retmeexpr = irMap->HashMeExpr(opmeexpr); + } else { + retmeexpr = irMap->CreateMeExprTypeCvt(iReadSSANode.GetPrimType(), retmeexpr->GetPrimType(), *retmeexpr); + } + } + return retmeexpr; } MeExpr *retMeExpr = irMap->HashMeExpr(*meExpr); delete meExpr; - if (op == OP_iread) { - ASSERT(static_cast(retMeExpr)->GetMu() != nullptr, "BuildExpr: ivar node cannot have mu == nullptr"); - } - return retMeExpr; } @@ -421,7 +472,7 @@ MeStmt *IRMapBuild::BuildMeStmtWithNoSSAPart(StmtNode &stmt) { case OP_brtrue: { auto &condGotoNode = static_cast(stmt); auto *condGotoMeStmt = irMap->New(&stmt); - condGotoMeStmt->SetOpnd(0, BuildExpr(*condGotoNode.Opnd(0))); + condGotoMeStmt->SetOpnd(0, BuildExpr(*condGotoNode.Opnd(0), false, false)); return condGotoMeStmt; } case OP_try: { @@ -440,7 +491,7 @@ MeStmt *IRMapBuild::BuildMeStmtWithNoSSAPart(StmtNode &stmt) { auto &unaryStmt = static_cast(stmt); auto *unMeStmt = static_cast((op == OP_switch) ? irMap->NewInPool(&stmt) : irMap->New(&stmt)); - unMeStmt->SetOpnd(0, BuildExpr(*unaryStmt.Opnd(0))); + unMeStmt->SetOpnd(0, BuildExpr(*unaryStmt.Opnd(0), false, false)); return unMeStmt; } default: @@ -449,21 +500,28 @@ MeStmt *IRMapBuild::BuildMeStmtWithNoSSAPart(StmtNode &stmt) { } MeStmt *IRMapBuild::BuildDassignMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { - auto *meStmt = irMap->NewInPool(&stmt); - auto &dassiNode = static_cast(stmt); - meStmt->SetRHS(BuildExpr(*dassiNode.GetRHS())); - auto *varLHS = static_cast(BuildLHSVar(*ssaPart.GetSSAVar(), *meStmt)); + DassignMeStmt *meStmt = irMap->NewInPool(&stmt); + DassignNode &dassiNode = static_cast(stmt); + meStmt->SetRHS(BuildExpr(*dassiNode.GetRHS(), false, false)); + VarMeExpr *varLHS = static_cast(BuildLHSVar(*ssaPart.GetSSAVar(), *meStmt)); meStmt->SetLHS(varLHS); BuildChiList(*meStmt, ssaPart.GetMayDefNodes(), *meStmt->GetChiList()); + if (propagater) { + propagater->PropUpdateDef(*meStmt->GetLHS()); + propagater->PropUpdateChiListDef(*meStmt->GetChiList()); + } return meStmt; } MeStmt *IRMapBuild::BuildRegassignMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { auto *meStmt = irMap->New(&stmt); auto ®Node = static_cast(stmt); - meStmt->SetRHS(BuildExpr(*regNode.Opnd(0))); + meStmt->SetRHS(BuildExpr(*regNode.Opnd(0), false, false)); auto *regLHS = static_cast(BuildLHSReg(*ssaPart.GetSSAVar(), *meStmt, regNode)); meStmt->SetLHS(regLHS); + if (propagater) { + propagater->PropUpdateDef(*meStmt->GetLHS()); + } return meStmt; } @@ -471,19 +529,38 @@ MeStmt *IRMapBuild::BuildIassignMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) auto &iasNode = static_cast(stmt); auto *meStmt = irMap->NewInPool(&stmt); meStmt->SetTyIdx(iasNode.GetTyIdx()); - meStmt->SetRHS(BuildExpr(*iasNode.GetRHS())); - meStmt->SetLHSVal(irMap->BuildLHSIvar(*BuildExpr(*iasNode.Opnd(0)), *meStmt, iasNode.GetFieldID())); + meStmt->SetRHS(BuildExpr(*iasNode.GetRHS(), false, false)); + meStmt->SetLHSVal(irMap->BuildLHSIvar(*BuildExpr(*iasNode.Opnd(0), false, false), *meStmt, iasNode.GetFieldID())); + if (mirModule.IsCModule()) { + bool isVolt = false; + for (MayDefNode maydef : ssaPart.GetMayDefNodes()) { + const OriginalSt *ost = maydef.GetResult()->GetOrigSt(); + if (ost->IsVolatile()) { + isVolt = true; + break; + } + } + if (isVolt) { + meStmt->GetLHS()->SetVolatileFromBaseSymbol(true); + } + } BuildChiList(*meStmt, ssaPart.GetMayDefNodes(), *(meStmt->GetChiList())); + if (propagater) { + propagater->PropUpdateChiListDef(*meStmt->GetChiList()); + } return meStmt; } MeStmt *IRMapBuild::BuildMaydassignMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { auto *meStmt = irMap->NewInPool(&stmt); auto &dassiNode = static_cast(stmt); - meStmt->SetRHS(BuildExpr(*dassiNode.GetRHS())); + meStmt->SetRHS(BuildExpr(*dassiNode.GetRHS(), false, false)); meStmt->SetMayDassignSym(ssaPart.GetSSAVar()->GetOst()); meStmt->SetFieldID(dassiNode.GetFieldID()); BuildChiList(*meStmt, ssaPart.GetMayDefNodes(), *(meStmt->GetChiList())); + if (propagater) { + propagater->PropUpdateChiListDef(*meStmt->GetChiList()); + } return meStmt; } @@ -492,13 +569,19 @@ MeStmt *IRMapBuild::BuildCallMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { auto &intrinNode = static_cast(stmt); callMeStmt->SetPUIdx(intrinNode.GetPUIdx()); for (size_t i = 0; i < intrinNode.NumOpnds(); ++i) { - callMeStmt->PushBackOpnd(BuildExpr(*intrinNode.Opnd(i))); + callMeStmt->PushBackOpnd(BuildExpr(*intrinNode.Opnd(i), true, false)); } BuildMuList(ssaPart.GetMayUseNodes(), *(callMeStmt->GetMuList())); if (kOpcodeInfo.IsCallAssigned(stmt.GetOpCode())) { BuildMustDefList(*callMeStmt, ssaPart.GetMustDefNodes(), *(callMeStmt->GetMustDefList())); } BuildChiList(*callMeStmt, ssaPart.GetMayDefNodes(), *(callMeStmt->GetChiList())); + if (propagater) { + propagater->PropUpdateChiListDef(*callMeStmt->GetChiList()); + if (kOpcodeInfo.IsCallAssigned(stmt.GetOpCode())) { + propagater->PropUpdateMustDefList(callMeStmt); + } + } return callMeStmt; } @@ -510,13 +593,16 @@ MeStmt *IRMapBuild::BuildNaryMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { : static_cast(irMap->NewInPool(&stmt)); auto &naryStmtNode = static_cast(stmt); for (size_t i = 0; i < naryStmtNode.NumOpnds(); ++i) { - naryMeStmt->PushBackOpnd(BuildExpr(*naryStmtNode.Opnd(i))); + naryMeStmt->PushBackOpnd(BuildExpr(*naryStmtNode.Opnd(i), false, false)); } BuildMuList(ssaPart.GetMayUseNodes(), *(naryMeStmt->GetMuList())); if (kOpcodeInfo.IsCallAssigned(op)) { BuildMustDefList(*naryMeStmt, ssaPart.GetMustDefNodes(), *(naryMeStmt->GetMustDefList())); } BuildChiList(*naryMeStmt, ssaPart.GetMayDefNodes(), *(naryMeStmt->GetChiList())); + if (propagater) { + propagater->PropUpdateChiListDef(*naryMeStmt->GetChiList()); + } return naryMeStmt; } @@ -524,7 +610,7 @@ MeStmt *IRMapBuild::BuildRetMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { auto &retStmt = static_cast(stmt); auto *meStmt = irMap->NewInPool(&stmt); for (size_t i = 0; i < retStmt.NumOpnds(); ++i) { - meStmt->PushBackOpnd(BuildExpr(*retStmt.Opnd(i))); + meStmt->PushBackOpnd(BuildExpr(*retStmt.Opnd(i), false, false)); } BuildMuList(ssaPart.GetMayUseNodes(), *(meStmt->GetMuList())); return meStmt; @@ -545,7 +631,7 @@ MeStmt *IRMapBuild::BuildGosubMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { MeStmt *IRMapBuild::BuildThrowMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { auto &unaryNode = static_cast(stmt); auto *tmeStmt = irMap->NewInPool(&stmt); - tmeStmt->SetMeStmtOpndValue(BuildExpr(*unaryNode.Opnd(0))); + tmeStmt->SetMeStmtOpndValue(BuildExpr(*unaryNode.Opnd(0), false, false)); BuildMuList(ssaPart.GetMayUseNodes(), *(tmeStmt->GetMuList())); return tmeStmt; } @@ -554,7 +640,7 @@ MeStmt *IRMapBuild::BuildSyncMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { auto &naryNode = static_cast(stmt); auto *naryStmt = irMap->NewInPool(&stmt); for (size_t i = 0; i < naryNode.NumOpnds(); ++i) { - naryStmt->PushBackOpnd(BuildExpr(*naryNode.Opnd(i))); + naryStmt->PushBackOpnd(BuildExpr(*naryNode.Opnd(i), false, false)); } BuildMuList(ssaPart.GetMayUseNodes(), *(naryStmt->GetMuList())); BuildChiList(*naryStmt, ssaPart.GetMayDefNodes(), *(naryStmt->GetChiList())); @@ -620,6 +706,23 @@ void IRMapBuild::BuildBB(BB &bb, std::vector &bbIRMapProcessed) { irMap->SetCurFunction(bb); // iterate phi list to update the definition by phi BuildPhiMeNode(bb); + std::vector curStackSizeVec; + if (propagater) { // proper is not null that means we will do propragation during build meir. + propagater->SetCurBB(&bb); + uint32 vstVecsize = propagater->GetVstLiveStackVecSize(); + curStackSizeVec.resize(vstVecsize); + for (uint32 i = 1; i < vstVecsize; i++) { + curStackSizeVec[i] = 0; + curStackSizeVec[i] = propagater->GetVstLiveStackVec(i)->size(); + } + // traversal phi nodes + MapleMap &mePhiList = bb.GetMePhiList(); + for (MapleMap::iterator it = mePhiList.begin(); it != mePhiList.end(); it++) { + MePhiNode *phimenode = it->second; + propagater->PropUpdateDef(*phimenode->GetLHS()); + } + } + if (!bb.IsEmpty()) { for (auto &stmt : bb.GetStmtNodes()) { MeStmt *meStmt = BuildMeStmt(stmt); @@ -633,5 +736,15 @@ void IRMapBuild::BuildBB(BB &bb, std::vector &bbIRMapProcessed) { BBId childBBId = *bbIt; BuildBB(*irMap->GetBB(childBBId), bbIRMapProcessed); } + if (propagater) { + for (uint32 i = 1; i < propagater->GetVstLiveStackVecSize(); i++) { + MapleStack *liveStack = propagater->GetVstLiveStackVec(i); + uint32 curSize = curStackSizeVec[i]; + while (liveStack->size() > curSize) { + liveStack->pop(); + } + } + } } + } // namespace maple diff --git a/src/mapleall/maple_me/src/me_ir.cpp b/src/mapleall/maple_me/src/me_ir.cpp index 24f311d9693a86324d76f5585ab4a36fa88f8460..98b47bea47cf28e17c8eaa21b263af1b67229af4 100644 --- a/src/mapleall/maple_me/src/me_ir.cpp +++ b/src/mapleall/maple_me/src/me_ir.cpp @@ -56,22 +56,6 @@ bool MeExpr::IsTheSameWorkcand(const MeExpr &expr) const { return IsUseSameSymbol(expr); } -void MeExpr::UpdateDepth() { - uint8 maxDepth = 0; - for (int32 i = 0; i < GetNumOpnds(); ++i) { - MeExpr *opnd = GetOpnd(i); - if (opnd == nullptr) { - continue; - } - uint8 curDepth = opnd->GetDepth(); - if (curDepth > maxDepth) { - maxDepth = curDepth; - } - } - ASSERT(maxDepth < UINT8_MAX, "runtime check error"); - depth = static_cast(maxDepth + 1); -} - // get the definition of this // for example: // v2 = x + b @@ -364,6 +348,9 @@ bool IvarMeExpr::IsUseSameSymbol(const MeExpr &expr) const { } bool IvarMeExpr::IsVolatile() const { + if (volatileFromBaseSymbol) { + return true; + } auto *type = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx)); MIRType *pointedType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(type->GetPointedTyIdx()); if (fieldID == 0) { diff --git a/src/mapleall/maple_me/src/me_irmap_build.cpp b/src/mapleall/maple_me/src/me_irmap_build.cpp index 1972185c42f3311a892e2faa22ad85af7abf7cc8..29a2f29fa68f2483cf81beb33c69a0025d0b88d4 100644 --- a/src/mapleall/maple_me/src/me_irmap_build.cpp +++ b/src/mapleall/maple_me/src/me_irmap_build.cpp @@ -34,9 +34,19 @@ AnalysisResult *MeDoIRMapBuild::Run(MeFunction *func, MeFuncResultMgr *funcResMg #if DEBUG globalIRMap = irMap; #endif - IRMapBuild irmapbuild(irMap, dom); - std::vector bbIrmapProcessed(func->NumBBs(), false); - irmapbuild.BuildBB(*func->GetCommonEntryBB(), bbIrmapProcessed); + MemPool *propMp = nullptr; + if (!func->GetMIRModule().IsJavaModule()) { + // create propgation + propMp = memPoolCtrler.NewMemPool("meirbuild prop"); + MeProp meprop(*irMap, *dom, *propMp, Prop::PropConfig{false, false, false, false, false, false}); + IRMapBuild irmapbuild(irMap, dom, &meprop); + std::vector bbIrmapProcessed(func->NumBBs(), false); + irmapbuild.BuildBB(*func->GetCommonEntryBB(), bbIrmapProcessed); + } else { + IRMapBuild irmapbuild(irMap, dom, nullptr); + std::vector bbIrmapProcessed(func->NumBBs(), false); + irmapbuild.BuildBB(*func->GetCommonEntryBB(), bbIrmapProcessed); + } if (DEBUGFUNC(func)) { irMap->Dump(); } @@ -61,6 +71,11 @@ AnalysisResult *MeDoIRMapBuild::Run(MeFunction *func, MeFuncResultMgr *funcResMg bb->SetLast(nullptr); } func->GetMeSSATab()->GetVersionStTable().GetVSTAlloc().GetMemPool()->Release(); + funcResMgr->InvalidAnalysisResult(MeFuncPhase_SSA, func); + funcResMgr->InvalidAnalysisResult(MeFuncPhase_DSE, func); + if (propMp) { + memPoolCtrler.DeleteMemPool(propMp); + } return irMap; } -} // namespace maple \ No newline at end of file +} // namespace maple diff --git a/src/mapleall/maple_me/src/me_prop.cpp b/src/mapleall/maple_me/src/me_prop.cpp index 01a24643b3baa351b1022775c714d1524d5288bc..086e73097f6322577d8bea5de726be819fcb9f93 100644 --- a/src/mapleall/maple_me/src/me_prop.cpp +++ b/src/mapleall/maple_me/src/me_prop.cpp @@ -34,7 +34,7 @@ AnalysisResult *MeDoMeProp::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResu bool propIloadRef = MeOption::propIloadRef; MeProp meProp(*hMap, *dom, *NewMemPool(), Prop::PropConfig { MeOption::propBase, propIloadRef, MeOption::propGlobalRef, MeOption::propFinaliLoadRef, MeOption::propIloadRefNonParm, MeOption::propAtPhi }); - meProp.DoProp(); + meProp.TraversalBB(*func->GetCommonEntryBB()); if (DEBUGFUNC(func)) { LogInfo::MapleLogger() << "\n============== After Copy Propagation =============" << '\n'; func->Dump(false); diff --git a/src/mapleall/maple_me/src/prop.cpp b/src/mapleall/maple_me/src/prop.cpp index e91bcdccc8ad9bf95eec5bffcbd04c672e40b002..c363ddabdaabf757783998b4d9b03939afcd5e26 100644 --- a/src/mapleall/maple_me/src/prop.cpp +++ b/src/mapleall/maple_me/src/prop.cpp @@ -16,211 +16,32 @@ #include "me_irmap.h" #include "dominance.h" -namespace { using namespace maple; const int kPropTreeLevel = 15; // tree height threshold to increase to -// (typeA -> typeB -> typeC) => (typeA -> typeC) -bool IgnoreInnerTypeCvt(PrimType typeA, PrimType typeB, PrimType typeC) { - if (IsPrimitiveInteger(typeA)) { - if (IsPrimitiveInteger(typeB)) { - if (IsPrimitiveInteger(typeC)) { - return GetPrimTypeSize(typeB) >= GetPrimTypeSize(typeA) || GetPrimTypeSize(typeB) >= GetPrimTypeSize(typeC); - } else if (IsPrimitiveFloat(typeC)) { - return GetPrimTypeSize(typeB) >= GetPrimTypeSize(typeA); - } - } else if (IsPrimitiveFloat(typeB)) { - if (IsPrimitiveFloat(typeC)) { - return GetPrimTypeSize(typeB) >= GetPrimTypeSize(typeC); - } - } - } else if (IsPrimitiveFloat(typeA)) { - if (IsPrimitiveFloat(typeB) && IsPrimitiveFloat(typeC)) { - return GetPrimTypeSize(typeB) >= GetPrimTypeSize(typeA) || GetPrimTypeSize(typeB) >= GetPrimTypeSize(typeC); - } - } - return false; -} -} // namespace - namespace maple { -Prop::Prop(IRMap &irMap, Dominance &dom, MemPool &memPool, std::vector &&bbVec, BB &commonEntryBB, - const PropConfig &config) +Prop::Prop(IRMap &irMap, Dominance &dom, MemPool &memPool, uint32 bbvecsize, const PropConfig &config) : dom(dom), irMap(irMap), ssaTab(irMap.GetSSATab()), mirModule(irMap.GetSSATab().GetModule()), propMapAlloc(&memPool), - bbVec(bbVec), - commonEntryBB(commonEntryBB), - vstLiveStackVec(), - bbVisited(bbVec.size(), false), + vstLiveStackVec(propMapAlloc.Adapter()), + bbVisited(bbvecsize, false, propMapAlloc.Adapter()), config(config) { const MapleVector &originalStVec = ssaTab.GetOriginalStTable().GetOriginalStVector(); vstLiveStackVec.resize(originalStVec.size()); for (size_t i = 1; i < originalStVec.size(); ++i) { OriginalSt *ost = originalStVec[i]; ASSERT(ost->GetIndex() == i, "inconsistent originalst_table index"); + MapleStack *verstStack = propMapAlloc.GetMemPool()->New>(propMapAlloc.Adapter()); MeExpr *expr = irMap.GetMeExpr(ost->GetZeroVersionIndex()); if (expr != nullptr) { - vstLiveStackVec[i].push(expr); - } - } -} - -MeExpr *Prop::SimplifyCvtMeExpr(const OpMeExpr &opMeExpr) const { - MeExpr *opnd0 = opMeExpr.GetOpnd(0); - - // convert a const expr - if (opnd0->GetMeOp() == kMeOpConst) { - return nullptr; - } - - // convert a convert expr - if (opnd0->GetOp() == OP_cvt) { - auto *cvtOpnd0 = static_cast(opnd0); - // simplify "cvt type1 type2 (cvt type2 type3 (expr ))" to "cvt type1 type3 expr" - auto typeA = cvtOpnd0->GetOpnd(0)->GetPrimType(); - auto typeB = cvtOpnd0->GetPrimType(); - auto typeC = opMeExpr.GetPrimType(); - if (IgnoreInnerTypeCvt(typeA, typeB, typeC)) { - return irMap.CreateMeExprTypeCvt(typeC, typeA, utils::ToRef(cvtOpnd0->GetOpnd(0))); - } - } - return nullptr; -} - -MeExpr *Prop::SimplifyCompareSelectConstMeExpr(const OpMeExpr &opMeExpr, const MeExpr &opMeOpnd0, MeExpr &opnd1, - MeExpr &opnd01, MeExpr &opnd02) const { - // b, c and compare operand are all constant - auto *constOpnd1 = static_cast(opnd1).GetConstVal(); - auto *constOpnd01 = static_cast(opnd01).GetConstVal(); - auto *constOpnd02 = static_cast(opnd02).GetConstVal(); - - bool isNe = opMeExpr.GetOp() == OP_ne; - if (constOpnd01->IsZero() && constOpnd02->IsOne()) { - if ((!isNe && constOpnd1->IsZero()) || - (isNe && constOpnd1->IsOne())) { - std::swap(constOpnd01, constOpnd02); - } - } else if (constOpnd01->IsOne() && constOpnd02->IsZero()) { - if ((!isNe && constOpnd1->IsZero()) || - (isNe && constOpnd1->IsOne())) { - std::swap(constOpnd01, constOpnd02); + verstStack->push(expr); } - } else { - return nullptr; + vstLiveStackVec[i] = verstStack; } - - // negative one is invalid ExprID - OpMeExpr newopMeExpr(-1, OP_select, PTY_u1, 3); - newopMeExpr.SetOpnd(0, opMeOpnd0.GetOpnd(0)); - - ConstMeExpr exNewOpnds01(-1, constOpnd01, PTY_u1); - MeExpr *newOpnd01 = irMap.HashMeExpr(exNewOpnds01); - - ConstMeExpr exNewOpnds02(-1, constOpnd02, PTY_u1); - MeExpr *newOpnds02 = irMap.HashMeExpr(exNewOpnds02); - - newopMeExpr.SetOpnd(1, newOpnd01); - newopMeExpr.SetOpnd(2, newOpnds02); - - return irMap.HashMeExpr(newopMeExpr); -} - -MeExpr *Prop::SimplifyCompareConstWithConst(OpMeExpr &opMeExpr) const { - return nullptr; -} - -MeExpr *Prop::SimplifyCompareConstWithAddress(const OpMeExpr &opMeExpr) const { - MeExpr *opnd0 = opMeExpr.GetOpnd(0); - MeExpr *opnd1 = opMeExpr.GetOpnd(1); - Opcode opcode = opMeExpr.GetOp(); - bool isNeOrEq = (opcode == OP_ne || opcode == OP_eq); - if (isNeOrEq) { - MIRConst *constOpnd = nullptr; - if (opnd0->GetMeOp() == kMeOpAddrof && opnd1->GetMeOp() == kMeOpConst) { - constOpnd = static_cast(opnd1)->GetConstVal(); - } else if (opnd0->GetMeOp() == kMeOpConst && opnd1->GetMeOp() == kMeOpAddrof) { - constOpnd = static_cast(opnd0)->GetConstVal(); - } - - if (constOpnd != nullptr && constOpnd->IsZero()) { - // addrof will not be zero, so this comparison can be replaced with a constant - auto *resConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst( - static_cast(opcode == OP_ne), utils::ToRef(GlobalTables::GetTypeTable().GetUInt1())); - return irMap.CreateConstMeExpr(opMeExpr.GetPrimType(), *resConst); - } - } - return nullptr; -} - -MeExpr *Prop::SimplifyCompareWithZero(const OpMeExpr &opMeExpr) const { - Opcode opcode = opMeExpr.GetOp(); - MeExpr *opnd0 = opMeExpr.GetOpnd(0); - MeExpr *opnd1 = opMeExpr.GetOpnd(1); - if (opnd0->GetOp() == OP_cmp && opnd1->GetMeOp() == kMeOpConst) { - auto *constVal = static_cast(opnd1)->GetConstVal(); - if (constVal->GetKind() == kConstInt && constVal->IsZero()) { - auto *subOpnd0 = opnd0->GetOpnd(0); - auto *subOpnd1 = opnd0->GetOpnd(1); - return irMap.CreateMeExprCompare(opcode, PTY_u1, subOpnd0->GetPrimType(), *subOpnd0, *subOpnd1); - } - } - return nullptr; -} - -MeExpr *Prop::SimplifyCompareMeExpr(OpMeExpr &opMeExpr) const { - // compare constant with constant - auto *newConstExpr = SimplifyCompareConstWithConst(opMeExpr); - if (newConstExpr != nullptr) { - return newConstExpr; - } - - // compare constant with addrof - auto *newOpExpr = SimplifyCompareConstWithAddress(opMeExpr); - if (newOpExpr != nullptr) { - return newOpExpr; - } - - MeExpr *opnd0 = opMeExpr.GetOpnd(0); - MeExpr *opnd1 = opMeExpr.GetOpnd(1); - Opcode opcode = opMeExpr.GetOp(); - bool isNeOrEq = (opcode == OP_ne || opcode == OP_eq); - // compare select (a ? b : c) with constant 0 or 1 - if (isNeOrEq && opnd0->GetOp() == OP_select && - (opnd1->GetMeOp() == kMeOpConst && IsPrimitivePureScalar(opnd1->GetPrimType()))) { - auto *opMeOpnd0 = static_cast(opnd0); - MeExpr *opnd01 = opMeOpnd0->GetOpnd(1); - MeExpr *opnd02 = opMeOpnd0->GetOpnd(2); - if (!(opnd01->GetMeOp() == kMeOpConst && IsPrimitivePureScalar(opnd01->GetPrimType()) && - opnd02->GetMeOp() == kMeOpConst && IsPrimitivePureScalar(opnd02->GetPrimType()))) { - return nullptr; - } - - return SimplifyCompareSelectConstMeExpr(opMeExpr, *opMeOpnd0, *opnd1, *opnd01, *opnd02); - } - - // compare compareRes with zero - newOpExpr = SimplifyCompareWithZero(opMeExpr); - if (newOpExpr != nullptr) { - return newOpExpr; - } - return nullptr; -} - -MeExpr *Prop::SimplifyMeExpr(OpMeExpr &opMeExpr) const { - Opcode opcode = opMeExpr.GetOp(); - if (kOpcodeInfo.IsCompare(opcode)) { - return SimplifyCompareMeExpr(opMeExpr); - } - - if (opcode == OP_cvt) { - return SimplifyCvtMeExpr(opMeExpr); - } - - return nullptr; } void Prop::PropUpdateDef(MeExpr &meExpr) { @@ -235,7 +56,7 @@ void Prop::PropUpdateDef(MeExpr &meExpr) { } ostIdx = regExpr.GetOstIdx(); } - vstLiveStackVec.at(ostIdx).push(meExpr); + vstLiveStackVec[ostIdx]->push(&meExpr); } void Prop::PropUpdateChiListDef(const MapleMap &chiList) { @@ -244,6 +65,14 @@ void Prop::PropUpdateChiListDef(const MapleMap &chiList) { } } +void Prop::PropUpdateMustDefList(MeStmt *mestmt) { + MapleVector *mustdefList = mestmt->GetMustDefList(); + if (!mustdefList->empty()) { + MeExpr *melhs = mustdefList->front().GetLHS(); + PropUpdateDef(*static_cast(melhs)); + } +} + void Prop::CollectSubVarMeExpr(const MeExpr &meExpr, std::vector &varVec) const { switch (meExpr.GetMeOp()) { case kMeOpReg: @@ -270,7 +99,7 @@ void Prop::CollectSubVarMeExpr(const MeExpr &meExpr, std::vector // the version of progation of x1 is a1, but the top of the stack of symbol a is a2, so it's not consistent // warning: I suppose the vector vervec is on the stack, otherwise would cause memory leak bool Prop::IsVersionConsistent(const std::vector &vstVec, - const std::vector> &vstLiveStack) const { + const MapleVector *> &vstLiveStack) const { for (auto it = vstVec.begin(); it != vstVec.end(); ++it) { // iterate each cur defintion of related symbols of rhs, check the version const MeExpr *subExpr = *it; @@ -281,14 +110,14 @@ bool Prop::IsVersionConsistent(const std::vector &vstVec, } else { stackIdx = static_cast(subExpr)->GetOstIdx(); } - auto &pStack = vstLiveStack.at(stackIdx); - if (pStack.empty()) { + MapleStack *pStack = vstLiveStack.at(stackIdx); + if (pStack->empty()) { // no definition so far go ahead continue; } - SafeMeExprPtr curDef = pStack.top(); + MeExpr * curDef = pStack->top(); CHECK_FATAL(curDef->GetMeOp() == kMeOpVar || curDef->GetMeOp() == kMeOpReg, "error: cur def error"); - if (subExpr != curDef.get()) { + if (subExpr != curDef) { return false; } } @@ -514,15 +343,20 @@ MeExpr &Prop::PropMeExpr(MeExpr &meExpr, bool &isProped, bool atParm) { } case kMeOpOp: { auto &meOpExpr = static_cast(meExpr); - OpMeExpr newMeExpr(meOpExpr, -1); + OpMeExpr newMeExpr(-1, meOpExpr.GetOp(), meOpExpr.GetPrimType(), meOpExpr.GetNumOpnds()); for (size_t i = 0; i < newMeExpr.GetNumOpnds(); ++i) { - newMeExpr.SetOpnd(i, &PropMeExpr(utils::ToRef(newMeExpr.GetOpnd(i)), subProped, false)); + newMeExpr.SetOpnd(i, &PropMeExpr(utils::ToRef(meOpExpr.GetOpnd(i)), subProped, false)); } if (subProped) { isProped = true; - MeExpr *simplifyExpr = SimplifyMeExpr(newMeExpr); + newMeExpr.SetOpndType(meOpExpr.GetOpndType()); + newMeExpr.SetBitsOffSet(meOpExpr.GetBitsOffSet()); + newMeExpr.SetBitsSize(meOpExpr.GetBitsSize()); + newMeExpr.SetTyIdx(meOpExpr.GetTyIdx()); + newMeExpr.SetFieldID(meOpExpr.GetFieldID()); + MeExpr *simplifyExpr = irMap.SimplifyOpMeExpr(&newMeExpr); return simplifyExpr != nullptr ? *simplifyExpr : utils::ToRef(irMap.HashMeExpr(newMeExpr)); } else { return meOpExpr; @@ -642,9 +476,9 @@ void Prop::TraversalBB(BB &bb) { curBB = &bb; // record stack size for variable versions before processing rename. It is used for stack pop up. - std::vector curStackSizeVec(vstLiveStackVec.size()); + MapleVector curStackSizeVec(vstLiveStackVec.size(), propMapAlloc.Adapter()); for (size_t i = 1; i < vstLiveStackVec.size(); ++i) { - curStackSizeVec[i] = vstLiveStackVec[i].size(); + curStackSizeVec[i] = vstLiveStackVec[i]->size(); } // update var phi nodes @@ -657,21 +491,18 @@ void Prop::TraversalBB(BB &bb) { TraversalMeStmt(meStmt); } - auto &domChildren = dom.GetDomChildren(bb.GetBBId()); - for (auto it = domChildren.begin(); it != domChildren.end(); ++it) { - TraversalBB(utils::ToRef(bbVec[*it])); + MapleSet &domChildren = dom.GetDomChildren(bb.GetBBId()); + for (MapleSet::iterator it = domChildren.begin(); it != domChildren.end(); ++it) { + BBId childbbid = *it; + TraversalBB(*GetBB(childbbid)); } for (size_t i = 1; i < vstLiveStackVec.size(); ++i) { - auto &liveStack = vstLiveStackVec[i]; + MapleStack *liveStack = vstLiveStackVec[i]; size_t curSize = curStackSizeVec[i]; - while (liveStack.size() > curSize) { - liveStack.pop(); + while (liveStack->size() > curSize) { + liveStack->pop(); } } } - -void Prop::DoProp() { - TraversalBB(commonEntryBB); -} } // namespace maple diff --git a/src/mapleall/mpl2mpl/include/constantfold.h b/src/mapleall/mpl2mpl/include/constantfold.h index 45c172fb8f78d32222638e10ad9a99f889b8f166..b93288166294365f13a7e1091d90fc5401050cca 100644 --- a/src/mapleall/mpl2mpl/include/constantfold.h +++ b/src/mapleall/mpl2mpl/include/constantfold.h @@ -50,6 +50,7 @@ class ConstantFold : public FuncOptimizeImpl { MIRConst *FoldRoundMIRConst(const MIRConst&, PrimType, PrimType) const; MIRConst *FoldTypeCvtMIRConst(const MIRConst&, PrimType, PrimType) const; MIRConst *FoldSignExtendMIRConst(Opcode, PrimType, uint8, const MIRConst&) const; + MIRConst *FoldIntConstBinaryMIRConst(Opcode opcode, PrimType resultType, const MIRIntConst *intConst0, const MIRIntConst *intConst1) const; MIRConst *FoldConstComparisonMIRConst(Opcode, PrimType, PrimType, const MIRConst&, const MIRConst&); private: diff --git a/src/mapleall/mpl2mpl/src/constantfold.cpp b/src/mapleall/mpl2mpl/src/constantfold.cpp index a2c225740e7a92fbd22cc45b8f5f86cddd03395e..3264ee62e5084952d67b6939279814877db272f9 100644 --- a/src/mapleall/mpl2mpl/src/constantfold.cpp +++ b/src/mapleall/mpl2mpl/src/constantfold.cpp @@ -437,12 +437,7 @@ ConstvalNode *ConstantFold::FoldIntConstComparison(Opcode opcode, PrimType resul return resultConst; } -ConstvalNode *ConstantFold::FoldIntConstBinary(Opcode opcode, PrimType resultType, const ConstvalNode &const0, - const ConstvalNode &const1) const { - const MIRIntConst *intConst0 = safe_cast(const0.GetConstVal()); - const MIRIntConst *intConst1 = safe_cast(const1.GetConstVal()); - CHECK_NULL_FATAL(intConst0); - CHECK_NULL_FATAL(intConst1); +MIRConst *ConstantFold::FoldIntConstBinaryMIRConst(Opcode opcode, PrimType resultType, const MIRIntConst *intConst0, const MIRIntConst *intConst1) const { int64 intValueOfConst0 = intConst0->GetValue(); int64 intValueOfConst1 = intConst1->GetValue(); uint64 result64 = 0; @@ -474,7 +469,7 @@ ConstvalNode *ConstantFold::FoldIntConstBinary(Opcode opcode, PrimType resultTyp break; } case OP_div: { - if (IsUnsignedInteger(const0.GetPrimType())) { + if (IsUnsignedInteger(resultType)) { if (useResult64) { result64 = static_cast(intValueOfConst0) / static_cast(intValueOfConst1); } else { @@ -490,7 +485,7 @@ ConstvalNode *ConstantFold::FoldIntConstBinary(Opcode opcode, PrimType resultTyp break; } case OP_rem: { - if (IsUnsignedInteger(const0.GetPrimType())) { + if (IsUnsignedInteger(resultType)) { if (useResult64) { result64 = static_cast(intValueOfConst0) % static_cast(intValueOfConst1); } else { @@ -530,7 +525,7 @@ ConstvalNode *ConstantFold::FoldIntConstBinary(Opcode opcode, PrimType resultTyp break; } case OP_max: { - if (IsUnsignedInteger(const0.GetPrimType())) { + if (IsUnsignedInteger(resultType)) { if (useResult64) { result64 = (static_cast(intValueOfConst0) >= static_cast(intValueOfConst1)) ? static_cast(intValueOfConst0) : static_cast(intValueOfConst1); @@ -550,7 +545,7 @@ ConstvalNode *ConstantFold::FoldIntConstBinary(Opcode opcode, PrimType resultTyp break; } case OP_min: { - if (IsUnsignedInteger(const0.GetPrimType())) { + if (IsUnsignedInteger(resultType)) { if (useResult64) { result64 = (static_cast(intValueOfConst0) <= static_cast(intValueOfConst1)) ? static_cast(intValueOfConst0) : static_cast(intValueOfConst1); @@ -632,9 +627,19 @@ ConstvalNode *ConstantFold::FoldIntConstBinary(Opcode opcode, PrimType resultTyp } else { constValue = GlobalTables::GetIntConstTable().GetOrCreateIntConst(result32, type); } + return constValue; +} + +ConstvalNode *ConstantFold::FoldIntConstBinary(Opcode opcode, PrimType resultType, const ConstvalNode &const0, + const ConstvalNode &const1) const { + const MIRIntConst *intConst0 = safe_cast(const0.GetConstVal()); + const MIRIntConst *intConst1 = safe_cast(const1.GetConstVal()); + CHECK_NULL_FATAL(intConst0); + CHECK_NULL_FATAL(intConst1); + MIRConst *constValue = FoldIntConstBinaryMIRConst(opcode, resultType, intConst0, intConst1); // form the ConstvalNode ConstvalNode *resultConst = mirModule->CurFuncCodeMemPool()->New(); - resultConst->SetPrimType(type.GetPrimType()); + resultConst->SetPrimType(resultType); resultConst->SetConstVal(constValue); return resultConst; }