diff --git a/src/mapleall/bin/dex2mpl b/src/mapleall/bin/dex2mpl index b71a9cc794138738aa9876ba8a7cf46ff4d64c82..34208b5dcbd6623db9f523ce3577e114d07e85b5 100755 Binary files a/src/mapleall/bin/dex2mpl and b/src/mapleall/bin/dex2mpl differ diff --git a/src/mapleall/bin/jbc2mpl b/src/mapleall/bin/jbc2mpl index 7a6ea3ef59cc978a6ce8536241373cbce7d6e1e9..db463bb1a615bac43473c92a54eda3baecc8734c 100755 Binary files a/src/mapleall/bin/jbc2mpl and b/src/mapleall/bin/jbc2mpl differ diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_isa.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_isa.h index bd0e93da9c076fe2e3eedbb25962928f7cf02f13..590e264989f8fad039ad517e695afb9cf3846046 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_isa.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_isa.h @@ -116,7 +116,6 @@ enum AArch64reg : uint32 { #include "aarch64_fp_simd_regs.def" #undef FP_SIMD_REG #undef FP_SIMD_REG_ALIAS - kNArmRegisters }; namespace AArch64isa { diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_reg_alloc.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_reg_alloc.h index 18542b7a42d4ace1428a877409df836c37f2344a..481b0774a00ae2bd8ac4be63d9a066cafe98617b 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_reg_alloc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_reg_alloc.h @@ -24,6 +24,7 @@ class AArch64RegAllocator : public RegAllocator { public: AArch64RegAllocator(CGFunc &cgFunc, MemPool &memPool) : RegAllocator(cgFunc), + memPool(&memPool), alloc(&memPool), regMap(std::less(), alloc.Adapter()), liveReg(std::less(), alloc.Adapter()), @@ -70,6 +71,7 @@ class AArch64RegAllocator : public RegAllocator { uint32 GetRegLivenessId(Operand *opnd); void SetupRegLiveness(BB *bb); + MemPool *memPool; MapleAllocator alloc; bool availRegSet[kAllRegNum]; MapleMap regMap; /* virtual-register-to-physical-register map */ diff --git a/src/mapleall/maple_be/include/cg/cg.h b/src/mapleall/maple_be/include/cg/cg.h index efc709a66e82392da4a20588654089f85bf52c9d..93e951a61314bb77d487eeb1d1f5e29c4c0980be 100644 --- a/src/mapleall/maple_be/include/cg/cg.h +++ b/src/mapleall/maple_be/include/cg/cg.h @@ -97,7 +97,7 @@ class CG { public: CG(MIRModule &mod, const CGOptions &cgOptions) - : memPool(memPoolCtrler.NewMemPool("maplecg mempool")), + : memPool(memPoolCtrler.NewMemPool("maplecg mempool", false /* isLcalPool */)), allocator(memPool), mirModule(&mod), emitter(nullptr), diff --git a/src/mapleall/maple_be/mdgen/src/mdmain.cpp b/src/mapleall/maple_be/mdgen/src/mdmain.cpp index 4e26ad8e64174324d7f03d68ee74e16db8b5f2f5..54181f050499a614d3a7e01be8f62664652bdd7d 100644 --- a/src/mapleall/maple_be/mdgen/src/mdmain.cpp +++ b/src/mapleall/maple_be/mdgen/src/mdmain.cpp @@ -54,17 +54,17 @@ void ParseCommandLine(int argc, char **argv) { } } -bool GenSchedFiles(const std::string &fileName, const std::string &oFileDir, maple::MemPoolCtrler &mdMpCtrler) { - maple::MemPool *schedInfoMemPool = mdMpCtrler.NewMemPool("schedInfoMp"); +bool GenSchedFiles(const std::string &fileName, const std::string &oFileDir) { + maple::MemPool *schedInfoMemPool = memPoolCtrler.NewMemPool("schedInfoMp", false /* isLcalPool */); MDClassRange moduleData("Schedule"); MDParser parser(moduleData, schedInfoMemPool); if (!parser.ParseFile(fileName)) { - mdMpCtrler.DeleteMemPool(schedInfoMemPool); + memPoolCtrler.DeleteMemPool(schedInfoMemPool); return false; } SchedInfoGen schedEmiiter(moduleData, oFileDir); schedEmiiter.Run(); - mdMpCtrler.DeleteMemPool(schedInfoMemPool); + memPoolCtrler.DeleteMemPool(schedInfoMemPool); return true; } @@ -74,9 +74,8 @@ int main(int argc, char **argv) { return PrintHelpAndExit(); } ParseCommandLine(argc, argv); - maple::MemPoolCtrler mdMpCtrler; if (isGenSched) { - if (!GenSchedFiles(schedSrcPath, oFileDir, mdMpCtrler)) { + if (!GenSchedFiles(schedSrcPath, oFileDir)) { return 1; } } diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index 9e7c56f8d57c767f4e57756263bb483c32ef09fe..67d23541492e54b1f8fc26e708d6bba4e442737c 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -1268,14 +1268,13 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { switch (stmt->GetOpCode()) { case OP_switch: { LowerStmt(*stmt, *newBlk); - MemPool *switchMp = memPoolCtrler.NewMemPool("switchlowerer"); - MapleAllocator switchAllocator(switchMp); + auto switchMp = std::make_unique(memPoolCtrler, "switchlowere"); + MapleAllocator switchAllocator(switchMp.get()); SwitchLowerer switchLowerer(mirModule, static_cast(*stmt), switchAllocator); BlockNode *blk = switchLowerer.LowerSwitch(); if (blk->GetFirst() != nullptr) { newBlk->AppendStatementsFromBlock(*blk); } - memPoolCtrler.DeleteMemPool(switchMp); needBranchCleanup = true; break; } @@ -1728,7 +1727,7 @@ void CGLowerer::LowerTryCatchBlocks(BlockNode &body) { #if DEBUG BBT::ValidateStmtList(nullptr, nullptr); #endif - MemPool *memPool = memPoolCtrler.NewMemPool("CreateNewBB mempool"); + auto memPool = std::make_unique(memPoolCtrler, "CreateNewBB mempool"); TryCatchBlocksLower tryCatchLower(*memPool, body, mirModule); tryCatchLower.RecoverBasicBlock(); bool generateEHCode = GenerateExceptionHandlingCode(); @@ -1737,7 +1736,6 @@ void CGLowerer::LowerTryCatchBlocks(BlockNode &body) { #if DEBUG tryCatchLower.CheckTryCatchPattern(); #endif - memPoolCtrler.DeleteMemPool(memPool); } inline bool IsAccessingTheSameMemoryLocation(const DassignNode &dassign, diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp index b6c0321ed1efb1edb5401f25a796aa8a22e43564..30808356af8653e7d4478accedc29543c6e38710 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp @@ -421,18 +421,18 @@ bool GraphColorRegAllocator::IsUnconcernedReg(const RegOperand ®Opnd) const { * Add info for startingBB and endingBB */ LiveRange *GraphColorRegAllocator::NewLiveRange() { - LiveRange *lr = cgFunc->GetMemoryPool()->New(alloc); + LiveRange *lr = memPool->New(alloc); if (bbBuckets == 0) { bbBuckets = (cgFunc->NumBBs() / kU64) + 1; } lr->SetBBBuckets(bbBuckets); - lr->InitBBMember(*cgFunc->GetMemoryPool(), bbBuckets); + lr->InitBBMember(*memPool, bbBuckets); if (regBuckets == 0) { regBuckets = (cgFunc->GetMaxRegNum() / kU64) + 1; } lr->SetRegBuckets(regBuckets); - lr->InitBBConflict(*cgFunc->GetMemoryPool(), regBuckets); + lr->InitBBConflict(*memPool, regBuckets); lr->InitPregveto(); lr->InitForbidden(); return lr; @@ -449,7 +449,7 @@ bool GraphColorRegAllocator::CreateLiveRangeHandleLocal(regno_t regNO, const BB */ LocalRaInfo *lraInfo = localRegVec[bb.GetId()]; if (lraInfo == nullptr) { - lraInfo = cgFunc->GetMemoryPool()->New(alloc); + lraInfo = memPool->New(alloc); localRegVec[bb.GetId()] = lraInfo; } if (isDef) { @@ -469,7 +469,7 @@ LiveRange *GraphColorRegAllocator::CreateLiveRangeAllocateAndUpdate(regno_t regN lr = NewLiveRange(); lr->SetID(currId); - LiveUnit *lu = cgFunc->GetMemoryPool()->New(); + LiveUnit *lu = memPool->New(); lr->SetElemToLuMap(bb.GetId(), *lu); lu->SetBegin(currId); lu->SetEnd(currId); @@ -484,7 +484,7 @@ LiveRange *GraphColorRegAllocator::CreateLiveRangeAllocateAndUpdate(regno_t regN LiveUnit *lu = lr->GetLiveUnitFromLuMap(bb.GetId()); if (lu == nullptr) { - lu = cgFunc->GetMemoryPool()->New(); + lu = memPool->New(); lr->SetElemToLuMap(bb.GetId(), *lu); lu->SetBegin(currId); lu->SetEnd(currId); @@ -548,7 +548,7 @@ bool GraphColorRegAllocator::SetupLiveRangeByOpHandlePhysicalReg(RegOperand ® } LocalRaInfo *lraInfo = localRegVec[insn.GetBB()->GetId()]; if (lraInfo == nullptr) { - lraInfo = cgFunc->GetMemoryPool()->New(alloc); + lraInfo = memPool->New(alloc); localRegVec[insn.GetBB()->GetId()] = lraInfo; } @@ -618,7 +618,7 @@ void GraphColorRegAllocator::SetupLiveRangeByOp(Operand &op, Insn &insn, bool is #ifdef MOVE_COALESCE if (insn.GetMachineOpcode() == MOP_xmovrr || insn.GetMachineOpcode() == MOP_wmovrr) { RegOperand &opnd = static_cast(insn.GetOperand(1)); - if (opnd.GetRegisterNumber() < kNArmRegisters) { + if (opnd.GetRegisterNumber() < kAllRegNum) { lr->InsertElemToPrefs(opnd->GetRegisterNumber() - R0); } } @@ -630,7 +630,7 @@ void GraphColorRegAllocator::SetupLiveRangeByRegNO(regno_t liveOut, BB &bb, uint if (IsUnconcernedReg(liveOut)) { return; } - if (liveOut >= kNArmRegisters) { + if (liveOut >= kAllRegNum) { (void)vregLive.insert(liveOut); CreateLiveRange(liveOut, bb, false, currPoint, false); return; @@ -648,7 +648,7 @@ void GraphColorRegAllocator::SetupLiveRangeByRegNO(regno_t liveOut, BB &bb, uint } LocalRaInfo *lraInfo = localRegVec[bb.GetId()]; if (lraInfo == nullptr) { - lraInfo = cgFunc->GetMemoryPool()->New(alloc); + lraInfo = memPool->New(alloc); localRegVec[bb.GetId()] = lraInfo; } /* Make it a large enough so no locals can be allocated. */ @@ -809,7 +809,7 @@ void GraphColorRegAllocator::ComputeLiveRangesUpdateIfInsnIsCall(const Insn &ins void GraphColorRegAllocator::ComputeLiveRangesUpdateLiveUnitInsnRange(BB &bb, uint32 currPoint) { for (auto lin : bb.GetLiveInRegNO()) { - if (lin < kNArmRegisters) { + if (lin < kAllRegNum) { continue; } LiveRange *lr = lrVec[lin]; @@ -1080,7 +1080,7 @@ void GraphColorRegAllocator::SetBBInfoGlobalAssigned(uint32 bbID, regno_t regNO) ASSERT(bbID < bbRegInfo.size(), "index out of range in GraphColorRegAllocator::SetBBInfoGlobalAssigned"); BBAssignInfo *bbInfo = bbRegInfo[bbID]; if (bbInfo == nullptr) { - bbInfo = cgFunc->GetMemoryPool()->New(alloc); + bbInfo = memPool->New(alloc); bbRegInfo[bbID] = bbInfo; bbInfo->InitGlobalAssigned(); } @@ -1875,7 +1875,7 @@ void GraphColorRegAllocator::SplitLr(LiveRange &lr) { } #ifdef REUSE_SPILLMEM /* Copy the original conflict vector for spill reuse optimization */ - lr.SetOldConflict(cgFunc->GetMemoryPool()->NewArray(regBuckets)); + lr.SetOldConflict(memPool->NewArray(regBuckets)); for (uint32 i = 0; i < regBuckets; ++i) { lr.SetBBConflictElem(i, lr.GetBBConflictElem(i)); } @@ -2104,7 +2104,7 @@ void GraphColorRegAllocator::HandleLocalReg(Operand &op, LocalRegAllocator &loca } /* is this a local register ? */ - if (regNO >= kNArmRegisters && !IsLocalReg(regNO)) { + if (regNO >= kAllRegNum && !IsLocalReg(regNO)) { return; } @@ -2160,14 +2160,14 @@ bool GraphColorRegAllocator::LocalRaInitRegSet(LocalRegAllocator &localRa, uint3 ASSERT(lraInfo != nullptr, "lraInfo not be nullptr"); for (const auto &useCntPair : lraInfo->GetUseCnt()) { regno_t regNO = useCntPair.first; - if (regNO >= kNArmRegisters) { + if (regNO >= kAllRegNum) { needLocalRa = true; } localRa.SetUseInfoElem(useCntPair.first, useCntPair.second); } for (const auto &defCntPair : lraInfo->GetDefCnt()) { regno_t regNO = defCntPair.first; - if (regNO >= kNArmRegisters) { + if (regNO >= kAllRegNum) { needLocalRa = true; } localRa.SetDefInfoElem(defCntPair.first, defCntPair.second); @@ -2296,7 +2296,7 @@ void GraphColorRegAllocator::LocalRegisterAllocator(bool doAllocate) { LogInfo::MapleLogger() << "LRA preprocessing start\n"; } } - LocalRegAllocator *localRa = cgFunc->GetMemoryPool()->New(*cgFunc, alloc); + LocalRegAllocator *localRa = memPool->New(*cgFunc, alloc); for (auto *bb : sortedBBs) { uint32 bbID = bb->GetId(); @@ -2321,7 +2321,7 @@ void GraphColorRegAllocator::LocalRegisterAllocator(bool doAllocate) { BBAssignInfo *bbInfo = bbRegInfo[bb->GetId()]; if (bbInfo == nullptr) { - bbInfo = cgFunc->GetMemoryPool()->New(alloc); + bbInfo = memPool->New(alloc); bbRegInfo[bbID] = bbInfo; bbInfo->InitGlobalAssigned(); } @@ -2866,7 +2866,7 @@ RegOperand *GraphColorRegAllocator::GetReplaceOpnd(Insn &insn, const Operand &op uint32 vregNO = regOpnd.GetRegisterNumber(); RegType regType = regOpnd.GetRegisterType(); - if (vregNO < kNArmRegisters) { + if (vregNO < kAllRegNum) { return nullptr; } if (IsUnconcernedReg(regOpnd)) { @@ -3009,7 +3009,7 @@ void GraphColorRegAllocator::FinalizeRegisters() { continue; } - FinalizeRegisterInfo *fInfo = cgFunc->GetMemoryPool()->New(alloc); + FinalizeRegisterInfo *fInfo = memPool->New(alloc); uint64 usedRegMask = FinalizeRegisterPreprocess(bbInfo, *fInfo, *insn); uint32 defSpillIdx = 0; uint32 useSpillIdx = 0; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_fixshortbranch.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_fixshortbranch.cpp index 4affa287cf99c31913f35ec0bcd82fa52a7bb00b..f1be9e1a678112329de4bb91374fc9ba615eb708 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_fixshortbranch.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_fixshortbranch.cpp @@ -127,11 +127,10 @@ void AArch64FixShortBranch::FixShortBranches() { AnalysisResult *CgFixShortBranch::Run(CGFunc *cgFunc, CgFuncResultMgr *cgFuncResultMgr) { (void)cgFuncResultMgr; ASSERT(cgFunc != nullptr, "nullptr check"); - MemPool *memPool = memPoolCtrler.NewMemPool("fixShortBranches"); + auto memPool = std::make_unique(memPoolCtrler, "FixShortBranches"); auto *fixShortBranch = memPool->New(cgFunc); CHECK_FATAL(fixShortBranch != nullptr, "AArch64FixShortBranch instance create failure"); fixShortBranch->FixShortBranches(); - memPoolCtrler.DeleteMemPool(memPool); return nullptr; } } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_lsra.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_lsra.cpp index a9adcfe540bd84f4499ddd9e7133bdb1cfeec91e..f0b5071bd66ff516860bb4af7d6679c4e728e5ed 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_lsra.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_lsra.cpp @@ -387,7 +387,7 @@ void LSRALinearScanRegAllocator::InitFreeRegPool() { /* Remember calls for caller/callee allocation. */ void LSRALinearScanRegAllocator::RecordCall(Insn &insn) { /* Maintain call at the beginning of active list */ - auto *li = cgFunc->GetMemoryPool()->New(alloc); + auto *li = memPool->New(alloc); li->SetFirstDef(insn.GetId()); li->SetIsCall(insn); callList.push_back(li); @@ -414,7 +414,7 @@ void LSRALinearScanRegAllocator::RecordPhysRegs(const RegOperand ®Opnd, uint3 if (isDef) { /* parameter register def is assumed to be live until a call. */ - auto *li = cgFunc->GetMemoryPool()->New(alloc); + auto *li = memPool->New(alloc); li->SetRegNO(regNO); li->SetRegType(regType); li->SetStackSlot(0xFFFFFFFF); @@ -475,7 +475,7 @@ void LSRALinearScanRegAllocator::SetupLiveInterval(Operand &opnd, Insn &insn, bo LiveInterval *li = nullptr; uint32 regNO = regOpnd.GetRegisterNumber(); if (liveIntervalsArray[regNO] == nullptr) { - li = cgFunc->GetMemoryPool()->New(alloc); + li = memPool->New(alloc); li->SetRegNO(regNO); li->SetStackSlot(0xFFFFFFFF); liveIntervalsArray[regNO] = li; @@ -615,7 +615,7 @@ void LSRALinearScanRegAllocator::SetupIntervalRangesByOperand(Operand &opnd, con RegType regType = regOpnd.GetRegisterType(); if (regType != kRegTyCc && regType != kRegTyVary) { regno_t regNO = regOpnd.GetRegisterNumber(); - if (regNO > kNArmRegisters) { + if (regNO > kAllRegNum) { if (isDef) { if (!liveIntervalsArray[regNO]->GetRanges().empty()) { liveIntervalsArray[regNO]->GetRanges().front().first = insn.GetId(); @@ -671,7 +671,7 @@ void LSRALinearScanRegAllocator::BuildIntervalRanges() { uint32 blockTo = bb->GetLastInsn()->GetId() + 1; for (auto regNO : bb->GetLiveOutRegNO()) { - if (regNO < kNArmRegisters) { + if (regNO < kAllRegNum) { /* Do not consider physical regs. */ continue; } @@ -707,7 +707,7 @@ void LSRALinearScanRegAllocator::BuildIntervalRanges() { /* Extend live interval with live-in info */ void LSRALinearScanRegAllocator::UpdateLiveIntervalByLiveIn(const BB &bb, uint32 insnNum) { for (const auto ®NO : bb.GetLiveInRegNO()) { - if (regNO < kNArmRegisters) { + if (regNO < kAllRegNum) { /* Do not consider physical regs. */ continue; } @@ -719,7 +719,7 @@ void LSRALinearScanRegAllocator::UpdateLiveIntervalByLiveIn(const BB &bb, uint32 * try-catch related * Since it is livein but not seen before, its a use before def */ - auto *li = cgFunc->GetMemoryPool()->New(alloc); + auto *li = memPool->New(alloc); li->SetRegNO(regNO); li->SetStackSlot(0xFFFFFFFF); liveIntervalsArray[regNO] = li; @@ -749,7 +749,7 @@ void LSRALinearScanRegAllocator::UpdateParamLiveIntervalByLiveIn(const BB &bb, u if (!AArch64Abi::IsParamReg(static_cast(regNO))) { continue; } - auto *li = cgFunc->GetMemoryPool()->New(alloc); + auto *li = memPool->New(alloc); li->SetRegNO(regNO); li->SetStackSlot(0xFFFFFFFF); li->SetFirstDef(insnNum); diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp index 2681590c7f223f3bf3c36de74f7188edceb9f3a2..ed22795ad93ec655c8dd085b806cdf27fd0849f5 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp @@ -220,10 +220,12 @@ void AArch64MemOperand::Emit(Emitter &emitter, const OpndProp *opndProp) const { emitter.Emit("["); auto *baseReg = static_cast(GetBaseRegister()); ASSERT(baseReg != nullptr, "expect an AArch64RegOperand here"); - if (CGOptions::IsPIC() && (baseReg->GetSize() != k64BitSize)) { + uint32 baseSize = baseReg->GetSize(); + if (CGOptions::IsPIC() && (baseSize != k64BitSize)) { baseReg->SetSize(k64BitSize); } baseReg->Emit(emitter, nullptr); + baseReg->SetSize(baseSize); AArch64OfstOperand *offset = GetOffsetImmediate(); if (offset != nullptr) { #ifndef USE_32BIT_REF /* can be load a ref here */ diff --git a/src/mapleall/maple_be/src/cg/cfgo.cpp b/src/mapleall/maple_be/src/cg/cfgo.cpp index 184e8aa6ee5288616d5ad7c4de5ed45c2c3f3983..1ba6f330fd5795cafedf7404bc16f64f659c3d39 100644 --- a/src/mapleall/maple_be/src/cg/cfgo.cpp +++ b/src/mapleall/maple_be/src/cg/cfgo.cpp @@ -241,7 +241,10 @@ bool ChainingPattern::Optimize(BB &curBB) { * 3. BB2 is of goto kind. Otherwise, the original fall through will be broken * 4. BB2 is neither catch BB nor switch case BB */ - if (sucBB == nullptr) { + if (sucBB == nullptr || curBB.GetEhSuccs().size() != sucBB->GetEhSuccs().size()) { + return false; + } + if (!curBB.GetEhSuccs().empty() && (curBB.GetEhSuccs().front() != sucBB->GetEhSuccs().front())) { return false; } if (sucBB->GetKind() == BB::kBBGoto && @@ -708,6 +711,12 @@ bool DuplicateBBPattern::Optimize(BB &curBB) { return false; } for (BB *bb : candidates) { + if (curBB.GetEhSuccs().size() != bb->GetEhSuccs().size()) { + continue; + } + if (!curBB.GetEhSuccs().empty() && (curBB.GetEhSuccs().front() != bb->GetEhSuccs().front())) { + continue; + } bb->RemoveInsn(*bb->GetLastInsn()); FOR_BB_INSNS(insn, (&curBB)) { Insn *clonedInsn = cgFunc->GetTheCFG()->CloneInsn(*insn); diff --git a/src/mapleall/maple_be/src/cg/peep.cpp b/src/mapleall/maple_be/src/cg/peep.cpp index 58435d7aa67ccdfa4598cd27a56b249f01f15ae4..58f906d0616bb04c4282e6b7bb656619d2e86ed2 100644 --- a/src/mapleall/maple_be/src/cg/peep.cpp +++ b/src/mapleall/maple_be/src/cg/peep.cpp @@ -279,94 +279,86 @@ void PeepOptimizer::Run() { int32 PeepOptimizer::index = 0; void PeepHoleOptimizer::Peephole0() { - MemPool *memPool = memPoolCtrler.NewMemPool("peepholeOptObj"); - PeepOptimizer peepOptimizer(*cgFunc, memPool); + auto memPool = std::make_unique(memPoolCtrler, "peepholeOptObj"); + PeepOptimizer peepOptimizer(*cgFunc, memPool.get()); #if TARGAARCH64 || TARGRISCV64 peepOptimizer.Run(); #endif #if TARGARM32 peepOptimizer.Run(); #endif - memPoolCtrler.DeleteMemPool(memPool); } void PeepHoleOptimizer::PeepholeOpt() { - MemPool *memPool = memPoolCtrler.NewMemPool("peepholeOptObj"); - PeepOptimizer peepOptimizer(*cgFunc, memPool); + auto memPool = std::make_unique(memPoolCtrler, "peepholeOptObj"); + PeepOptimizer peepOptimizer(*cgFunc, memPool.get()); #if TARGAARCH64 || TARGRISCV64 peepOptimizer.Run(); #endif #if TARGARM32 peepOptimizer.Run(); #endif - memPoolCtrler.DeleteMemPool(memPool); } void PeepHoleOptimizer::PrePeepholeOpt() { - MemPool *memPool = memPoolCtrler.NewMemPool("peepholeOptObj"); - PeepOptimizer peepOptimizer(*cgFunc, memPool); + auto memPool = std::make_unique(memPoolCtrler, "peepholeOptObj"); + PeepOptimizer peepOptimizer(*cgFunc, memPool.get()); #if TARGAARCH64 || TARGRISCV64 peepOptimizer.Run(); #endif #if TARGARM32 peepOptimizer.Run(); #endif - memPoolCtrler.DeleteMemPool(memPool); } void PeepHoleOptimizer::PrePeepholeOpt1() { - MemPool *memPool = memPoolCtrler.NewMemPool("peepholeOptObj"); - PeepOptimizer peepOptimizer(*cgFunc, memPool); + auto memPool = std::make_unique(memPoolCtrler, "peepholeOptObj"); + PeepOptimizer peepOptimizer(*cgFunc, memPool.get()); #if TARGAARCH64 || TARGRISCV64 peepOptimizer.Run(); #endif #if TARGARM32 peepOptimizer.Run(); #endif - memPoolCtrler.DeleteMemPool(memPool); } AnalysisResult *CgDoPrePeepHole::Run(CGFunc *cgFunc, CgFuncResultMgr *cgFuncResultMgr) { (void)cgFuncResultMgr; ASSERT(cgFunc != nullptr, "nullptr check"); - MemPool *memPool = memPoolCtrler.NewMemPool("prePeepholeOpt"); + auto memPool = std::make_unique(memPoolCtrler, "prePeepholeOpt"); auto *peep = memPool->New(cgFunc); CHECK_FATAL(peep != nullptr, "PeepHoleOptimizer instance create failure"); peep->PrePeepholeOpt(); - memPoolCtrler.DeleteMemPool(memPool); return nullptr; } AnalysisResult *CgDoPrePeepHole1::Run(CGFunc *cgFunc, CgFuncResultMgr *cgFuncResultMgr) { (void)cgFuncResultMgr; ASSERT(cgFunc != nullptr, "nullptr check"); - MemPool *memPool = memPoolCtrler.NewMemPool("prePeepholeOpt1"); + auto memPool = std::make_unique(memPoolCtrler, "prePeepholeOpt1"); auto *peep = memPool->New(cgFunc); CHECK_FATAL(peep != nullptr, "PeepHoleOptimizer instance create failure"); peep->PrePeepholeOpt1(); - memPoolCtrler.DeleteMemPool(memPool); return nullptr; } AnalysisResult *CgDoPeepHole0::Run(CGFunc *cgFunc, CgFuncResultMgr *cgFuncResultMgr) { (void)cgFuncResultMgr; ASSERT(cgFunc != nullptr, "nullptr check"); - MemPool *memPool = memPoolCtrler.NewMemPool("peephole0"); + auto memPool = std::make_unique(memPoolCtrler, "peephole0"); auto *peep = memPool->New(cgFunc); CHECK_FATAL(peep != nullptr, "PeepHoleOptimizer instance create failure"); peep->Peephole0(); - memPoolCtrler.DeleteMemPool(memPool); return nullptr; } AnalysisResult *CgDoPeepHole::Run(CGFunc *cgFunc, CgFuncResultMgr *cgFuncResultMgr) { (void)cgFuncResultMgr; ASSERT(cgFunc != nullptr, "nullptr check"); - MemPool *memPool = memPoolCtrler.NewMemPool("PeepHoleOptimizer"); + auto memPool = std::make_unique(memPoolCtrler, "PeepHoleOptimizer"); auto *peep = memPool->New(cgFunc); CHECK_FATAL(peep != nullptr, "PeepHoleOptimizer instance create failure"); peep->PeepholeOpt(); - memPoolCtrler.DeleteMemPool(memPool); return nullptr; } } /* namespace maplebe */ diff --git a/src/mapleall/maple_driver/src/driver_runner.cpp b/src/mapleall/maple_driver/src/driver_runner.cpp index acb68eb3a27ed3b96fe2adc9ad8b98d86ef8d23e..e37bebdea3415040ffd1f660bf0399d9edeb008c 100644 --- a/src/mapleall/maple_driver/src/driver_runner.cpp +++ b/src/mapleall/maple_driver/src/driver_runner.cpp @@ -444,8 +444,8 @@ void DriverRunner::RunCGFunctions(CG &cg, CgFuncPhaseManager &cgfpm, std::vector lowerTime += timer.ElapsedMicroseconds(); MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(mirFunc->GetStIdx().Idx()); - MemPool *funcMp = memPoolCtrler.NewMemPool(funcSt->GetName()); - MapleAllocator funcScopeAllocator(funcMp); + auto funcMp = std::make_unique(memPoolCtrler, funcSt->GetName()); + MapleAllocator funcScopeAllocator(funcMp.get()); // Create CGFunc mirFunc->SetPuidxOrigin(++countFuncId); @@ -464,8 +464,7 @@ void DriverRunner::RunCGFunctions(CG &cg, CgFuncPhaseManager &cgfpm, std::vector cgfpm.ClearPhaseNameInfo(); // Delete mempool. - memPoolCtrler.DeleteMemPool(funcMp); - memPoolCtrler.DeleteMemPool(mirFunc->GetCodeMempool()); + mirFunc->ReleaseCodeMemory(); ++rangeNum; } diff --git a/src/mapleall/maple_driver/src/maple_comb_compiler.cpp b/src/mapleall/maple_driver/src/maple_comb_compiler.cpp index 57afe6c16b6d9d3c446be5c6cc5bf50bcbad9a82..322cfbbb69d1afa2f2d0227a169d81f88da6672a 100644 --- a/src/mapleall/maple_driver/src/maple_comb_compiler.cpp +++ b/src/mapleall/maple_driver/src/maple_comb_compiler.cpp @@ -164,7 +164,7 @@ std::string MapleCombCompiler::DecideOutExe(const MplOptions &options) { } ErrorCode MapleCombCompiler::Compile(MplOptions &options, std::unique_ptr &theModule) { - MemPool *optMp = memPoolCtrler.NewMemPool("maplecomb mempool"); + MemPool *optMp = memPoolCtrler.NewMemPool("maplecomb mempool", false /* isLocalPool */); std::string fileName = GetInputFileName(options); bool fileParsed = true; if (theModule == nullptr) { diff --git a/src/mapleall/maple_driver/src/mplcg_compiler.cpp b/src/mapleall/maple_driver/src/mplcg_compiler.cpp index f3590fb34f3ecc5a3673a0cfb2b7570dc475ed45..c95c11eb28fd9d05f86ed08410447c7459a4e742 100644 --- a/src/mapleall/maple_driver/src/mplcg_compiler.cpp +++ b/src/mapleall/maple_driver/src/mplcg_compiler.cpp @@ -126,7 +126,7 @@ ErrorCode MplcgCompiler::Compile(MplOptions &options, std::unique_ptr return kErrorCompileFail; } std::string fileName = GetInputFile(options, *theModule); - MemPool *optMp = memPoolCtrler.NewMemPool("maplecg mempool"); + MemPool *optMp = memPoolCtrler.NewMemPool("maplecg mempool", false /* isLcalPool */); bool fileRead = true; if (theModule == nullptr) { MPLTimer timer; diff --git a/src/mapleall/maple_ipa/src/call_graph.cpp b/src/mapleall/maple_ipa/src/call_graph.cpp index 4aafd4789356a22e0707c32a50d252d9f1fcb7b8..1bebc6e4d6d548c785bb04b8777caf4ac064b88c 100644 --- a/src/mapleall/maple_ipa/src/call_graph.cpp +++ b/src/mapleall/maple_ipa/src/call_graph.cpp @@ -1694,7 +1694,7 @@ MIRFunction *CGNode::HasOneCandidate() const { } AnalysisResult *DoCallGraph::Run(MIRModule *module, ModuleResultMgr *mgr) { - MemPool *memPool = memPoolCtrler.NewMemPool("callgraph mempool"); + MemPool *memPool = NewMemPool(); KlassHierarchy *klassh = static_cast(mgr->GetAnalysisResult(MoPhase_CHA, module)); CHECK_FATAL(klassh != nullptr, "CHA can't be null"); CallGraph *cg = memPool->New(*module, *memPool, *klassh, module->GetFileName()); @@ -1704,23 +1704,21 @@ AnalysisResult *DoCallGraph::Run(MIRModule *module, ModuleResultMgr *mgr) { mgr->AddResult(GetPhaseID(), *module, *cg); if (!module->IsInIPA() && module->firstInline) { // do retype - MemPool *localMp = memPoolCtrler.NewMemPool(PhaseName()); + MemPool *localMp = NewMemPool(); maple::MIRBuilder dexMirbuilder(module); Retype retype(module, localMp); retype.DoRetype(); - memPoolCtrler.DeleteMemPool(localMp); } return cg; } AnalysisResult *DoIPODevirtulize::Run(MIRModule *module, ModuleResultMgr *mgr) { - MemPool *memPool = memPoolCtrler.NewMemPool("ipodevirulize mempool"); + MemPool *memPool = NewMemPool(); KlassHierarchy *klassh = static_cast(mgr->GetAnalysisResult(MoPhase_CHA, module)); CHECK_NULL_FATAL(klassh); IPODevirtulize *dev = memPool->New(module, memPool, klassh); // Devirtualize vcall of final variable dev->DevirtualFinal(); - memPoolCtrler.DeleteMemPool(memPool); return nullptr; } } // namespace maple diff --git a/src/mapleall/maple_ipa/src/clone.cpp b/src/mapleall/maple_ipa/src/clone.cpp index f694e60b156daf948f21ee24374d556e158c6ae1..cedb01b731c0189e62b5f0061ba0f0b328f27e7f 100644 --- a/src/mapleall/maple_ipa/src/clone.cpp +++ b/src/mapleall/maple_ipa/src/clone.cpp @@ -240,7 +240,7 @@ void Clone::DoClone() { } AnalysisResult *DoClone::Run(MIRModule *module, ModuleResultMgr *mgr) { - MemPool *memPool = memPoolCtrler.NewMemPool(PhaseName()); + MemPool *memPool = memPoolCtrler.NewMemPool(PhaseName(), false /* isLcalPool */); maple::MIRBuilder dexMirBuilder(module); KlassHierarchy *kh = static_cast(mgr->GetAnalysisResult(MoPhase_CHA, module)); Clone *clone = memPool->New(module, memPool, dexMirBuilder, kh); diff --git a/src/mapleall/maple_ipa/src/do_ipa_escape_analysis.cpp b/src/mapleall/maple_ipa/src/do_ipa_escape_analysis.cpp index bfa60378d8a59ba470cae963f9983bedf8590e4e..4672d4288afcac09bc6d24a74794c9b15c3d5a29 100644 --- a/src/mapleall/maple_ipa/src/do_ipa_escape_analysis.cpp +++ b/src/mapleall/maple_ipa/src/do_ipa_escape_analysis.cpp @@ -35,7 +35,7 @@ AnalysisResult *DoIpaEA::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultM if (mirFunc->GetModule()->IsInIPA()) { pcg = static_cast(mrm->GetAnalysisResult(MoPhase_CALLGRAPH_ANALYSIS, &func->GetMIRModule())); } - MemPool *eaMemPool = memPoolCtrler.NewMemPool(PhaseName()); + MemPool *eaMemPool = memPoolCtrler.NewMemPool(PhaseName(), false /* isLcalPool */); mirFunc->GetModule()->SetCurFunction(mirFunc); if (IPAEscapeAnalysis::kDebug) { @@ -86,7 +86,7 @@ AnalysisResult *DoIpaEAOpt::Run(MeFunction *func, MeFuncResultMgr *mgr, ModuleRe if (mirFunc->GetModule()->IsInIPA()) { pcg = static_cast(mrm->GetAnalysisResult(MoPhase_CALLGRAPH_ANALYSIS, &func->GetMIRModule())); } - MemPool *eaMemPool = memPoolCtrler.NewMemPool(PhaseName()); + MemPool *eaMemPool = memPoolCtrler.NewMemPool(PhaseName(), false /* isLcalPool */); mirFunc->GetModule()->SetCurFunction(mirFunc); if (IPAEscapeAnalysis::kDebug) { diff --git a/src/mapleall/maple_ipa/src/ea_connection_graph.cpp b/src/mapleall/maple_ipa/src/ea_connection_graph.cpp index 2dabed6f32c048df37849570116905b85aa15e39..b2e40e853bfd9a0cad6f69c867aa04bbd10843be 100644 --- a/src/mapleall/maple_ipa/src/ea_connection_graph.cpp +++ b/src/mapleall/maple_ipa/src/ea_connection_graph.cpp @@ -17,7 +17,7 @@ namespace maple { constexpr maple::uint32 kInvalid = 0xffffffff; void EACGBaseNode::CheckAllConnectionInNodes() { -#if DEBUG +#ifdef DEBUG for (EACGBaseNode *inNode : in) { ASSERT_NOT_NULL(eaCG->nodes[inNode->id - 1]); ASSERT(eaCG->nodes[inNode->id - 1] == inNode, "must be inNode"); @@ -142,7 +142,7 @@ bool EACGBaseNode::CanIgnoreRC() const { } void EACGObjectNode::CheckAllConnectionInNodes() { -#if DEBUG +#ifdef DEBUG for (EACGBaseNode *inNode : in) { ASSERT_NOT_NULL(eaCG->nodes[inNode->id - 1]); ASSERT(eaCG->nodes[inNode->id - 1] == inNode, "must be inNode"); diff --git a/src/mapleall/maple_ipa/src/inline.cpp b/src/mapleall/maple_ipa/src/inline.cpp index f0501865979f7f51fff0c5b86359939fe3370a28..730fc8d31c6bc874a897b576b47e644ded7a1ee2 100644 --- a/src/mapleall/maple_ipa/src/inline.cpp +++ b/src/mapleall/maple_ipa/src/inline.cpp @@ -1391,7 +1391,7 @@ void MInline::MarkUsedSymbols(const BaseNode *baseNode) const { // Unified interface to run inline module phase. AnalysisResult *DoInline::Run(MIRModule *module, ModuleResultMgr *mgr) { - MemPool *memPool = memPoolCtrler.NewMemPool("inline mempool"); + MemPool *memPool = memPoolCtrler.NewMemPool("inline mempool", false /* isLocalPool */); KlassHierarchy *klassHierarchy = static_cast(mgr->GetAnalysisResult(MoPhase_CHA, module)); CHECK_FATAL(klassHierarchy != nullptr, "Expecting a valid KlassHierarchy, found nullptr"); CallGraph *cg = static_cast(mgr->GetAnalysisResult(MoPhase_CALLGRAPH_ANALYSIS, module)); diff --git a/src/mapleall/maple_ipa/src/interleaved_manager.cpp b/src/mapleall/maple_ipa/src/interleaved_manager.cpp index 56b8bbcd8e7301d51ef523e235938c54bcc6dd1a..33cdaa0d3aa16c8a2b20a7f812c0e05539e72260 100644 --- a/src/mapleall/maple_ipa/src/interleaved_manager.cpp +++ b/src/mapleall/maple_ipa/src/interleaved_manager.cpp @@ -202,7 +202,7 @@ void InterleavedManager::OptimizeFuncs(MeFuncPhaseManager &fpm, MapleVector &compList, uint32 nThreads) { auto mainMpCtrler = std::make_unique(); - MemPool *mainMp = mainMpCtrler->NewMemPool("main thread mempool"); + MemPool *mainMp = mainMpCtrler->NewMemPool("main thread mempool", false /* isLocalPool */); MeFuncPhaseManager &fpmCopy = fpm.Clone(*mainMp, *mainMpCtrler); auto funcOpt = std::make_unique(std::move(mainMpCtrler), fpmCopy); MeFuncOptScheduler funcOptScheduler("me func opt", std::move(funcOpt)); diff --git a/src/mapleall/maple_ipa/src/method_replace.cpp b/src/mapleall/maple_ipa/src/method_replace.cpp index 836dd2f9e8317aef9f20ffcb8d233c325edced17..13b378643263b98921c2ef7eaf2f75bc9ff9a78b 100644 --- a/src/mapleall/maple_ipa/src/method_replace.cpp +++ b/src/mapleall/maple_ipa/src/method_replace.cpp @@ -80,7 +80,7 @@ void MethodReplace::DoMethodReplace() { } AnalysisResult *DoMethodReplace::Run(MIRModule *module, ModuleResultMgr*) { - MemPool *mp = memPoolCtrler.NewMemPool(PhaseName()); + MemPool *mp = memPoolCtrler.NewMemPool(PhaseName(), false /* isLocalPool */); maple::MIRBuilder builder(module); MethodReplace methodReplace(module, mp, builder); methodReplace.Init(); diff --git a/src/mapleall/maple_ir/include/lexer.h b/src/mapleall/maple_ir/include/lexer.h index f028d151240535d19a489c97413752fd106430bf..26812634a563ff82c0c70e654d2b98f0e92f9886 100644 --- a/src/mapleall/maple_ir/include/lexer.h +++ b/src/mapleall/maple_ir/include/lexer.h @@ -164,7 +164,8 @@ inline bool IsConstValue(TokenKind tk) { } inline bool IsConstAddrExpr(TokenKind tk) { - return (tk == TK_addrof) || (tk == TK_addroffunc) || (tk == TK_addroflabel) || (tk == TK_conststr) || (tk == TK_conststr16); + return (tk == TK_addrof) || (tk == TK_addroffunc) || (tk == TK_addroflabel) || + (tk == TK_conststr) || (tk == TK_conststr16); } } // namespace maple #endif // MAPLE_IR_INCLUDE_LEXER_H diff --git a/src/mapleall/maple_ir/include/mir_function.h b/src/mapleall/maple_ir/include/mir_function.h index e9f54871eb004b6fd8e6973f1124ffc9f2ba2a28..c95a705fb7e642e8b64c8de9d777c4455251e9c6 100644 --- a/src/mapleall/maple_ir/include/mir_function.h +++ b/src/mapleall/maple_ir/include/mir_function.h @@ -444,20 +444,29 @@ class MIRFunction { void ResetGDBEnv(); #endif void ReleaseMemory() { - memPoolCtrler.DeleteMemPool(codeMemPoolTmp); - codeMemPoolTmp = nullptr; + if (codeMemPoolTmp != nullptr) { + delete codeMemPoolTmp; + codeMemPoolTmp = nullptr; + } + } + + void ReleaseCodeMemory() { + if (codeMemPool != nullptr) { + delete codeMemPool; + SetMemPool(nullptr); + } } MemPool *GetCodeMempool() { if (useTmpMemPool) { if (codeMemPoolTmp == nullptr) { - codeMemPoolTmp = memPoolCtrler.NewMemPool("func code mempool"); + codeMemPoolTmp = new ThreadLocalMemPool(memPoolCtrler, "func code mempool"); codeMemPoolTmpAllocator.SetMemPool(codeMemPoolTmp); } return codeMemPoolTmp; } if (codeMemPool == nullptr) { - codeMemPool = memPoolCtrler.NewMemPool("func code mempool"); + codeMemPool = new ThreadLocalMemPool(memPoolCtrler, "func code mempool"); codeMemPoolAllocator.SetMemPool(codeMemPool); } return codeMemPool; @@ -473,7 +482,7 @@ class MIRFunction { MapleAllocator &GetCodeMempoolAllocator() { if (codeMemPool == nullptr) { - codeMemPool = memPoolCtrler.NewMemPool("func code mempool"); + codeMemPool = new ThreadLocalMemPool(memPoolCtrler, "func code mempool"); codeMemPoolAllocator.SetMemPool(codeMemPool); } return codeMemPoolAllocator; @@ -900,7 +909,7 @@ class MIRFunction { MemPool *GetCodeMemPool() { if (codeMemPool == nullptr) { - codeMemPool = memPoolCtrler.NewMemPool("func code mempool"); + codeMemPool = new ThreadLocalMemPool(memPoolCtrler, "func code mempool"); codeMemPoolAllocator.SetMemPool(codeMemPool); } return codeMemPool; @@ -952,7 +961,7 @@ class MIRFunction { MemPool *GetCodeMemPoolTmp() { if (codeMemPoolTmp == nullptr) { - codeMemPoolTmp = memPoolCtrler.NewMemPool("func code mempool"); + codeMemPoolTmp = new ThreadLocalMemPool(memPoolCtrler, "func code mempool"); codeMemPoolTmpAllocator.SetMemPool(codeMemPoolTmp); } return codeMemPoolTmp; diff --git a/src/mapleall/maple_ir/src/mir_function.cpp b/src/mapleall/maple_ir/src/mir_function.cpp index ab212d7fa5a88e3228ba3cd432d4e79589f21ce1..83408f5fc893e574bce81cd8afb4076074a22182 100644 --- a/src/mapleall/maple_ir/src/mir_function.cpp +++ b/src/mapleall/maple_ir/src/mir_function.cpp @@ -628,14 +628,14 @@ void MIRFunction::NewBody() { #ifdef DEBUGME void MIRFunction::SetUpGDBEnv() { if (codeMemPool != nullptr) { - memPoolCtrler.DeleteMemPool(codeMemPool); + delete codeMemPool; } - codeMemPool = memPoolCtrler.NewMemPool("tmp debug"); + codeMemPool = new ThreadLocalMemPool(memPoolCtrler, "tmp debug"); codeMemPoolAllocator.SetMemPool(codeMemPool); } void MIRFunction::ResetGDBEnv() { - memPoolCtrler.DeleteMemPool(codeMemPool); + delete codeMemPool; codeMemPool = nullptr; } #endif diff --git a/src/mapleall/maple_ir/src/mir_module.cpp b/src/mapleall/maple_ir/src/mir_module.cpp index 7a0a2b611ef3a32ad3d2d4198ccc6c427118bb1b..858eb2743cd0188d6a07d8e005b44ac72d4b4855 100644 --- a/src/mapleall/maple_ir/src/mir_module.cpp +++ b/src/mapleall/maple_ir/src/mir_module.cpp @@ -30,8 +30,8 @@ namespace maple { #if MIR_FEATURE_FULL // to avoid compilation error when MIR_FEATURE_FULL=0 MIRModule::MIRModule(const std::string &fn) - : memPool(memPoolCtrler.NewMemPool("maple_ir mempool")), - pragmaMemPool(memPoolCtrler.NewMemPool("pragma mempool")), + : memPool(new ThreadShareMemPool(memPoolCtrler, "maple_ir mempool")), + pragmaMemPool(memPoolCtrler.NewMemPool("pragma mempool", false /* isLcalPool */)), memPoolAllocator(memPool), pragmaMemPoolAllocator(pragmaMemPool), functionList(memPoolAllocator.Adapter()), @@ -61,7 +61,10 @@ MIRModule::MIRModule(const std::string &fn) } MIRModule::~MIRModule() { - memPoolCtrler.DeleteMemPool(memPool); + for (MIRFunction *mirFunc : functionList) { + mirFunc->ReleaseCodeMemory(); + } + delete memPool; delete binMplt; } diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index f35fcfe5594bea1fb294894ec9bbdcd36b3b7d6b..05b27f67950307f44f5664e10da20cc7df8f9571 100644 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -1432,7 +1432,7 @@ bool UnaryNode::Verify() const { // When an opcode only specifies one type, check for compatibility // between the operands and the result-type. bool compVerf = true; - // op_alloca : return type is not compatible with operand, skip + // op_alloca : return type is not compatible with operand, skip if (GetOpCode() != OP_alloca) { compVerf = CompatibleTypeVerify(*uOpnd, *this); } diff --git a/src/mapleall/maple_ir/src/mir_type.cpp b/src/mapleall/maple_ir/src/mir_type.cpp index a221f2da12cb953ed3e7ba93f0d4c2ba5a4199c5..c3163794d9a29a61830901b1c99fa80d19de3486 100644 --- a/src/mapleall/maple_ir/src/mir_type.cpp +++ b/src/mapleall/maple_ir/src/mir_type.cpp @@ -160,6 +160,15 @@ bool IsNoCvtNeeded(PrimType toType, PrimType fromType) { // answer in bytes; 0 if unknown uint32 GetPrimTypeSize(PrimType primType) { + if (primType == PTY_ref || primType == PTY_ptr) { +#if TARGX86_64 || TARGAARCH64 + primType = PTY_a64; +#elif TARGX86 || TARGARM32 || TARGVM + primType = PTY_a32; +#else + ASSERT(false, "NIY"); +#endif + } switch (primType) { case PTY_void: case PTY_agg: diff --git a/src/mapleall/maple_ir/src/parser.cpp b/src/mapleall/maple_ir/src/parser.cpp index 0781540088348ba7a25283eb3abb21de8ea8bda0..6b5deb5867a2589867d42ad541e8fa0292890b57 100644 --- a/src/mapleall/maple_ir/src/parser.cpp +++ b/src/mapleall/maple_ir/src/parser.cpp @@ -826,7 +826,19 @@ bool MIRParser::ParseStructType(TyIdx &styIdx, const GStrIdx &strIdx) { GlobalTables::GetTypeTable().SetTypeWithTyIdx(styIdx, *structType.CopyMIRTypeNode()); } } else { - styIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&structType); + TyIdx prevTypeIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(strIdx); + if (prevTypeIdx != 0) { + // if the MIRStructType has been created by name or incompletely, refresh the prev created type + MIRType *prevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(prevTypeIdx); + if (prevType->GetKind() == kTypeByName || + (prevType->GetKind() == kTypeStructIncomplete && tkind == kTypeStruct)) { + structType.SetTypeIndex(prevTypeIdx); + GlobalTables::GetTypeTable().SetTypeWithTyIdx(prevTypeIdx, *structType.CopyMIRTypeNode()); + } + styIdx = prevTypeIdx; + } else { + styIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&structType); + } } lexer.NextToken(); return true; diff --git a/src/mapleall/maple_me/include/alias_class.h b/src/mapleall/maple_me/include/alias_class.h index 876edfd80bcc82c6c97a19304984ad4d72c81de5..9fbb003c4bb3f061534e1b839366fc13b01ebe85 100644 --- a/src/mapleall/maple_me/include/alias_class.h +++ b/src/mapleall/maple_me/include/alias_class.h @@ -187,7 +187,7 @@ class AliasClass : public AnalysisResult { void SetPtrOpndsNextLevNADS(unsigned int start, unsigned int end, MapleVector &opnds, bool hasNoPrivateDefEffect); void ApplyUnionForDassignCopy(const AliasElem &lhsAe, const AliasElem *rhsAe, const BaseNode &rhs); - void CreateMirroringAliasElems(OriginalSt *ost1, OriginalSt *ost2); + void CreateMirroringAliasElems(const OriginalSt *ost1, OriginalSt *ost2); AliasElem *FindOrCreateDummyNADSAe(); bool IsPointedTo(OriginalSt &oSt); AliasElem &FindOrCreateAliasElemOfAddrofOSt(OriginalSt &oSt); @@ -219,6 +219,7 @@ class AliasClass : public AnalysisResult { virtual BB *GetBB(BBId id) = 0; void ProcessIdsAliasWithRoot(const std::set &idsAliasWithRoot, std::vector &newGroups); int GetOffset(const Klass &super, const Klass &base) const; + void UnionAllNodes(MapleVector *nextLevOsts); MemPool &acMemPool; MapleAllocator acAlloc; diff --git a/src/mapleall/maple_me/include/irmap.h b/src/mapleall/maple_me/include/irmap.h index 6ec120292fb28459d3622f0261563c2cd9f04b31..fe2853df1846e5e49b53726c36e734f4550531ce 100644 --- a/src/mapleall/maple_me/include/irmap.h +++ b/src/mapleall/maple_me/include/irmap.h @@ -46,7 +46,7 @@ class IRMap : public AnalysisResult { MeExpr *CreateAddrofMeExpr(MeExpr&); MeExpr *CreateAddroffuncMeExpr(PUIdx); MeExpr *CreateAddrofMeExprFromSymbol(MIRSymbol& sym, PUIdx puIdx); - MeExpr *CreateIaddrofMeExpr(MeExpr &expr, TyIdx tyIdx, MeExpr &base); + MeExpr *CreateIaddrofMeExpr(FieldID fieldId, TyIdx tyIdx, MeExpr *base); MeExpr *CreateIvarMeExpr(MeExpr &expr, TyIdx tyIdx, MeExpr &base); // for creating VarMeExpr diff --git a/src/mapleall/maple_me/include/me_check_cast.h b/src/mapleall/maple_me/include/me_check_cast.h index aebeaa2b6c7d5cf9893ff1e1292528e89d3c44bc..b7169fcf5ed310f95250d853fa9bdb76d2fb7dbe 100644 --- a/src/mapleall/maple_me/include/me_check_cast.h +++ b/src/mapleall/maple_me/include/me_check_cast.h @@ -42,6 +42,13 @@ class CheckCast { void DoCheckCastOpt(); void FindRedundantChecks(); void DeleteRedundants(); + void ReleaseMemory() { + if (graphTempMem != nullptr) { + delete graphTempMem; + graphTempAllocator.SetMemPool(nullptr); + graphTempMem = nullptr; + } + } private: void RemoveRedundantCheckCast(MeStmt &stmt, BB &bb); bool ProvedByAnnotationInfo(const IntrinsiccallMeStmt &callNode); @@ -71,7 +78,7 @@ class CheckCast { MeFunction *func; KlassHierarchy *klassh; MeSSI *meSSI; - MemPool *graphTempMem { memPoolCtrler.NewMemPool("graph mempool tmp") }; + MemPool *graphTempMem { new ThreadLocalMemPool(memPoolCtrler, "graph mempool tmp") }; MapleAllocator graphTempAllocator { graphTempMem }; MIRType *curCheckCastType { nullptr }; std::vector redundantChecks; diff --git a/src/mapleall/maple_me/include/me_function.h b/src/mapleall/maple_me/include/me_function.h index 47f801f28b784dd35294dd9b3134dbb56337e70e..d102ac9f7547a157bcefdeab1727346fc62ae93a 100644 --- a/src/mapleall/maple_me/include/me_function.h +++ b/src/mapleall/maple_me/include/me_function.h @@ -160,9 +160,10 @@ class MeFunction : public FuncEmit { using reverse_iterator = BBPtrHolder::reverse_iterator; using const_reverse_iterator = BBPtrHolder::const_reverse_iterator; - MeFunction(MIRModule *mod, MIRFunction *func, MemPool *memPool, MemPool *versMemPool, + MeFunction(MIRModule *mod, MIRFunction *func, MemPool *memPool, StackMemPool &funcStackMP, MemPool *versMemPool, const std::string &fileName) : memPool(memPool), + stackMP(funcStackMP), alloc(memPool), versMemPool(versMemPool), versAlloc(versMemPool), @@ -447,6 +448,14 @@ class MeFunction : public FuncEmit { return versMemPool; } + void ReleaseVersMemory() { + if (versMemPool != nullptr) { + delete versMemPool; + versMemPool = nullptr; + versAlloc.SetMemPool(nullptr); + } + } + void SetNextBBId(uint32 currNextBBId) { nextBBId = currNextBBId; } @@ -477,6 +486,10 @@ class MeFunction : public FuncEmit { return memPool; } + StackMemPool &GetStackMemPool() { + return stackMP; + } + void AddProfileDesc(uint64 hash, uint32 start, uint32 end) { mirFunc->AddProfileDesc(hash, start, end); } @@ -524,6 +537,7 @@ class MeFunction : public FuncEmit { void SplitBBPhysically(BB &bb, StmtNode &splitPoint, BB &newBB); MemPool *memPool; + StackMemPool &stackMP; MapleAllocator alloc; MemPool *versMemPool; MapleAllocator versAlloc; diff --git a/src/mapleall/maple_me/include/me_phase_manager.h b/src/mapleall/maple_me/include/me_phase_manager.h index fc92b84a3d18137da0df16aeb981180e4efd192e..5991649f009ed8834b0e29f7712d9b796926e6fe 100644 --- a/src/mapleall/maple_me/include/me_phase_manager.h +++ b/src/mapleall/maple_me/include/me_phase_manager.h @@ -56,7 +56,6 @@ class MeFuncPhaseManager : public PhaseManager { void Run(MIRFunction *mirFunc, uint64 rangeNum, const std::string &meInput, MemPoolCtrler &localMpCtrler = memPoolCtrler); - void IPACleanUp(MeFunction *mirfunc); void Run() override {} MeFuncPhaseManager &Clone(MemPool &mp, MemPoolCtrler &ctrler) const; diff --git a/src/mapleall/maple_me/include/ver_symbol.h b/src/mapleall/maple_me/include/ver_symbol.h index 79c0d62321cb0827c4bb53963484bacfe67a683d..2f8e1eac904ca40ada8bc4bc2aab3272275cdad8 100644 --- a/src/mapleall/maple_me/include/ver_symbol.h +++ b/src/mapleall/maple_me/include/ver_symbol.h @@ -19,9 +19,6 @@ #include "mir_symbol.h" #include "orig_symbol.h" -// This file defines the data structure VersionSt that represents an SSA version -struct BBId; - namespace maple { class BB; // circular dependency exists, no other choice class PhiNode; // circular dependency exists, no other choice diff --git a/src/mapleall/maple_me/src/alias_class.cpp b/src/mapleall/maple_me/src/alias_class.cpp index b0985da21bde3a1c59eb3606b75470c18911e0f5..575f73fdf262a6decbbdb7b143206cffa6aa57a5 100644 --- a/src/mapleall/maple_me/src/alias_class.cpp +++ b/src/mapleall/maple_me/src/alias_class.cpp @@ -38,29 +38,29 @@ inline bool IsPotentialAddress(PrimType primType, const MIRModule *mirModule) { // return true if this expression opcode can result in a valid address static bool OpCanFormAddress(Opcode op) { switch (op) { - case OP_dread: - case OP_regread: - case OP_iread: - case OP_ireadoff: - case OP_ireadfpoff: - case OP_ireadpcoff: - case OP_addrof: - case OP_addroffunc: - case OP_addroflabel: - case OP_addroffpc: - case OP_iaddrof: - case OP_constval: - case OP_conststr: - case OP_conststr16: - case OP_alloca: - case OP_malloc: - case OP_add: - case OP_sub: - case OP_select: - case OP_array: - case OP_intrinsicop: - return true; - default: ; + case OP_dread: + case OP_regread: + case OP_iread: + case OP_ireadoff: + case OP_ireadfpoff: + case OP_ireadpcoff: + case OP_addrof: + case OP_addroffunc: + case OP_addroflabel: + case OP_addroffpc: + case OP_iaddrof: + case OP_constval: + case OP_conststr: + case OP_conststr16: + case OP_alloca: + case OP_malloc: + case OP_add: + case OP_sub: + case OP_select: + case OP_array: + case OP_intrinsicop: + return true; + default: ; } return false; } @@ -145,7 +145,6 @@ AliasElem *AliasClass::FindOrCreateAliasElem(OriginalSt &ost) { } if (ost.GetIndirectLev() > 1) { aliasElem->SetNotAllDefsSeen(true); - aliasElem->SetNextLevNotAllDefsSeen(true); } id2Elem.push_back(aliasElem); osym2Elem[ostIdx] = aliasElem; @@ -307,7 +306,7 @@ void AliasClass::SetPtrOpndsNextLevNADS(unsigned int start, unsigned int end, } // based on ost1's extra level ost's, ensure corresponding ones exist for ost2 -void AliasClass::CreateMirroringAliasElems(OriginalSt *ost1, OriginalSt *ost2) { +void AliasClass::CreateMirroringAliasElems(const OriginalSt *ost1, OriginalSt *ost2) { if (ost1->IsSameSymOrPreg(ost2)) { return; } @@ -476,9 +475,10 @@ void AliasClass::ApplyUnionForPointedTos() { for (AliasElem *aliaselem : id2Elem) { if (aliaselem->GetAssignSet() == nullptr) { if (aliaselem->IsNextLevNotAllDefsSeen()) { - MapleVector *nextLevelNodes = GetAliasAnalysisTable()->GetNextLevelNodes(aliaselem->GetOriginalSt()); + MapleVector *nextLevelNodes = + GetAliasAnalysisTable()->GetNextLevelNodes(aliaselem->GetOriginalSt()); MapleVector::iterator ostit = nextLevelNodes->begin(); - for (; ostit != nextLevelNodes->end(); ostit++) { + for (; ostit != nextLevelNodes->end(); ++ostit) { AliasElem *indae = FindAliasElem(**ostit); if (!indae->GetOriginalSt().IsFinal()) { indae->SetNotAllDefsSeen(true); @@ -497,8 +497,8 @@ void AliasClass::ApplyUnionForPointedTos() { // iterate through all the alias elems to check if any has indirectLev > 0 // or if any has nextLevNotAllDefsSeen being true bool hasNextLevNotAllDefsSeen = false; - for (MapleSet::iterator setit = aliaselem->GetAssignSet()->begin(); setit != aliaselem->GetAssignSet()->end(); - setit++) { + for (auto setit = aliaselem->GetAssignSet()->begin(); setit != aliaselem->GetAssignSet()->end(); + ++setit) { AliasElem *ae0 = id2Elem[*setit]; if (ae0->GetOriginalSt().GetIndirectLev() > 0 || ae0->IsNotAllDefsSeen() || ae0->IsNextLevNotAllDefsSeen()) { hasNextLevNotAllDefsSeen = true; @@ -507,12 +507,12 @@ void AliasClass::ApplyUnionForPointedTos() { } if (hasNextLevNotAllDefsSeen) { // make all pointedto's in this assignSet notAllDefsSeen - for (MapleSet::iterator setit = aliaselem->GetAssignSet()->begin(); setit != aliaselem->GetAssignSet()->end(); - setit++) { + for (auto setit = aliaselem->GetAssignSet()->begin(); setit != aliaselem->GetAssignSet()->end(); + ++setit) { AliasElem *ae0 = id2Elem[*setit]; MapleVector *nextLevelNodes = GetAliasAnalysisTable()->GetNextLevelNodes(ae0->GetOriginalSt()); MapleVector::iterator ostit = nextLevelNodes->begin(); - for (; ostit != nextLevelNodes->end(); ostit++) { + for (; ostit != nextLevelNodes->end(); ++ostit) { AliasElem *indae = FindAliasElem(**ostit); if (!indae->GetOriginalSt().IsFinal()) { indae->SetNotAllDefsSeen(true); @@ -531,15 +531,15 @@ void AliasClass::ApplyUnionForPointedTos() { break; // done processing all elements in assignSet } AliasElem *ae1 = id2Elem[*pickit]; - tempset.erase(pickit); - for (MapleSet::iterator setit = tempset.begin(); setit != tempset.end(); setit++) { + (void)tempset.erase(pickit); + for (MapleSet::iterator setit = tempset.begin(); setit != tempset.end(); ++setit) { AliasElem *ae2 = id2Elem[*setit]; MapleVector *nextLevelNodes1 = GetAliasAnalysisTable()->GetNextLevelNodes(ae1->GetOriginalSt()); MapleVector::iterator ost1it = nextLevelNodes1->begin(); - for (; ost1it != nextLevelNodes1->end(); ost1it++) { + for (; ost1it != nextLevelNodes1->end(); ++ost1it) { MapleVector *nextLevelNodes2 = GetAliasAnalysisTable()->GetNextLevelNodes(ae2->GetOriginalSt()); MapleVector::iterator ost2it = nextLevelNodes2->begin(); - for (; ost2it != nextLevelNodes2->end(); ost2it++) { + for (; ost2it != nextLevelNodes2->end(); ++ost2it) { bool hasFieldid0 = (*ost1it)->GetFieldID() == 0 || (*ost2it)->GetFieldID() == 0; if (((*ost1it)->GetFieldID() != (*ost2it)->GetFieldID()) && !hasFieldid0) { continue; @@ -615,7 +615,7 @@ void AliasClass::UnionForNotAllDefsSeenCLang() { // notAllDefsSeenAe is the first notAllDefsSeen AliasElem. // Union notAllDefsSeenAe with the other notAllDefsSeen aes. AliasElem *notAllDefsSeenAe = notAllDefsSeenAes[0]; - notAllDefsSeenAes.erase(notAllDefsSeenAes.begin()); + (void)notAllDefsSeenAes.erase(notAllDefsSeenAes.begin()); for (AliasElem *ae : notAllDefsSeenAes) { unionFind.Union(notAllDefsSeenAe->GetClassID(), ae->GetClassID()); } @@ -642,7 +642,6 @@ void AliasClass::UnionForNotAllDefsSeenCLang() { } OriginalSt *ostOfAe = &(ae->GetOriginalSt()); bool hasNotAllDefsSeen = ae->IsNotAllDefsSeen() || ostOfAe->GetMIRSymbol()->GetStorageClass() == kScFormal; - MapleForwardList::iterator it; if (!hasNotAllDefsSeen) { // see if any at level 1 has notAllDefsSeen set for (OriginalSt *nextLevelNode : *GetAliasAnalysisTable()->GetNextLevelNodes(*ost)) { @@ -656,10 +655,10 @@ void AliasClass::UnionForNotAllDefsSeenCLang() { if (hasNotAllDefsSeen) { // set to true for all members at this level for (OriginalSt *nextLevelNode : *GetAliasAnalysisTable()->GetNextLevelNodes(*ost)) { - AliasElem *ae = osym2Elem[nextLevelNode->GetIndex()]; - if (ae != nullptr) { - ae->SetNotAllDefsSeen(true); - unionFind.Union(notAllDefsSeenAe->GetClassID(), ae->GetClassID()); + AliasElem *nextLevAE = osym2Elem[nextLevelNode->GetIndex()]; + if (nextLevAE != nullptr) { + nextLevAE->SetNotAllDefsSeen(true); + unionFind.Union(notAllDefsSeenAe->GetClassID(), nextLevAE->GetClassID()); } } } @@ -714,28 +713,51 @@ AliasElem *AliasClass::FindOrCreateDummyNADSAe() { } } +void AliasClass::UnionAllNodes(MapleVector *nextLevOsts) { + if (nextLevOsts->size() < 2) { + return; + } + + auto it = nextLevOsts->begin(); + OriginalSt *ostA = *it; + AliasElem *aeA = FindAliasElem(*ostA); + ++it; + for (; it != nextLevOsts->end(); ++it) { + OriginalSt *ostB = *it; + AliasElem *aeB = FindAliasElem(*ostB); + unionFind.Union(aeA->GetClassID(), aeB->GetClassID()); + } +} + // This is applicable only for C language. For each ost that is a struct, // union all fields within the same struct void AliasClass::ApplyUnionForStorageOverlaps() { // iterate through all the alias elems for (AliasElem *ae : id2Elem) { OriginalSt *ost = &ae->GetOriginalSt(); - OriginalSt *prevLevOst = GetAliasAnalysisTable()->GetPrevLevelNode(*ost); - if (prevLevOst == nullptr) { + MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ost->GetTyIdx()); + if (mirType->GetKind() != kTypePointer) { continue; } - MIRType *prevLevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(prevLevOst->GetTyIdx()); - if (prevLevType->GetKind() != kTypePointer) { + auto nextLevOsts = GetAliasAnalysisTable()->GetNextLevelNodes(*ost); + if (nextLevOsts == nullptr) { continue; } - MIRType *prevLevPointedType = static_cast(prevLevType)->GetPointedType(); - MIRType *ostType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ost->GetTyIdx()); - if (!ostType->HasFields() && prevLevPointedType->GetKind() != kTypeUnion) { + + MIRType *pointedType = static_cast(mirType)->GetPointedType(); + if (pointedType->GetKind() == kTypeUnion) { + // union all fields of union + UnionAllNodes(nextLevOsts); continue; } - for (OriginalSt *sameLevOst : *GetAliasAnalysisTable()->GetNextLevelNodes(*prevLevOst)) { - AliasElem *ae1 = FindAliasElem(*sameLevOst); - unionFind.Union(ae->GetClassID(), ae1->GetClassID()); + + for (auto *nextLevOst : *nextLevOsts) { + MIRType *nextLevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(nextLevOst->GetTyIdx()); + if (nextLevType->HasFields()) { + // union all fields if one next-level-ost has fields + UnionAllNodes(nextLevOsts); + break; + } } } } @@ -1454,8 +1476,6 @@ void AliasClass::InsertMayDefUseIntrncall(StmtNode &stmt, BBId bbid) { for (uint32 i = 0; i < stmt.NumOpnds(); ++i) { InsertMayUseExpr(*stmt.Opnd(i)); } - } else { - CollectMayUseFromNADS(mayDefUseOsts); } // 2. collect mayDefs and mayUses caused by not_all_defs_seen_ae CollectMayUseFromNADS(mayDefUseOsts); diff --git a/src/mapleall/maple_me/src/irmap.cpp b/src/mapleall/maple_me/src/irmap.cpp index 8ff33c0e4d3d287164c087f3211d27e07a378db8..1e710bb9fa4de927233cb773c867b705d17c6d5c 100644 --- a/src/mapleall/maple_me/src/irmap.cpp +++ b/src/mapleall/maple_me/src/irmap.cpp @@ -50,13 +50,11 @@ MeExpr *IRMap::CreateAddroffuncMeExpr(PUIdx puIdx) { return HashMeExpr(addroffuncMeExpr); } -MeExpr *IRMap::CreateIaddrofMeExpr(MeExpr &expr, TyIdx tyIdx, MeExpr &base) { - ASSERT(expr.GetMeOp() == kMeOpIvar, "expecting IVarMeExpr"); - auto &ivarExpr = static_cast(expr); +MeExpr *IRMap::CreateIaddrofMeExpr(FieldID fieldId, TyIdx tyIdx, MeExpr *base) { OpMeExpr opMeExpr(kInvalidExprID, OP_iaddrof, PTY_ptr, 1); - opMeExpr.SetFieldID(ivarExpr.GetFieldID()); + opMeExpr.SetFieldID(fieldId); opMeExpr.SetTyIdx(tyIdx); - opMeExpr.SetOpnd(0, &base); + opMeExpr.SetOpnd(0, base); return HashMeExpr(opMeExpr); } diff --git a/src/mapleall/maple_me/src/me_cfg_opt.cpp b/src/mapleall/maple_me/src/me_cfg_opt.cpp index f42e85c875e033cca3131c6929b615b7f2c0528a..23ce0680f6e230c96a4b7cab12481b3b9b4eeed9 100644 --- a/src/mapleall/maple_me/src/me_cfg_opt.cpp +++ b/src/mapleall/maple_me/src/me_cfg_opt.cpp @@ -337,12 +337,11 @@ void MeDoCfgOpt::EmitMapleIr(MeFunction &func, MeFuncResultMgr &m) { auto layoutBBs = func.GetLaidOutBBs(); CHECK_NULL_FATAL(func.GetIRMap()); MIRFunction *mirFunction = func.GetMirFunc(); - if (mirFunction->GetCodeMemPool() != nullptr) { - mirFunction->GetCodeMemPool()->Release(); - } - mirFunction->SetCodeMemPool(memPoolCtrler.NewMemPool("IR from IRMap::Emit()")); - mirFunction->GetCodeMPAllocator().SetMemPool(mirFunction->GetCodeMemPool()); + + mirFunction->ReleaseCodeMemory(); + mirFunction->SetMemPool(new ThreadLocalMemPool(memPoolCtrler, "IR from IRMap::Emit()")); mirFunction->SetBody(mirFunction->GetCodeMemPool()->New()); + for (size_t k = 1; k < mirFunction->GetSymTab()->GetSymbolTableSize(); ++k) { MIRSymbol *sym = mirFunction->GetSymTab()->GetSymbolFromStIdx(k); if (sym->GetSKind() == kStVar) { diff --git a/src/mapleall/maple_me/src/me_check_cast.cpp b/src/mapleall/maple_me/src/me_check_cast.cpp index 05632feaa2893d709284487735626f99749937b1..c305657cf4bf04cadbc7c237fa204af52f97a88a 100644 --- a/src/mapleall/maple_me/src/me_check_cast.cpp +++ b/src/mapleall/maple_me/src/me_check_cast.cpp @@ -668,7 +668,7 @@ void CheckCast::DoCheckCastOpt() { } } } - memPoolCtrler.DeleteMemPool(graphTempMem); + ReleaseMemory(); } void CheckCast::FindRedundantChecks() { diff --git a/src/mapleall/maple_me/src/me_emit.cpp b/src/mapleall/maple_me/src/me_emit.cpp index d568e8ee82508b319b0636ea5f83d8423c631d09..6be456c4fc424255351f674cf74db572bc7155ff 100644 --- a/src/mapleall/maple_me/src/me_emit.cpp +++ b/src/mapleall/maple_me/src/me_emit.cpp @@ -31,11 +31,9 @@ AnalysisResult *MeDoEmit::Run(MeFunction *func, MeFuncResultMgr*, ModuleResultMg CHECK_FATAL(func->HasLaidOut(), "Check/Run bb layout phase."); auto layoutBBs = func->GetLaidOutBBs(); MIRFunction *mirFunction = func->GetMirFunc(); - if (mirFunction->GetCodeMempool() != nullptr) { - mirFunction->GetCodeMempool()->Release(); - } - mirFunction->SetCodeMemPool(memPoolCtrler.NewMemPool("IR from IRMap::Emit()")); - mirFunction->GetCodeMPAllocator().SetMemPool(mirFunction->GetCodeMempool()); + mirFunction->ReleaseCodeMemory(); + + mirFunction->SetMemPool(new ThreadLocalMemPool(memPoolCtrler, "IR from IRMap::Emit()")); mirFunction->SetBody(mirFunction->GetCodeMempool()->New()); // initialize is_deleted field to true; will reset when emitting Maple IR for (size_t k = 1; k < mirFunction->GetSymTab()->GetSymbolTableSize(); ++k) { diff --git a/src/mapleall/maple_me/src/me_func_opt.cpp b/src/mapleall/maple_me/src/me_func_opt.cpp index ab9094a4b29d7861e1d7ec0fe3287d64a428a02f..e4a2ac1430f50e5e956719e98da078085e9b5eb8 100644 --- a/src/mapleall/maple_me/src/me_func_opt.cpp +++ b/src/mapleall/maple_me/src/me_func_opt.cpp @@ -29,7 +29,7 @@ int MeFuncOptTask::RunImpl(MplTaskParam *param) { std::unique_ptr MeFuncOptExecutor::Clone() const { // thread local memPoolCtrler and fpm auto threadLocalCtrler = std::make_unique(); - auto *memPool = threadLocalCtrler->NewMemPool("thread local func opt mempool"); + auto *memPool = threadLocalCtrler->NewMemPool("thread local func opt mempool", true /* isLcalPool */); MeFuncPhaseManager &fpmCopy = fpm.Clone(*memPool, *threadLocalCtrler); auto copy = std::make_unique(std::move(threadLocalCtrler), fpmCopy); return copy; diff --git a/src/mapleall/maple_me/src/me_irmap.cpp b/src/mapleall/maple_me/src/me_irmap.cpp index 65e4de3baf7add323c8445c432b4b241ff262539..e10f5759cbf4f2fa0013e1f248c0c54dbc726f89 100644 --- a/src/mapleall/maple_me/src/me_irmap.cpp +++ b/src/mapleall/maple_me/src/me_irmap.cpp @@ -20,7 +20,7 @@ void MeIRMap::Dump() { // we dump IRMap, restore the mempool afterwards MIRFunction *mirFunction = func.GetMirFunc(); MemPool *backup = mirFunction->GetCodeMempool(); - mirFunction->SetMemPool(memPoolCtrler.NewMemPool("IR Dump")); + mirFunction->SetMemPool(new ThreadLocalMemPool(memPoolCtrler, "IR Dump")); LogInfo::MapleLogger() << "===================Me IR dump==================\n"; auto eIt = func.valid_end(); for (auto bIt = func.valid_begin(); bIt != eIt; ++bIt) { @@ -40,7 +40,7 @@ void MeIRMap::Dump() { meStmt.Dump(this); } } - memPoolCtrler.DeleteMemPool(mirFunction->GetCodeMempool()); + mirFunction->ReleaseCodeMemory(); mirFunction->SetMemPool(backup); } } // namespace maple diff --git a/src/mapleall/maple_me/src/me_irmap_build.cpp b/src/mapleall/maple_me/src/me_irmap_build.cpp index 6e16faa4c689dedaf32555391caade85b31dee40..32d8100b3e2e2b554eddeee5a6e70d8057ec170b 100644 --- a/src/mapleall/maple_me/src/me_irmap_build.cpp +++ b/src/mapleall/maple_me/src/me_irmap_build.cpp @@ -37,7 +37,7 @@ AnalysisResult *MeDoIRMapBuild::Run(MeFunction *func, MeFuncResultMgr *funcResMg MemPool *propMp = nullptr; if (!func->GetMIRModule().IsJavaModule() && MeOption::propDuringBuild) { // create propgation - propMp = memPoolCtrler.NewMemPool("meirbuild prop"); + propMp = memPoolCtrler.NewMemPool("meirbuild prop", true /* isLocalPool */); MeProp meprop(*irMap, *dom, *propMp, Prop::PropConfig{false, false, false, false, false, false}); IRMapBuild irmapbuild(irMap, dom, &meprop); std::vector bbIrmapProcessed(func->NumBBs(), false); @@ -54,8 +54,7 @@ AnalysisResult *MeDoIRMapBuild::Run(MeFunction *func, MeFuncResultMgr *funcResMg // delete mempool for meirmap temporaries // delete input IR code for current function MIRFunction *mirFunc = func->GetMirFunc(); - mirFunc->GetCodeMempool()->Release(); - mirFunc->SetCodeMemPool(nullptr); + mirFunc->ReleaseCodeMemory(); // delete versionst_table // nullify all references to the versionst_table contents @@ -70,7 +69,7 @@ AnalysisResult *MeDoIRMapBuild::Run(MeFunction *func, MeFuncResultMgr *funcResMg bb->SetFirst(nullptr); bb->SetLast(nullptr); } - func->GetMeSSATab()->GetVersionStTable().GetVSTAlloc().GetMemPool()->Release(); + func->ReleaseVersMemory(); funcResMgr->InvalidAnalysisResult(MeFuncPhase_SSA, func); funcResMgr->InvalidAnalysisResult(MeFuncPhase_DSE, func); if (propMp) { diff --git a/src/mapleall/maple_me/src/me_lower_globals.cpp b/src/mapleall/maple_me/src/me_lower_globals.cpp index be4041d5891c994e7e44bdd5dde2d5d6b61d8639..d808aff4397b324c58cf65608c082f1aa6cd1fb4 100644 --- a/src/mapleall/maple_me/src/me_lower_globals.cpp +++ b/src/mapleall/maple_me/src/me_lower_globals.cpp @@ -93,7 +93,7 @@ void MeLowerGlobals::LowerGlobalDreads(MeStmt &stmt, MeExpr &expr) { MIRPtrType ptrType(baseOst->GetTyIdx(), PTY_ptr); TyIdx addrTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType); ASSERT_NOT_NULL(irMap); - MeExpr *iaddrofExpr = irMap->CreateIaddrofMeExpr(addrofExpr, addrTyIdx, *newAddrofExpr); + MeExpr *iaddrofExpr = irMap->CreateIaddrofMeExpr(addrofExpr.GetFieldID(), addrTyIdx, newAddrofExpr); (void)irMap->ReplaceMeExprStmt(stmt, addrofExpr, *iaddrofExpr); break; } diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index 1342d1a3558beba480f8e763b575ff059561c05f..6e1562fe133ae5a2f56f1cc8af4bf201f1af7551 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -193,12 +193,6 @@ bool MeFuncPhaseManager::FuncFilter(const std::string &filter, const std::string return (filter == "*") || (name.find(filter) != std::string::npos); } -void MeFuncPhaseManager::IPACleanUp(MeFunction *func) { - ASSERT(func != nullptr, "null ptr check"); - GetAnalysisResultManager()->InvalidAllResults(); - memPoolCtrler.DeleteMemPool(func->GetMemPool()); -} - void MeFuncPhaseManager::Run(MIRFunction *mirFunc, uint64 rangeNum, const std::string &meInput, MemPoolCtrler &localMpCtrler) { if (!MeOption::quiet) { @@ -212,9 +206,10 @@ void MeFuncPhaseManager::Run(MIRFunction *mirFunc, uint64 rangeNum, const std::s if (timePhases) { funcPrepareTimer.Start(); } - MemPool *funcMP = localMpCtrler.NewMemPool("maple_me per-function mempool"); - MemPool *versMP = localMpCtrler.NewMemPool("first verst mempool"); - MeFunction &func = *(funcMP->New(&mirModule, mirFunc, funcMP, versMP, meInput)); + auto funcMP = std::make_unique(localMpCtrler, "maple_me per-function mempool"); + auto funcStackMP = std::make_unique(localMpCtrler, ""); + MemPool *versMP = new ThreadLocalMemPool(localMpCtrler, "first verst mempool"); + MeFunction &func = *(funcMP->New(&mirModule, mirFunc, funcMP.get(), *funcStackMP, versMP, meInput)); func.PartialInit(false); #if DEBUG globalMIRModule = &mirModule; @@ -313,10 +308,10 @@ void MeFuncPhaseManager::Run(MIRFunction *mirFunc, uint64 rangeNum, const std::s funcPrepareTimer.Start(); } // do all the phases start over - MemPool *versMemPool = localMpCtrler.NewMemPool("second verst mempool"); - MeFunction function(&mirModule, mirFunc, funcMP, versMemPool, meInput); - function.PartialInit(true); - function.Prepare(rangeNum); + auto *versMemPool = new ThreadLocalMemPool(localMpCtrler, "second verst mempool"); + auto function = funcMP->New(&mirModule, mirFunc, funcMP.get(), *funcStackMP, versMemPool, meInput); + function->PartialInit(true); + function->Prepare(rangeNum); if (timePhases) { funcPrepareTimer.Stop(); extraMeTimers["prepareFunc"] += funcPrepareTimer.ElapsedMicroseconds(); @@ -344,19 +339,19 @@ void MeFuncPhaseManager::Run(MIRFunction *mirFunc, uint64 rangeNum, const std::s if (MeOption::dumpBefore && dumpFunc && dumpPhase) { LogInfo::MapleLogger() << ">>>>>Second time Dump before " << phaseName << " <<<<<\n"; if (phaseName != "emit") { - function.Dump(false); + function->Dump(false); } else { - function.DumpFunctionNoSSA(); + function->DumpFunctionNoSSA(); } LogInfo::MapleLogger() << ">>>>> Second time Dump before End <<<<<\n"; } - RunFuncPhase(&function, p); + RunFuncPhase(function, p); if ((MeOption::dumpAfter || dumpPhase) && dumpFunc) { LogInfo::MapleLogger() << ">>>>>Second time Dump after " << phaseName << " <<<<<\n"; if (phaseName != "emit") { - function.Dump(false); + function->Dump(false); } else { - function.DumpFunctionNoSSA(); + function->DumpFunctionNoSSA(); } LogInfo::MapleLogger() << ">>>>> Second time Dump after End <<<<<\n\n"; } @@ -391,8 +386,6 @@ void MeFuncPhaseManager::Run(MIRFunction *mirFunc, uint64 rangeNum, const std::s invalidTimer.Start(); } - localMpCtrler.DeleteMemPool(funcMP); - if (timePhases) { invalidTimer.Stop(); extraMeTimers["invalidResult"] += invalidTimer.ElapsedMicroseconds(); diff --git a/src/mapleall/maple_me/src/me_rename2preg.cpp b/src/mapleall/maple_me/src/me_rename2preg.cpp index c5391fb10c1c740e8778ca9908bf1b43c8ba795c..4bcf7bb3b98310bf117b91a2cc17812c6491e703 100644 --- a/src/mapleall/maple_me/src/me_rename2preg.cpp +++ b/src/mapleall/maple_me/src/me_rename2preg.cpp @@ -349,11 +349,11 @@ AnalysisResult *MeDoSSARename2Preg::Run(MeFunction *func, MeFuncResultMgr *m, Mo MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); ASSERT(irMap != nullptr, ""); - MemPool *renamemp = memPoolCtrler.NewMemPool(PhaseName().c_str()); + MemPool *renamemp = memPoolCtrler.NewMemPool(PhaseName().c_str(), true /* isLocalPool */); if (func->GetAllBBs().size() == 0) { // empty function, we only promote the parameter - SSARename2Preg emptyrenamer(renamemp, func, nullptr, nullptr); - emptyrenamer.PromoteEmptyFunction(); + auto *emptyrenamer = renamemp->New(renamemp, func, nullptr, nullptr); + emptyrenamer->PromoteEmptyFunction(); memPoolCtrler.DeleteMemPool(renamemp); return nullptr; } @@ -361,8 +361,8 @@ AnalysisResult *MeDoSSARename2Preg::Run(MeFunction *func, MeFuncResultMgr *m, Mo AliasClass *aliasclass = static_cast(m->GetAnalysisResult(MeFuncPhase_ALIASCLASS, func)); ASSERT(aliasclass != nullptr, ""); - SSARename2Preg ssarename2preg(renamemp, func, irMap, aliasclass); - ssarename2preg.RunSelf(); + auto *phase = renamemp->New(renamemp, func, irMap, aliasclass); + phase->RunSelf(); if (DEBUGFUNC(func)) { irMap->Dump(); } diff --git a/src/mapleall/maple_me/src/me_ssu_pre.cpp b/src/mapleall/maple_me/src/me_ssu_pre.cpp index 94a2dafe804da9f6d321e1f1962ac5d22a86da1c..308a187f4c1b1d976deadc0d92653c531f146820 100644 --- a/src/mapleall/maple_me/src/me_ssu_pre.cpp +++ b/src/mapleall/maple_me/src/me_ssu_pre.cpp @@ -277,23 +277,7 @@ void MeSSUPre::Rename() { if (!occStack.empty()) { SOcc *topOcc = occStack.top(); if (topOcc->GetOccTy() == kSOccLambda) { - // make sure this lambda is dominated by at least one kill occurrence - for (SOcc *realOcc : workCand->GetRealOccs()) { - if (realOcc->GetOccTy() == kSOccUse || realOcc->GetOccTy() == kSOccPhi) { - continue; - } - CHECK_FATAL(realOcc->GetOccTy() == kSOccReal, "just check"); - if ((preKind == kDecrefPre || preKind == kSecondDecrefPre) && - !static_cast(realOcc)->GetRealFromDef()) { - continue; - } - CHECK_NULL_FATAL(dom); - if (!dom->Dominate(realOcc->GetBB(), topOcc->GetBB())) { - continue; - } - static_cast(topOcc)->SetIsUpsafe(false); - break; - } + static_cast(topOcc)->SetIsUpsafe(false); } } break; diff --git a/src/mapleall/maple_me/src/me_store_pre.cpp b/src/mapleall/maple_me/src/me_store_pre.cpp index ff61a44419510d56ec864bcbcfd2e75dea4d8c68..57fea929c055b49e214775b5e5b8d5ecaaee0caf 100644 --- a/src/mapleall/maple_me/src/me_store_pre.cpp +++ b/src/mapleall/maple_me/src/me_store_pre.cpp @@ -307,7 +307,7 @@ void MeStorePre::BuildWorkListBB(BB *bb) { OStIdx lhsOstIdx(0); if (stmt->GetOp() == OP_dassign) { auto *dass = static_cast(to_ptr(stmt)); - if (dass->GetLHS()->GetPrimType() != PTY_ref) { + if (dass->GetLHS()->GetPrimType() != PTY_ref && dass->GetLHS()->GetPrimType() != PTY_agg) { lhsOstIdx = dass->GetVarLHS()->GetOstIdx(); } } else if (kOpcodeInfo.IsCallAssigned(stmt->GetOp())) { @@ -315,7 +315,7 @@ void MeStorePre::BuildWorkListBB(BB *bb) { CHECK_NULL_FATAL(mustDefList); if (!mustDefList->empty()) { MeExpr *mdLHS = mustDefList->front().GetLHS(); - if (mdLHS->GetMeOp() == kMeOpVar && mdLHS->GetPrimType() != PTY_ref) { + if (mdLHS->GetMeOp() == kMeOpVar && mdLHS->GetPrimType() != PTY_ref && mdLHS->GetPrimType() != PTY_agg) { lhsOstIdx = static_cast(mdLHS)->GetOstIdx(); } } diff --git a/src/mapleall/maple_me/src/preg_renamer.cpp b/src/mapleall/maple_me/src/preg_renamer.cpp index a8f5aef807ba61c3ebd26fee4c370c3c7ccc58a0..b04fe5bec7bd709c8294e6bba8c199860a8e1094 100644 --- a/src/mapleall/maple_me/src/preg_renamer.cpp +++ b/src/mapleall/maple_me/src/preg_renamer.cpp @@ -111,7 +111,7 @@ void PregRenamer::RunSelf() { AnalysisResult *MeDoPregRename::Run(MeFunction *func, MeFuncResultMgr *frm, ModuleResultMgr *mrm) { MeIRMap *irmap = static_cast(frm->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); std::string renamePhaseName = PhaseName(); - MemPool *renamemp = memPoolCtrler.NewMemPool(renamePhaseName); + MemPool *renamemp = memPoolCtrler.NewMemPool(renamePhaseName, true /* isLocalPool */); PregRenamer pregrenamer(renamemp, func, irmap); pregrenamer.RunSelf(); if (DEBUGFUNC(func)) { diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index daeb5e10a1863764df5b19a608aaedbbbf2c401c..a393f2a43f410202fde2fb3491cc07f58781dd82 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -50,9 +50,7 @@ ScalarMeExpr *SSAPre::CreateNewCurTemp(const MeExpr &meExpr) { SetCurFunction(workCand->GetPUIdx()); RegMeExpr *regVar = nullptr; if (meExpr.GetMeOp() == kMeOpVar) { - auto *varMeExpr = static_cast(&meExpr); - const MIRSymbol *sym = varMeExpr->GetOst()->GetMIRSymbol(); - MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); + auto *ty = static_cast(meExpr).GetType(); regVar = ty->GetPrimType() == PTY_ref ? irMap->CreateRegMeExpr(*ty) : irMap->CreateRegMeExpr(ty->GetPrimType()); } else if (meExpr.GetMeOp() == kMeOpIvar) { diff --git a/src/mapleall/maple_phase/include/phase.h b/src/mapleall/maple_phase/include/phase.h index a1b17f8169c911d67a2335dacf0ec3e4815256f6..c513dd16139732137571a0d6c7a66bf10b964078 100644 --- a/src/mapleall/maple_phase/include/phase.h +++ b/src/mapleall/maple_phase/include/phase.h @@ -40,7 +40,8 @@ class AnalysisResult { } void EraseMemPool() { - memPool->Release(); + delete memPool; + memPool = nullptr; } private: @@ -62,11 +63,15 @@ class Phase { // obtain a new mempool by invoke this function MemPool *NewMemPool() { +#ifdef MP_DEBUG std::string phaseName = PhaseName(); ASSERT(!phaseName.empty(), "PhaseName should not be empty"); ++memPoolCount; std::string memPoolName = phaseName + " MemPool " + std::to_string(memPoolCount); - MemPool *memPool = mpCtrler->NewMemPool(memPoolName); + MemPool *memPool = new ThreadLocalMemPool(*mpCtrler, memPoolName); +#else + MemPool *memPool = new ThreadLocalMemPool(*mpCtrler, ""); +#endif memPools.insert(memPool); return memPool; } @@ -74,7 +79,7 @@ class Phase { // remove the specified memPool from memPools, then release the memPool void ReleaseMemPool(MemPool *memPool) { memPools.erase(memPool); - memPool->Release(); + delete memPool; } // release all mempool use in this phase except exclusion @@ -83,7 +88,7 @@ class Phase { if (memPool == exclusion) { continue; } - mpCtrler->DeleteMemPool(memPool); + delete memPool; memPool = nullptr; } memPools.clear(); @@ -94,7 +99,9 @@ class Phase { } private: +#ifdef MP_DEBUG uint32 memPoolCount = 0; +#endif std::set memPools; MemPoolCtrler *mpCtrler = &memPoolCtrler; }; diff --git a/src/mapleall/mempool/include/mempool.h b/src/mapleall/mempool/include/mempool.h index 1ae540d82476be1dd1a00a3a9629405d2190fae5..6d25f8efc80cf665bce78b40ca614b6300b0f4af 100644 --- a/src/mapleall/mempool/include/mempool.h +++ b/src/mapleall/mempool/include/mempool.h @@ -16,12 +16,14 @@ #define MEMPOOL_INCLUDE_MEMPOOL_H #include #include +#include #include #include #include #include #include "mir_config.h" #include "mpl_logging.h" +#include "thread_env.h" // Local debug control #ifdef MP_DEBUG @@ -34,74 +36,106 @@ namespace maple { #define TRUE 1 #endif +#define BITS_ALIGN(size) (((size) + 7) & (0xFFFFFFF8)) + +constexpr size_t kMemBlockSizeMin = 2 * 1024; + +struct MemBlock { + explicit MemBlock(size_t size) : memSize(size) { + startPtr = reinterpret_cast(malloc(size)); +#ifdef MP_DEBUG + LogInfo::MapleLogger() << "New MemBlock: " << this << ", startPtr: " << (void *)startPtr << ", memSize: " << memSize + << std::endl; +#endif + } + + ~MemBlock() { + if (startPtr != nullptr) { + free(startPtr); + } + } + + uint8_t *EndPtr() const { + return startPtr + memSize; + } + + uint8_t *startPtr = nullptr; + size_t memSize = 0; + MemBlock *nextMemBlock = nullptr; +}; + // Class declaration -class MemPool; // circular dependency exists, no other choice +class MemPool; +class StackMemPool; +class MemPoolCtrler; +extern MemPoolCtrler memPoolCtrler; + +static inline bool IsGlobalCtrler(const MemPoolCtrler &mpCtrler) { + return &mpCtrler == &maple::memPoolCtrler; +} + // Memory Pool controller class class MemPoolCtrler { friend MemPool; - public: // Methods + public: static bool freeMemInTime; MemPoolCtrler() = default; ~MemPoolCtrler(); - MemPool *NewMemPool(const std::string&); + MemPool *NewMemPool(const std::string&, bool isLocalPool); void DeleteMemPool(MemPool *memPool); - void FreeMem(); - bool IsEmpty() const { - return memPools.empty(); + bool HaveRace() const { + return ThreadEnv::IsMeParallel() && IsGlobalCtrler(*this); } - private: // Methods - struct MemBlock { - size_t available; // Available memory size - size_t origSize; // original size - void *ptr; // Current pointer to the first available position - }; + MemBlock *AllocMemBlock(const MemPool &pool, size_t size); + MemBlock *AllocFixMemBlock(const MemPool &pool); + MemBlock *AllocBigMemBlock(const MemPool &pool, size_t size); - class MemBlockCmp { - public: + private: + struct MemBlockCmp { bool operator()(const MemBlock *l, const MemBlock *r) const { - if (l->available != r->available) { - return l->available > r->available; - } - return (std::uintptr_t)(l->ptr) > (std::uintptr_t)(r->ptr); + return l->memSize > r->memSize; } }; - inline bool HaveRace() const; - std::mutex mtx; // this mutex is used to protect memPools, freeMemBlocks and largeFreeMemBlocks - // Free small/large size memory block list - std::list freeMemBlocks; - std::map> largeFreeMemBlocks; - std::set memPools; // set of mempools managed by it + void FreeMem(); + void FreeMemBlocks(const MemPool &pool, MemBlock *fixedMemHead, MemBlock *bigMemHead); + + std::mutex ctrlerMutex; // this mutex is used to protect memPools + std::unordered_set memPools; // set of mempools managed by it + MemBlock *fixedFreeMemBlocks = nullptr; + std::multiset bigFreeMemBlocks; +#ifdef MP_DEBUG + size_t totalFreeMem = 0; + size_t maxFreeMen = 0; + size_t allocFailed = 0; + size_t allocFailedSize = 0; + size_t allocTotal = 0; + size_t allocTotalSize = 0; +#endif }; class MemPool { friend MemPoolCtrler; - public: // Methods - MemPool(MemPoolCtrler &ctl, const std::string &name) : ctrler(ctl), name(name) { + public: + MemPool(MemPoolCtrler &ctl, const std::string &name) : ctrler(ctl) { #ifdef MP_DEBUG - frozen = false; LogInfo::MapleLogger() << "MEMPOOL: New " << name << '\n'; + this->name = name; #endif + (void)(name); } - ~MemPool(); - void *Malloc(size_t size); + virtual ~MemPool(); + + virtual void *Malloc(size_t size); void *Calloc(size_t size); void *Realloc(const void *ptr, size_t oldSize, size_t newSize); - void ReleaseContainingMem(); - - void Release() { - ctrler.DeleteMemPool(this); - } - - const std::string &GetName() const { - return name; - } + virtual void ReleaseContainingMem(); const MemPoolCtrler &GetCtrler() const { return ctrler; @@ -110,50 +144,104 @@ class MemPool { template T *Clone(const T &t) { void *p = Malloc(sizeof(T)); - CHECK_FATAL(p != nullptr, "ERROR: New error"); - p = new (p) T(t); // Call clone constructor - return static_cast(p); + ASSERT(p != nullptr, "ERROR: New error"); + p = new (p) T(t); + return static_cast(p); } - // New templates template T *New(Arguments &&... args) { void *p = Malloc(sizeof(T)); - CHECK_FATAL(p != nullptr, "ERROR: New error"); - p = new (p) T(std::forward(args)...); // Call constructor - return static_cast(p); + ASSERT(p != nullptr, "ERROR: New error"); + p = new (p) T(std::forward(args)...); + return static_cast(p); } - // New Array template template T *NewArray(size_t num) { void *p = Malloc(sizeof(T) * num); - CHECK_FATAL(p != nullptr, "ERROR: NewArray error"); + ASSERT(p != nullptr, "ERROR: NewArray error"); p = new (p) T[num]; - return static_cast(p); + return static_cast(p); } -#define BITS_ALIGN(size) (((size) + 7) & (0xFFFFFFF8)) -#define MEM_BLOCK_FIRST_PTR(x) \ - static_cast((reinterpret_cast(x)) + BITS_ALIGN(sizeof(MemPoolCtrler::MemBlock))) - - private: // constants - static constexpr size_t kMinBlockSize = 0x800; // Minimum BlockSize is 2K - static constexpr size_t kMemBlockOverhead = (BITS_ALIGN(sizeof(MemPoolCtrler::MemBlock))); - MemPoolCtrler::MemBlock *GetLargeMemBlock(size_t size); // Raw allocate large memory block - MemPoolCtrler::MemBlock *GetMemBlock(); - inline bool HaveRace() const; + protected: MemPoolCtrler &ctrler; // Hookup controller object - std::string name; // Name of the memory pool - // Save the memory block stack - std::stack memBlockStack; - std::stack largeMemBlockStack; + uint8_t *endPtr = nullptr; + uint8_t *curPtr = nullptr; + MemBlock *fixedMemHead = nullptr; + MemBlock *bigMemHead = nullptr; + #ifdef MP_DEBUG - bool IsValid(void); - bool frozen; + std::string name; + size_t alloc = 0; + size_t used = 0; + static size_t sumAlloc; + static size_t sumUsed; #endif + uint8_t *AllocNewMemBlock(size_t bytes); }; -extern MemPoolCtrler memPoolCtrler; +using ThreadLocalMemPool = MemPool; + +class ThreadShareMemPool : public MemPool { + public: + using MemPool::MemPool; + void *Malloc(size_t size) override { + ParallelGuard guard(poolMutex, ctrler.HaveRace()); + return MemPool::Malloc(size); + } + void ReleaseContainingMem() override { + ParallelGuard guard(poolMutex, ctrler.HaveRace()); + MemPool::ReleaseContainingMem(); + } + + private: + std::mutex poolMutex; // this mutex is used to protect memPools +}; + +class LocalMapleAllocator; +class StackMemPool : public MemPool { + public: + using MemPool::MemPool; + friend LocalMapleAllocator; + + private: + // all malloc requested from LocalMapleAllocator + void *Malloc(size_t size); + uint8_t *AllocTailMemBlock(size_t size); + + // these methods should be called from LocalMapleAllocator + template + T *Clone(const T &t) = delete; + + template + T *New(Arguments &&... args) = delete; + + template + T *NewArray(size_t num) = delete; + +#ifdef DEBUG + void PushAllocator(const LocalMapleAllocator *alloc) { + allocators.push(alloc); + } + const LocalMapleAllocator *TopAllocator() { + return allocators.top(); + } + void PopAllocator() { + allocators.pop(); + } + std::stack allocators; +#endif + + // reuse mempool fixedMemHead, bigMemHead, (curPtr, endPtr for fixed memory) + MemBlock *fixedMemStackTop = nullptr; + MemBlock *bigMemStackTop = nullptr; + uint8_t *bigCurPtr = nullptr; + uint8_t *bigEndPtr = nullptr; + MemBlock *AllocMemBlockBySize(size_t size); + void ResetStackTop(const LocalMapleAllocator *alloc, uint8_t *fixedCurPtrMark, MemBlock *fixedStackTopMark, + uint8_t *bigCurPtrMark, MemBlock *bigStackTopMark) noexcept; +}; } // namespace maple #endif // MEMPOOL_INCLUDE_MEMPOOL_H diff --git a/src/mapleall/mempool/include/mempool_allocator.h b/src/mapleall/mempool/include/mempool_allocator.h index dafea7bc6b09c7d884ff0db1a954cd1a84a0fe5a..dcd2bf3fcb5b314ad79466d09b64b44b11b44ea1 100644 --- a/src/mapleall/mempool/include/mempool_allocator.h +++ b/src/mapleall/mempool/include/mempool_allocator.h @@ -36,7 +36,7 @@ class MapleAllocator { // Get adapter for use in STL containers. See arena_containers.h . MapleAllocatorAdapter Adapter(); - void *Alloc(size_t bytes) { + virtual void *Alloc(size_t bytes) { return (memPool != nullptr) ? memPool->Malloc(bytes) : nullptr; } @@ -48,12 +48,61 @@ class MapleAllocator { memPool = m; } - private: + protected: MemPool *memPool; template friend class MapleAllocatorAdapter; }; // MapleAllocator +// must be destroyed, otherwise there will be memory leak +// only one allocater can be used at the same time +class LocalMapleAllocator : public MapleAllocator { + public: + explicit LocalMapleAllocator(StackMemPool &m) + : MapleAllocator(&m), + fixedStackTopMark(m.fixedMemStackTop), + bigStackTopMark(m.bigMemStackTop), + fixedCurPtrMark(m.curPtr), + bigCurPtrMark(m.bigCurPtr) { +#ifdef DEBUG + m.PushAllocator(this); +#endif + } + ~LocalMapleAllocator() override { + static_cast(memPool)->ResetStackTop(this, fixedCurPtrMark, fixedStackTopMark, bigCurPtrMark, + bigStackTopMark); + }; + + StackMemPool &GetStackMemPool() const { + return static_cast(*memPool); + } + + MemPool *GetMemPool() const = delete; + + template + T *New(Arguments &&... args) { + void *p = memPool->Malloc(sizeof(T)); + ASSERT(p != nullptr, "ERROR: New error"); + p = new (p) T(std::forward(args)...); + return static_cast(p); + } + + void *Alloc(size_t bytes) override { +#ifdef DEBUG + CHECK_FATAL(static_cast(memPool)->TopAllocator() == this, + "Alloc Error, Only top allocator can Alloc"); +#endif + return memPool->Malloc(bytes); + } + + private: + using MapleAllocator::MapleAllocator; + MemBlock *const fixedStackTopMark; + MemBlock *const bigStackTopMark; + uint8_t *const fixedCurPtrMark; + uint8_t *const bigCurPtrMark; +}; + template class MapleAllocatorAdapter; // circular dependency exists, no other choice @@ -131,6 +180,9 @@ using MapleMap = std::map> using MapleMultiMap = std::multimap>>; +template > +using MapleMultiSet = std::multiset>; + template , typename Equal = std::equal_to> using MapleUnorderedMap = std::unordered_map>>; diff --git a/src/mapleall/mempool/src/MPTest.cpp b/src/mapleall/mempool/src/MPTest.cpp index 01794bce94acd34f5f925e8eacec2ab18a0bb70d..b2d9b438be5107a3b95a87d97ac3f27a13aaf0ae 100644 --- a/src/mapleall/mempool/src/MPTest.cpp +++ b/src/mapleall/mempool/src/MPTest.cpp @@ -30,21 +30,36 @@ class MyClass { id = currId; name = currName; }; - ~MyClass() {}; + ~MyClass(){}; int id; std::string name; }; +void TestLocalAllocater() { + MemPoolCtrler mpc; + auto mp = std::unique_ptr(new StackMemPool(mpc, "")); + LocalMapleAllocator alloc1(*mp); + MapleVector v1({ 1, 2, 3, 4, 5 }, alloc1.Adapter()); + { + LocalMapleAllocator alloc2(*mp); + MapleVector v2({ 1, 2, 3, 4, 5 }, alloc2.Adapter()); + { + LocalMapleAllocator alloc3(*mp); + MapleVector v3({ 1, 2, 3, 4, 5 }, alloc3.Adapter()); + } + } +} + int main() { // 1. Create a memory pool controler instance; MemPoolCtrler mpc; // 2. Create two memory pools on mpc - MemPool *mp1 = mpc.NewMemPool("Test Memory Pool 1"); - MemPool *mp2 = mpc.NewMemPool("Test Memory Pool 2"); + MemPool *mp1 = mpc.NewMemPool("Test Memory Pool 1", true /* isLocalPool */); + MemPool *mp2 = mpc.NewMemPool("Test Memory Pool 2", true /* isLocalPool */); // 3. Usage of memory pool, Malloc/Call on primitive types // char string constexpr int lengthOfHelloWorld = 12; - char *charP = static_cast(mp1->Malloc(lengthOfHelloWorld * sizeof(char))); + char *charP = static_cast(mp1->Malloc(lengthOfHelloWorld * sizeof(char))); errno_t cpyRes = strcpy_s(charP, lengthOfHelloWorld, "Hello world"); if (cpyRes != 0) { LogInfo::MapleLogger() << "call strcpy_s failed" << std::endl; @@ -53,7 +68,7 @@ int main() { LogInfo::MapleLogger() << charP << std::endl; // int, float, double constexpr int arrayLen = 10; - int *intP = static_cast(mp1->Calloc(arrayLen * sizeof(int))); + int *intP = static_cast(mp1->Calloc(arrayLen * sizeof(int))); CHECK_FATAL(intP, "null ptr check "); for (int i = 0; i < arrayLen; ++i) { intP[i] = i * i; @@ -62,9 +77,9 @@ int main() { LogInfo::MapleLogger() << intP[i] << " ,"; } LogInfo::MapleLogger() << intP[arrayLen - 1] << std::endl; - float *floatP = static_cast(mp1->Malloc(arrayLen * sizeof(float))); + float *floatP = static_cast(mp1->Malloc(arrayLen * sizeof(float))); for (int i = 0; i < arrayLen; ++i) { - floatP[i] = 10.0 / (i + 1); // test float num is 10.0 + floatP[i] = 10.0 / (i + 1); // test float num is 10.0 } for (int i = 0; i < arrayLen - 1; ++i) { LogInfo::MapleLogger() << floatP[i] << " ,"; @@ -72,10 +87,10 @@ int main() { LogInfo::MapleLogger() << floatP[arrayLen - 1] << std::endl; // 4. Allocate memory on struct Structure *structP = mp1->New(); - structP->height = 1024; // test num is 1024. + structP->height = 1024; // test num is 1024. structP->id = 0; - LogInfo::MapleLogger() << "Structure: my_struct height=" << structP->height << " feet," << "id= x" << - structP->id << std::endl; + LogInfo::MapleLogger() << "Structure: my_struct height=" << structP->height << " feet," + << "id= x" << structP->id << std::endl; // 5. Allocate memory on class constructor MyClass *myClass = mp1->New(1, "class name"); LogInfo::MapleLogger() << "Class: my_class id=" << myClass->id << " , name=" << myClass->name << std::endl; @@ -109,7 +124,7 @@ int main() { // list MapleList myList(mpAllocator.Adapter()); for (int i = 0; i < arrayLen; ++i) { - myList.push_back(1000.0 / (i + 1)); // test float num is 1000.0 + myList.push_back(1000.0 / (i + 1)); // test float num is 1000.0 } MapleList::iterator listItr; for (listItr = myList.begin(); listItr != myList.end(); ++listItr) { @@ -143,5 +158,7 @@ int main() { // Delete memory pool mpc.DeleteMemPool(mp1); mpc.DeleteMemPool(mp2); + + TestLocalAllocater(); return 1; } diff --git a/src/mapleall/mempool/src/mempool.cpp b/src/mapleall/mempool/src/mempool.cpp index ae3b38e2e26a15d69b8a489f17d8376e88b1106f..3196280d9249cd6bab5076990065c4a6657405cd 100644 --- a/src/mapleall/mempool/src/mempool.cpp +++ b/src/mapleall/mempool/src/mempool.cpp @@ -26,22 +26,61 @@ namespace maple { MemPoolCtrler memPoolCtrler; bool MemPoolCtrler::freeMemInTime = false; -static inline bool IsGlobalCtrler(const MemPoolCtrler &mpCtrler) { - return &mpCtrler == &maple::memPoolCtrler; -} +#ifdef MP_DEBUG +size_t MemPool::sumAlloc = 0; +size_t MemPool::sumUsed = 0; +#endif -static inline bool IsMpManagedByGlobalCtrler(const MemPool &mp) { - return &mp.GetCtrler() == &maple::memPoolCtrler; -} +void MemPoolCtrler::FreeMemBlocks(const MemPool &pool, MemBlock *fixedMemHead, MemBlock *bigMemHead) { + (void)(pool); -inline bool MemPoolCtrler::HaveRace() const { - return ThreadEnv::IsMeParallel() && IsGlobalCtrler(*this); -} + MemBlock *fixedTail = nullptr; -inline bool MemPool::HaveRace() const { - return ThreadEnv::IsMeParallel() && IsMpManagedByGlobalCtrler(*this); + if (fixedMemHead != nullptr) { +#ifdef MP_DEBUG + MemBlock *cur = fixedMemHead; + while (cur != nullptr) { + totalFreeMem += cur->memSize; + maxFreeMen = std::max(cur->memSize, maxFreeMen); + LogInfo::MapleLogger() << "Giveback MemBlock: " << cur << ", startPtr: " << (void *)cur->startPtr + << ", memSize: " << cur->memSize << std::endl; + cur = cur->nextMemBlock; + } +#endif + fixedTail = fixedMemHead; + while (fixedTail->nextMemBlock != nullptr) { + fixedTail = fixedTail->nextMemBlock; + } + } + + ParallelGuard guard(ctrlerMutex, HaveRace()); + if (fixedTail != nullptr) { + fixedTail->nextMemBlock = fixedFreeMemBlocks; + ASSERT(fixedTail->nextMemBlock != fixedTail, "error"); + fixedFreeMemBlocks = fixedMemHead; + } + + if (bigMemHead != nullptr) { + auto *cur = bigMemHead; + while (cur != nullptr) { +#ifdef MP_DEBUG + totalFreeMem += cur->memSize; + maxFreeMen = std::max(cur->memSize, maxFreeMen); + LogInfo::MapleLogger() << "Giveback MemBlock: " << cur << ", startPtr: " << (void *)cur->startPtr + << ", memSize: " << cur->memSize << std::endl; +#endif + bigFreeMemBlocks.insert(cur); + cur = cur->nextMemBlock; + } + } + +#ifdef MP_DEBUG + LogInfo::MapleLogger() << "MEMPOOL: Free Success, " << pool.name << " Total Free Mem: " << totalFreeMem + << " Max Free Mem: " << maxFreeMen << '\n'; +#endif } -// Destructor, free all allocated memory pool and blocks + +// Destructor, free all allocated memories MemPoolCtrler::~MemPoolCtrler() { // Delete Memory Pool for (MemPool *memPool : memPools) { @@ -52,258 +91,337 @@ MemPoolCtrler::~MemPoolCtrler() { #endif delete memPool; } - // Delete all free_memory_block - for (MemBlock *block : freeMemBlocks) { - free(block); - } - for (auto it = largeFreeMemBlocks.begin(); it != largeFreeMemBlocks.end(); ++it) { - for (auto itr = (*it).second.begin(); itr != (*it).second.end(); ++itr) { - free(*itr); - } - } + +#ifdef MP_DEBUG + LogInfo::MapleLogger() << "MEMPOOL: Alloc Failed Stat: Alloc Failed: " << allocFailed + << " Alloc Total: " << allocTotal + << " Alloc Fail Rate: " << (1.0 * allocFailed / std::max(static_cast(1), allocTotal)) + << " Alloc Failed Size: " << allocFailedSize << " Alloc Total Size: " << allocTotalSize + << " Alloc Failed Size Rate " + << (1.0 * allocFailedSize / std::max(static_cast(1), allocTotalSize)) << '\n'; +#endif + FreeMem(); } // Allocate a new memory pool and register it in controller -MemPool *MemPoolCtrler::NewMemPool(const std::string &name) { - auto memPool = new (std::nothrow) MemPool(*this, name); - if (memPool == nullptr) { - CHECK_FATAL(false, "ERROR: Can't allocate new memory pool"); - return nullptr; +MemPool *MemPoolCtrler::NewMemPool(const std::string &name, bool isLocalPool) { + MemPool *memPool = nullptr; + + if (isLocalPool) { + memPool = new ThreadLocalMemPool(*this, name); + } else { + memPool = new ThreadShareMemPool(*this, name); } - ParallelGuard guard(mtx, HaveRace()); + + ParallelGuard guard(ctrlerMutex, HaveRace()); memPools.insert(memPool); return memPool; } -// Re-cycle all memory blocks allocated on a memory pool to free list +// Re-cycle all memories allocated on a memory pool to free list void MemPoolCtrler::DeleteMemPool(MemPool *memPool) { - CHECK_NULL_FATAL(memPool); + ASSERT_NOT_NULL(memPool); -#ifdef MP_DEBUG - if (!memPool->IsValid()) { - CHECK_FATAL(false, "MEMPOOL: Re-cycled wrong memory pool\n"); - return; - } -#endif - ParallelGuard guard(mtx, HaveRace()); - // Transfer memory blocks to ctrler->freeMemBlocks stack - while (!memPool->memBlockStack.empty()) { - MemBlock *mb = memPool->memBlockStack.top(); - mb->available = mb->origSize; - mb->ptr = MEM_BLOCK_FIRST_PTR(mb); - freeMemBlocks.push_back(mb); - memPool->memBlockStack.pop(); + { + ParallelGuard guard(ctrlerMutex, HaveRace()); + // Delete entry of this mempool in memPools and delete the mempool node + memPools.erase(memPool); } - // Transfer large memory blocks to ctrler->freeMemBlocks stack - while (!memPool->largeMemBlockStack.empty()) { - MemBlock *mb = memPool->largeMemBlockStack.top(); - mb->available = mb->origSize; - mb->ptr = MEM_BLOCK_FIRST_PTR(mb); - size_t key = (mb->available / 0x800) + 1; // Minimum BlockSize is 2K. - if (largeFreeMemBlocks.find(key) == largeFreeMemBlocks.end()) { - largeFreeMemBlocks[key] = std::set(); - } - largeFreeMemBlocks[key].insert(mb); - memPool->largeMemBlockStack.pop(); - } - // Delete entry of this mempool in memPools and delete the mempool node - memPools.erase(memPool); delete memPool; + if (freeMemInTime) { FreeMem(); } } void MemPoolCtrler::FreeMem() { - ParallelGuard guard(mtx, HaveRace()); - for (MemBlock *block : freeMemBlocks) { - free(block); + ParallelGuard guard(ctrlerMutex, HaveRace()); + + while (fixedFreeMemBlocks != nullptr) { + MemBlock *arena = fixedFreeMemBlocks; + fixedFreeMemBlocks = fixedFreeMemBlocks->nextMemBlock; + delete arena; } - for (auto it = largeFreeMemBlocks.begin(); it != largeFreeMemBlocks.end(); ++it) { - for (auto itr = (*it).second.begin(); itr != (*it).second.end(); ++itr) { - free(*itr); - } + + for (MemBlock *block : bigFreeMemBlocks) { + delete block; } - freeMemBlocks.clear(); - largeFreeMemBlocks.clear(); + bigFreeMemBlocks.clear(); } -MemPool::~MemPool() { - while (!memBlockStack.empty()) { - free(memBlockStack.top()); - memBlockStack.pop(); +MemBlock *MemPoolCtrler::AllocMemBlock(const MemPool &pool, size_t size) { + if (size <= kMemBlockSizeMin) { + return AllocFixMemBlock(pool); + } else { + return AllocBigMemBlock(pool, size); } - while (!largeMemBlockStack.empty()) { - free(largeMemBlockStack.top()); - largeMemBlockStack.pop(); +} + +MemBlock *MemPoolCtrler::AllocFixMemBlock(const MemPool &pool) { + (void)(pool); + MemBlock *ret = nullptr; + + { + ParallelGuard guard(ctrlerMutex, HaveRace()); + if (fixedFreeMemBlocks != nullptr) { + ret = fixedFreeMemBlocks; + fixedFreeMemBlocks = fixedFreeMemBlocks->nextMemBlock; +#ifdef MP_DEBUG + totalFreeMem -= ret->memSize; + if (ret->memSize == maxFreeMen) { + if (fixedFreeMemBlocks == nullptr) { + maxFreeMen = 0; + } + } + LogInfo::MapleLogger() << "MEMPOOL: Alloc Success, " << pool.name << " Alloc size: " << kMemBlockSizeMin + << " Total Free Mem: " << totalFreeMem << " Max Free Mem: " << maxFreeMen << '\n'; + LogInfo::MapleLogger() << "Reuse MemBlock: " << ret << ", startPtr: " << (void *)ret->startPtr + << ", memSize: " << ret->memSize << std::endl; + allocTotal += 1; +#endif + return ret; + } } + #ifdef MP_DEBUG - LogInfo::MapleLogger() << "MEMPOOL: Deleted " << name << "\n"; + if (maxFreeMen > kMemBlockSizeMin) { + allocFailed += 1; + allocFailedSize += kMemBlockSizeMin; + LogInfo::MapleLogger() << "MEMPOOL: Alloc Failed, " << pool.name << " Alloc size: " << kMemBlockSizeMin + << " Total Free Mem: " << totalFreeMem << " Max Free Mem: " << maxFreeMen << '\n'; + } else { + LogInfo::MapleLogger() << "MEMPOOL: Alloc Success, " << pool.name << " Alloc size: " << kMemBlockSizeMin + << " Total Free Mem: " << totalFreeMem << " Max Free Mem: " << maxFreeMen << '\n'; + } + allocTotal += 1; + allocTotalSize += kMemBlockSizeMin; #endif + + return new MemBlock(kMemBlockSizeMin); } -// Return a pointer that points to size of memory from memory block -void *MemPool::Malloc(size_t size) { - // we use the same mutex as ctrler to avoid MemPool::Malloc and MemPoolCtrler::DeleteMemPool are called meanwhile - ParallelGuard guard(ctrler.mtx, HaveRace()); +MemBlock *MemPoolCtrler::AllocBigMemBlock(const MemPool &pool, size_t size) { + ASSERT(size > kMemBlockSizeMin, "Big memory block must be bigger than fixed memory block"); + (void)(pool); + MemBlock *ret = nullptr; + + { + ParallelGuard guard(ctrlerMutex, HaveRace()); + if (!bigFreeMemBlocks.empty() && (*bigFreeMemBlocks.begin())->memSize >= size) { + ret = *bigFreeMemBlocks.begin(); + bigFreeMemBlocks.erase(bigFreeMemBlocks.begin()); #ifdef MP_DEBUG - // If controller is not set, or the memory pool is invalid - if (!IsValid()) { - return nullptr; - } - if (size > UINT_MAX) { - CHECK_FATAL(false, "ERROR: MemPool allocator cannot handle block size larger than 4GB\n"); - } + totalFreeMem -= ret->memSize; + if (!bigFreeMemBlocks.empty()) { + maxFreeMen = (*bigFreeMemBlocks.begin())->memSize; + } else if (fixedFreeMemBlocks != nullptr) { + maxFreeMen = kMemBlockSizeMin; + } else { + maxFreeMen = 0; + } + LogInfo::MapleLogger() << "MEMPOOL: Alloc Success, " << pool.name << " Alloc size: " << kMemBlockSizeMin + << " Total Free Mem: " << totalFreeMem << " Max Free Mem: " << maxFreeMen << '\n'; + LogInfo::MapleLogger() << "Reuse MemBlock: " << ret << ", startPtr: " << (void *)ret->startPtr + << ", memSize: " << ret->memSize << std::endl; + allocTotal += 1; #endif - void *result = nullptr; - MemPoolCtrler::MemBlock *b = nullptr; - // If size is smaller than 2K, fetch size of memory from the last memory block - if (size <= kMinBlockSize) { - // Get the top memory block from the top - b = (memBlockStack.empty() ? nullptr : memBlockStack.top()); - // the last operation was a push - if (b == nullptr || b->available < size) { - b = GetMemBlock(); + return ret; } - // Return the pointer that points to the starting point + 8; + } + +#ifdef MP_DEBUG + if (maxFreeMen > size) { + allocFailed += 1; + allocFailedSize += size; + LogInfo::MapleLogger() << "MEMPOOL: Alloc Failed, " << pool.name << " Alloc size: " << size + << " Total Free Mem: " << totalFreeMem << " Max Free Mem: " << maxFreeMen << '\n'; } else { - b = GetLargeMemBlock(size); + LogInfo::MapleLogger() << "MEMPOOL: Alloc Success, " << pool.name << " Alloc size: " << size + << " Total Free Mem: " << totalFreeMem << " Max Free Mem: " << maxFreeMen << '\n'; } - CHECK_FATAL(b != nullptr, "ERROR: Malloc error"); - result = static_cast(b->ptr); - b->ptr = static_cast(static_cast(b->ptr) + size); - // available size decrease - int tmp = b->available - size; - CHECK_FATAL(tmp >= 0, "ERROR: Malloc error"); - b->available = tmp; - return result; + allocTotal += 1; + allocTotalSize += size; +#endif + + return new MemBlock(size); } -// Malloc size of memory from memory pool, then set 0 -void *MemPool::Calloc(size_t size) { +MemPool::~MemPool() { #ifdef MP_DEBUG - if (!IsValid()) { - return nullptr; + MemPool::sumAlloc += alloc; + MemPool::sumUsed += used; + LogInfo::MapleLogger() << "MEMPOOL: Deleted " << name << " alloc: " << alloc << " used: " << used + << " Use Rate: " << (1.0 * used / std::max(static_cast(1), alloc)) + << " sum alloc: " << MemPool::sumAlloc << " sum used: " << MemPool::sumUsed << " sum rate: " + << (1.0 * MemPool::sumUsed / std::max(static_cast(1), MemPool::sumAlloc)) << "\n"; +#endif + ctrler.FreeMemBlocks(*this, fixedMemHead, bigMemHead); +} + +void *MemPool::Malloc(size_t size) { + size = BITS_ALIGN(size); + ASSERT(endPtr >= curPtr, "endPtr should >= curPtr"); + if (size > static_cast(endPtr - curPtr)) { + return AllocNewMemBlock(size); } + uint8_t *retPtr = curPtr; + curPtr += size; +#ifdef MP_DEBUG + used += size; #endif + return retPtr; +} + +void MemPool::ReleaseContainingMem() { + ctrler.FreeMemBlocks(*this, fixedMemHead, bigMemHead); + + fixedMemHead = nullptr; + bigMemHead = nullptr; + endPtr = nullptr; + curPtr = nullptr; +} + +// Malloc size of memory from memory pool, then set 0 +void *MemPool::Calloc(size_t size) { void *p = Malloc(BITS_ALIGN(size)); - if (p == nullptr) { - CHECK_FATAL(false, "ERROR: Calloc error\n"); - return nullptr; - } + ASSERT(p != nullptr, "ERROR: Calloc error"); errno_t eNum = memset_s(p, BITS_ALIGN(size), 0, BITS_ALIGN(size)); - if (eNum != EOK) { - CHECK_FATAL(false, "memset_s failed"); - } + CHECK_FATAL(eNum == EOK, "memset_s failed"); return p; } // Realloc new size of memory void *MemPool::Realloc(const void *ptr, size_t oldSize, size_t newSize) { -#ifdef MP_DEBUG - if (!IsValid()) { - return nullptr; - } -#endif void *result = Malloc(newSize); - if (result != nullptr) { - size_t copySize = ((newSize > oldSize) ? oldSize : newSize); - if (copySize != 0 && ptr != nullptr) { - errno_t eNum = memcpy_s(result, copySize, ptr, copySize); - if (eNum != EOK) { - FATAL(kLncFatal, "memcpy_s failed"); - } - } - } else { - CHECK_FATAL(false, "Error Realloc\n"); + ASSERT(result != nullptr, "ERROR: Realloc error"); + size_t copySize = ((newSize > oldSize) ? oldSize : newSize); + if (copySize != 0 && ptr != nullptr) { + errno_t eNum = memcpy_s(result, copySize, ptr, copySize); + CHECK_FATAL(eNum == EOK, "memcpy_s failed"); } return result; } -void MemPool::ReleaseContainingMem() { - ParallelGuard guard(ctrler.mtx, HaveRace()); - while (!memBlockStack.empty()) { - MemPoolCtrler::MemBlock *block1 = memBlockStack.top(); - block1->available = block1->origSize; - block1->ptr = MEM_BLOCK_FIRST_PTR(block1); - ctrler.freeMemBlocks.push_back(block1); - memBlockStack.pop(); +uint8_t *MemPool::AllocNewMemBlock(size_t size) { + MemBlock **head = nullptr; + MemBlock *newMemBlock = ctrler.AllocMemBlock(*this, size); + if (newMemBlock->memSize <= kMemBlockSizeMin) { + head = &fixedMemHead; + } else { + head = &bigMemHead; } - while (!largeMemBlockStack.empty()) { - MemPoolCtrler::MemBlock *block2 = largeMemBlockStack.top(); - block2->available = block2->origSize; - block2->ptr = MEM_BLOCK_FIRST_PTR(block2); - size_t key = (block2->available / 0x800) + 1; // Minimum BlockSize is 2K. - if (ctrler.largeFreeMemBlocks.find(key) == ctrler.largeFreeMemBlocks.end()) { - std::set tmp; - ctrler.largeFreeMemBlocks[key] = tmp; - } - ctrler.largeFreeMemBlocks[key].insert(block2); - largeMemBlockStack.pop(); +#ifdef MP_DEBUG + alloc += newMemBlock->memSize; +#endif + + newMemBlock->nextMemBlock = *head; + *head = newMemBlock; + CHECK_FATAL(newMemBlock->nextMemBlock != newMemBlock, "error"); + + curPtr = newMemBlock->startPtr + size; + endPtr = newMemBlock->startPtr + newMemBlock->memSize; + ASSERT(curPtr <= endPtr, "must be"); + + return newMemBlock->startPtr; +} + +void *StackMemPool::Malloc(size_t size) { + size = BITS_ALIGN(size); + uint8_t **curPtrPtr = nullptr; + uint8_t *curEndPtr = nullptr; + if (size <= kMemBlockSizeMin) { + curPtrPtr = &curPtr; + curEndPtr = endPtr; + } else { + curPtrPtr = &bigCurPtr; + curEndPtr = bigEndPtr; + } + uint8_t *retPtr = *curPtrPtr; + ASSERT(curEndPtr >= *curPtrPtr, "endPtr should >= curPtr"); + if (size > static_cast(curEndPtr - *curPtrPtr)) { + retPtr = AllocTailMemBlock(size); } +#ifdef MP_DEBUG + LogInfo::MapleLogger() << "Malloc MemBlock: " + << " bigMemStackTop, " << (void *)bigMemStackTop << " retPtr, " << (void *)retPtr + << ", curPtr: " << (void *)(retPtr + size) << " bigCurPtr, " << (void *)bigCurPtr + << " bigEndPtr, " << (void *)bigEndPtr << std::endl; +#endif + *curPtrPtr = retPtr + size; + return retPtr; } -// Allocate a new memory block -MemPoolCtrler::MemBlock *MemPool::GetMemBlock() { - MemPoolCtrler::MemBlock *block = nullptr; - // Try to fetch one from free_memory_list - if (!ctrler.freeMemBlocks.empty()) { - block = ctrler.freeMemBlocks.front(); - ctrler.freeMemBlocks.erase(ctrler.freeMemBlocks.begin()); +// scoped mem pool don't use big mem block for small size, different with normal mempool +MemBlock *StackMemPool::AllocMemBlockBySize(size_t size) { + if (size <= kMemBlockSizeMin) { + return ctrler.AllocFixMemBlock(*this); } else { - // Allocate a block of memory, 2K + MemBlock head size - size_t total = kMinBlockSize + kMemBlockOverhead; - block = static_cast(malloc(total)); - if (block == nullptr) { - CHECK_FATAL(false, "ERROR: Allocate memory block failed\n"); - return nullptr; - } - // Available memory size is BlockSize - block->available = kMinBlockSize; - block->origSize = kMinBlockSize; - // Set the pointer points to the first available byte - block->ptr = MEM_BLOCK_FIRST_PTR(block); + return ctrler.AllocBigMemBlock(*this, size); } - memBlockStack.push(block); - return block; } -// Allocate a large memory block when user allocates memory size > 2K -MemPoolCtrler::MemBlock *MemPool::GetLargeMemBlock(size_t size) { - MemPoolCtrler::MemBlock *block = nullptr; - size_t key = (size / kMinBlockSize) + 1; - if (ctrler.largeFreeMemBlocks.find(key) != ctrler.largeFreeMemBlocks.end() && - ctrler.largeFreeMemBlocks[key].size()) { - block = *(ctrler.largeFreeMemBlocks[key].begin()); - if (block->origSize >= size) { - ctrler.largeFreeMemBlocks[key].erase(ctrler.largeFreeMemBlocks[key].begin()); - } else { - block = nullptr; - } +void StackMemPool::ResetStackTop(const LocalMapleAllocator *alloc, uint8_t *fixedCurPtrMark, + MemBlock *fixedStackTopMark, uint8_t *bigCurPtrMark, + MemBlock *bigStackTopMark) noexcept { +#ifdef DEBUG + CHECK_FATAL(alloc == TopAllocator(), "ResetStackTop Eror, Only Top Allocator can ResetStackTop"); + PopAllocator(); +#else + (void)alloc; +#endif + if (fixedStackTopMark != nullptr) { + fixedMemStackTop = fixedStackTopMark; + curPtr = fixedCurPtrMark; + endPtr = fixedMemStackTop->EndPtr(); + } else if (fixedMemHead != nullptr) { + fixedMemStackTop = fixedMemHead; + curPtr = fixedMemStackTop->startPtr; + endPtr = fixedMemStackTop->EndPtr(); } - if (block == nullptr) { - // Allocate a large memory block - block = static_cast(malloc(size + kMemBlockOverhead)); - if (block == nullptr) { - CHECK_FATAL(false, "ERROR: Fail to allocate large memory block\n"); - return nullptr; - } - block->origSize = size; - block->available = size; - block->ptr = MEM_BLOCK_FIRST_PTR(block); + + if (bigStackTopMark != nullptr) { + bigMemStackTop = bigStackTopMark; + bigCurPtr = bigCurPtrMark; + bigEndPtr = bigMemStackTop->EndPtr(); + } else if (bigMemHead != nullptr) { + bigMemStackTop = bigMemHead; + bigCurPtr = bigMemStackTop->startPtr; + bigEndPtr = bigMemStackTop->EndPtr(); } - largeMemBlockStack.push(block); - return block; } -#ifdef MP_DEBUG -// Whether the memory pool is valid -bool MemPool::IsValid(void) { - if (frozen) { - CHECK_FATAL(false, "Operate on a frozen pool %s", name.c_str()); - return false; +uint8_t *StackMemPool::AllocTailMemBlock(size_t size) { + MemBlock **head = nullptr; + MemBlock **stackTop = nullptr; + uint8_t **endPtrPtr = nullptr; + + if (size <= kMemBlockSizeMin) { + head = &fixedMemHead; + stackTop = &fixedMemStackTop; + endPtrPtr = &endPtr; + } else { + head = &bigMemHead; + stackTop = &bigMemStackTop; + endPtrPtr = &bigEndPtr; } - return true; + + if (*stackTop == nullptr) { + MemBlock *newMemBlock = AllocMemBlockBySize(size); + *stackTop = newMemBlock; + *head = newMemBlock; + (*stackTop)->nextMemBlock = nullptr; + } else { + if ((*stackTop)->nextMemBlock != nullptr && (*stackTop)->nextMemBlock->memSize >= size) { + *stackTop = (*stackTop)->nextMemBlock; + } else { + MemBlock *newMemBlock = AllocMemBlockBySize(size); + auto *tmp = (*stackTop)->nextMemBlock; + (*stackTop)->nextMemBlock = newMemBlock; + *stackTop = newMemBlock; + newMemBlock->nextMemBlock = tmp; + } + } + *endPtrPtr = (*stackTop)->EndPtr(); + return (*stackTop)->startPtr; } -#endif } // namespace maple diff --git a/src/mapleall/mpl2mpl/src/annotation_analysis.cpp b/src/mapleall/mpl2mpl/src/annotation_analysis.cpp index 7f99406582bba489be7642f7c4036ba83168700d..238fe1800a1aada00ada5f32c3d12521e15e9deb 100644 --- a/src/mapleall/mpl2mpl/src/annotation_analysis.cpp +++ b/src/mapleall/mpl2mpl/src/annotation_analysis.cpp @@ -548,13 +548,12 @@ void AnnotationAnalysis::Run() { } AnalysisResult *DoAnnotationAnalysis::Run(MIRModule *module, ModuleResultMgr *moduleResultMgr) { - MemPool *memPool = memPoolCtrler.NewMemPool("AnnotationAnalysis mempool"); - MemPool *pragmaMemPool = memPoolCtrler.NewMemPool("New Pragma mempool"); + auto memPool = std::make_unique(memPoolCtrler, "AnnotationAnalysis mempool"); + MemPool *pragmaMemPool = memPoolCtrler.NewMemPool("New Pragma mempool", false /* isLocalPool */); auto *kh = static_cast(moduleResultMgr->GetAnalysisResult(MoPhase_CHA, module)); ASSERT_NOT_NULL(kh); - AnnotationAnalysis *aa = pragmaMemPool->New(module, memPool, pragmaMemPool, kh); + AnnotationAnalysis *aa = pragmaMemPool->New(module, memPool.get(), pragmaMemPool, kh); aa->Run(); - memPoolCtrler.DeleteMemPool(memPool); return aa; } } diff --git a/src/mapleall/mpl2mpl/src/constantfold.cpp b/src/mapleall/mpl2mpl/src/constantfold.cpp index c5901c90381602bba9eafbaba70ae925162cbcea..cddbad61c5eb42fd1e4de2f62563a690cb70d523 100644 --- a/src/mapleall/mpl2mpl/src/constantfold.cpp +++ b/src/mapleall/mpl2mpl/src/constantfold.cpp @@ -1483,33 +1483,40 @@ std::pair ConstantFold::FoldExtractbits(ExtractbitsNode *node) std::pair ConstantFold::FoldIread(IreadNode *node) { CHECK_NULL_FATAL(node); - Opcode op = node->GetOpCode(); - FieldID fieldID = node->GetFieldID(); std::pair p = DispatchFold(node->Opnd(0)); BaseNode *e = PairToExpr(node->Opnd(0)->GetPrimType(), p); node->SetOpnd(e, 0); BaseNode *result = node; - if (op == OP_iaddrof && e->GetOpCode() == OP_addrof) { - AddrofNode *addrofNode = static_cast(e); + if (e->GetOpCode() != OP_addrof) { + return std::make_pair(result, 0); + } + + AddrofNode *addrofNode = static_cast(e); + MIRSymbol *msy = mirModule->CurFunction()->GetLocalOrGlobalSymbol(addrofNode->GetStIdx()); + TyIdx typeId = msy->GetTyIdx(); + CHECK_FATAL(GlobalTables::GetTypeTable().GetTypeTable().empty() == false, "container check"); + MIRType *msyType = GlobalTables::GetTypeTable().GetTypeTable()[typeId]; + if (addrofNode->GetFieldID() != 0 && + (msyType->GetKind() == kTypeStruct || msyType->GetKind() == kTypeClass)) { + msyType = static_cast(msyType)->GetFieldType(addrofNode->GetFieldID()); + } + MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(node->GetTyIdx())); + // If the high level type of iaddrof/iread doesn't match + // the type of addrof's rhs, this optimization cannot be done. + if (ptrType->GetPointedType() != msyType) { + return std::make_pair(result, 0); + } + + Opcode op = node->GetOpCode(); + FieldID fieldID = node->GetFieldID(); + if (op == OP_iaddrof) { AddrofNode *newAddrof = addrofNode->CloneTree(mirModule->GetCurFuncCodeMPAllocator()); CHECK_NULL_FATAL(newAddrof); newAddrof->SetFieldID(newAddrof->GetFieldID() + fieldID); result = newAddrof; - } else if (op == OP_iread && e->GetOpCode() == OP_addrof) { - AddrofNode *addrofNode = static_cast(e); - MIRSymbol *msy = mirModule->CurFunction()->GetLocalOrGlobalSymbol(addrofNode->GetStIdx()); - TyIdx typeId = msy->GetTyIdx(); - CHECK_FATAL(GlobalTables::GetTypeTable().GetTypeTable().empty() == false, "container check"); - MIRType *msyType = GlobalTables::GetTypeTable().GetTypeTable()[typeId]; - if (addrofNode->GetFieldID() != 0 && - (msyType->GetKind() == kTypeStruct || msyType->GetKind() == kTypeClass)) { - msyType = static_cast(msyType)->GetFieldType(addrofNode->GetFieldID()); - } - MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(node->GetTyIdx())); - if (ptrType->GetPointedType() == msyType) { - result = mirModule->CurFuncCodeMemPool()->New( + } else if (op == OP_iread) { + result = mirModule->CurFuncCodeMemPool()->New( OP_dread, node->GetPrimType(), addrofNode->GetStIdx(), node->GetFieldID() + addrofNode->GetFieldID()); - } } return std::make_pair(result, 0); } diff --git a/src/mapleall/mpl2mpl/src/reflection_analysis.cpp b/src/mapleall/mpl2mpl/src/reflection_analysis.cpp index cf4c6c11c6049e26ef52f96b3c48b4895c596c86..af80e59d437b1c14f27e619e4bfa1aa4ef3b06ce 100644 --- a/src/mapleall/mpl2mpl/src/reflection_analysis.cpp +++ b/src/mapleall/mpl2mpl/src/reflection_analysis.cpp @@ -2247,11 +2247,11 @@ void ReflectionAnalysis::Run() { } AnalysisResult *DoReflectionAnalysis::Run(MIRModule *module, ModuleResultMgr *moduleResultMgr) { - MemPool *memPool = memPoolCtrler.NewMemPool("ReflectionAnalysis mempool"); + auto memPool = std::make_unique(memPoolCtrler, "ReflectionAnalysis mempool"); auto *kh = static_cast(moduleResultMgr->GetAnalysisResult(MoPhase_CHA, module)); ASSERT_NOT_NULL(kh); maple::MIRBuilder mirBuilder(module); - ReflectionAnalysis *rv = memPool->New(module, memPool, kh, mirBuilder); + ReflectionAnalysis *rv = memPool->New(module, memPool.get(), kh, mirBuilder); if (rv == nullptr) { CHECK_FATAL(false, "failed to allocate memory"); } @@ -2259,8 +2259,6 @@ AnalysisResult *DoReflectionAnalysis::Run(MIRModule *module, ModuleResultMgr *mo if (Options::genPGOReport) { rv->DumpPGOSummary(); } - // This is a transform phase, delete mempool. - memPoolCtrler.DeleteMemPool(memPool); return nullptr; } } // namespace maple diff --git a/src/mplfe/ast_input/include/ast_decl.h b/src/mplfe/ast_input/include/ast_decl.h index d6dc8073b90dc331be866af2df877e778b0e96b3..86fcfb3ced6dbb75e23d140123b3af1966d605ab 100644 --- a/src/mplfe/ast_input/include/ast_decl.h +++ b/src/mplfe/ast_input/include/ast_decl.h @@ -43,7 +43,12 @@ class ASTDecl { return isGlobalDecl; } + void GenerateInitStmt(std::list &stmts) { + return GenerateInitStmtImpl(stmts); + } + protected: + virtual void GenerateInitStmtImpl(std::list &stmts) {} bool isGlobalDecl; const std::string srcFileName; std::string name; @@ -138,7 +143,27 @@ class ASTVar : public ASTDecl { std::unique_ptr Translate2FEIRVar(); private: + void GenerateInitStmtImpl(std::list &stmts) override; ASTExpr *initExpr = nullptr; }; + +// only process local `EnumDecl` here +class ASTLocalEnumDecl : public ASTDecl { + public: + ASTLocalEnumDecl(const std::string &srcFile, const std::string &nameIn, const std::vector &typeDescIn, + const GenericAttrs &genAttrsIn) + : ASTDecl(srcFile, nameIn, typeDescIn) { + genAttrs = genAttrsIn; + } + ~ASTLocalEnumDecl() = default; + + void PushConstantVar(ASTVar *var) { + vars.emplace_back(var); + } + + private: + void GenerateInitStmtImpl(std::list &stmts) override; + std::list vars; +}; } // namespace maple #endif // MPLFE_AST_INPUT_INCLUDE_AST_DECL_H diff --git a/src/mplfe/ast_input/include/ast_decl_builder.h b/src/mplfe/ast_input/include/ast_decl_builder.h index 006828b6eb6adc93ddb1d7ded81949f68ceb6562..8f17e308fabe9e1909852fcb2b32f0b244f29a3a 100644 --- a/src/mplfe/ast_input/include/ast_decl_builder.h +++ b/src/mplfe/ast_input/include/ast_decl_builder.h @@ -30,6 +30,11 @@ class ASTDeclsBuilder { return allocator.GetMemPool()->New(srcFile, varName, desc, genAttrsIn); } + static ASTLocalEnumDecl *ASTLocalEnumDeclBuilder(MapleAllocator &allocator, const std::string &srcFile, + const std::string &varName, const std::vector &desc, const GenericAttrs &genAttrsIn) { + return allocator.GetMemPool()->New(srcFile, varName, desc, genAttrsIn); + } + static ASTFunc *ASTFuncBuilder(MapleAllocator &allocator, const std::string &srcFile, const std::string &nameIn, const std::vector &typeDescIn, const GenericAttrs &genAttrsIn, const std::vector &parmNamesIn) { diff --git a/src/mplfe/ast_input/include/ast_expr.h b/src/mplfe/ast_input/include/ast_expr.h index 6942383f0a6fb3ddeb8283652fcbc0a0e95cf21e..044dd12eccc014ff83d1304e6d573ce1d51016f8 100644 --- a/src/mplfe/ast_input/include/ast_expr.h +++ b/src/mplfe/ast_input/include/ast_expr.h @@ -310,10 +310,15 @@ class ASTOffsetOfExpr : public ASTExpr { void SetStructType(MIRType *stype); void SetFieldName(std::string); + void SetOffset(size_t val) { + offset = val; + } + private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; MIRType *structType; std::string fieldName; + size_t offset; }; class ASTInitListExpr : public ASTExpr { @@ -323,25 +328,32 @@ class ASTInitListExpr : public ASTExpr { void SetFillerExprs(ASTExpr*); void SetInitListType(MIRType *type); + MIRType *GetInitListType() { + return initListType; + } + + void SetInitListVarName(const std::string &argVarName) { + varName = argVarName; + }; + private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; std::vector fillers; MIRType *initListType; + std::string varName; }; class ASTBinaryConditionalOperator : public ASTExpr { public: ASTBinaryConditionalOperator() : ASTExpr(kASTOpBinaryConditionalOperator) {} ~ASTBinaryConditionalOperator() = default; - void SetRetType(MIRType *type); - void SetCondExpr(ASTExpr*); - void SetFalseExpr(ASTExpr*); + void SetCondExpr(ASTExpr *expr); + void SetFalseExpr(ASTExpr *expr); private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; - MIRType *retType; - ASTExpr *cExpr = nullptr; - ASTExpr *fExpr = nullptr; + ASTExpr *condExpr = nullptr; + ASTExpr *falseExpr = nullptr; }; class ASTBinaryOperatorExpr : public ASTExpr { @@ -367,6 +379,10 @@ class ASTBinaryOperatorExpr : public ASTExpr { opcode = op; } + Opcode GetOp() const { + return opcode; + } + protected: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; Opcode opcode; @@ -511,190 +527,28 @@ class ASTDesignatedInitUpdateExpr : public ASTExpr { updaterExpr = astExpr; } - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; - ASTExpr *baseExpr; - ASTExpr *updaterExpr; -}; - -class ASTBOCompoundAssign : public ASTBinaryOperatorExpr { - public: - ASTBOCompoundAssign() : ASTBinaryOperatorExpr(kASTOpCompoundAssign) {} - ~ASTBOCompoundAssign() override = default; - - protected: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBOAddExpr : public ASTBinaryOperatorExpr { - public: - ASTBOAddExpr() : ASTBinaryOperatorExpr(kASTOpAdd) {} - ~ASTBOAddExpr() override = default; - - protected: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBOMulExpr : public ASTBinaryOperatorExpr { - public: - ASTBOMulExpr() : ASTBinaryOperatorExpr(kASTOpMul) {} - ~ASTBOMulExpr() override = default; - - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBODivExpr : public ASTBinaryOperatorExpr { - public: - ASTBODivExpr() : ASTBinaryOperatorExpr(kASTOpDiv) {} - ~ASTBODivExpr() override = default; - - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBORemExpr : public ASTBinaryOperatorExpr { - public: - ASTBORemExpr() : ASTBinaryOperatorExpr(kASTOpRem) {} - ~ASTBORemExpr() override = default; - - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBOSubExpr : public ASTBinaryOperatorExpr { - public: - ASTBOSubExpr() : ASTBinaryOperatorExpr(kASTOpSub) {} - ~ASTBOSubExpr() override = default; - - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBOShlExpr : public ASTBinaryOperatorExpr { - public: - ASTBOShlExpr() : ASTBinaryOperatorExpr(kASTOpShl) {} - ~ASTBOShlExpr() override = default; - - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBOShrExpr : public ASTBinaryOperatorExpr { - public: - ASTBOShrExpr() : ASTBinaryOperatorExpr(kASTOpShr) {} - ~ASTBOShrExpr() override = default; - - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBOLTExpr : public ASTBinaryOperatorExpr { - public: - ASTBOLTExpr() : ASTBinaryOperatorExpr(kASTOpLT) {} - ~ASTBOLTExpr() override = default; - - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBOGTExpr : public ASTBinaryOperatorExpr { - public: - ASTBOGTExpr() : ASTBinaryOperatorExpr(kASTOpGT) {} - ~ASTBOGTExpr() override = default; - - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBOLEExpr : public ASTBinaryOperatorExpr { - public: - ASTBOLEExpr() : ASTBinaryOperatorExpr(kASTOpLE) {} - ~ASTBOLEExpr() override = default; - - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBOGEExpr : public ASTBinaryOperatorExpr { - public: - ASTBOGEExpr() : ASTBinaryOperatorExpr(kASTOpGE) {} - ~ASTBOGEExpr() override = default; - - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBOEQExpr : public ASTBinaryOperatorExpr { - public: - ASTBOEQExpr() : ASTBinaryOperatorExpr(kASTOpEQ) {} - ~ASTBOEQExpr() override = default; - - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBONEExpr : public ASTBinaryOperatorExpr { - public: - ASTBONEExpr() : ASTBinaryOperatorExpr(kASTOpNE) {} - ~ASTBONEExpr() override = default; - - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBOAndExpr : public ASTBinaryOperatorExpr { - public: - ASTBOAndExpr() : ASTBinaryOperatorExpr(kASTOpAnd) {} - ~ASTBOAndExpr() override = default; - - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBOXorExpr : public ASTBinaryOperatorExpr { - public: - ASTBOXorExpr() : ASTBinaryOperatorExpr(kASTOpXor) {} - ~ASTBOXorExpr() override = default; - - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBOOrExpr : public ASTBinaryOperatorExpr { - public: - ASTBOOrExpr() : ASTBinaryOperatorExpr(kASTOpOr) {} - ~ASTBOOrExpr() override = default; - - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBOLAndExpr : public ASTBinaryOperatorExpr { - public: - ASTBOLAndExpr() : ASTBinaryOperatorExpr(kASTOpLAnd) {} - ~ASTBOLAndExpr() override = default; - - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; + void SetInitListType(MIRType *type) { + initListType = type; + } -class ASTBOLOrExpr : public ASTBinaryOperatorExpr { - public: - ASTBOLOrExpr() : ASTBinaryOperatorExpr(kASTOpLOr) {} - ~ASTBOLOrExpr() override = default; + MIRType *GetInitListType() const { + return initListType; + } - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; + void SetInitListVarName (std::string name) { + initListVarName = name; + } -class ASTBOEqExpr : public ASTBinaryOperatorExpr { - public: - ASTBOEqExpr() : ASTBinaryOperatorExpr(kASTOpEQ) {} - ~ASTBOEqExpr() override = default; + std::string GetInitListVarName () const { + return initListVarName; + } private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; + ASTExpr *baseExpr; + ASTExpr *updaterExpr; + MIRType *initListType; + std::string initListVarName; }; class ASTAssignExpr : public ASTBinaryOperatorExpr { diff --git a/src/mplfe/ast_input/include/ast_parser.h b/src/mplfe/ast_input/include/ast_parser.h index 03086e91a6c89389b58167bab8014267a5b1bbb3..dfa63a448079672ed456d8fa294b3394790754b9 100644 --- a/src/mplfe/ast_input/include/ast_parser.h +++ b/src/mplfe/ast_input/include/ast_parser.h @@ -26,7 +26,8 @@ class ASTParser { public: ASTParser(MapleAllocator &allocatorIn, uint32 fileIdxIn, const std::string &fileNameIn) : fileIdx(fileIdxIn), fileName(fileNameIn), globalVarDecles(allocatorIn.Adapter()), - funcDecles(allocatorIn.Adapter()), recordDecles(allocatorIn.Adapter()) {} + funcDecles(allocatorIn.Adapter()), recordDecles(allocatorIn.Adapter()), + globalEnumDecles(allocatorIn.Adapter()) {} virtual ~ASTParser() = default; bool OpenFile(); bool Verify(); @@ -36,6 +37,8 @@ class ASTParser { bool RetrieveFuncs(MapleAllocator &allocator, MapleList &funcs); bool RetrieveGlobalVars(MapleAllocator &allocator, MapleList &vars); + bool ProcessGlobalEnums(MapleAllocator &allocator, MapleList &vars); + const std::string &GetSourceFileName() const; const uint32 GetFileIdx() const; void SetAstIn(ASTInput *in) { @@ -127,10 +130,12 @@ ASTDecl *ProcessDecl(MapleAllocator &allocator, const clang::Decl &decl); ASTDecl *PROCESS_DECL(Function); ASTDecl *PROCESS_DECL(Record); ASTDecl *PROCESS_DECL(Var); + ASTDecl *PROCESS_DECL(Enum); private: - void TraverseDecl(clang::Decl *decl, std::function const &functor); + void TraverseDecl(const clang::Decl *decl, std::function const &functor); ASTDecl *GetAstDeclOfDeclRefExpr(MapleAllocator &allocator, const clang::Expr &expr); + void SetSourceFileInfo(clang::Decl *decl); uint32 fileIdx; const std::string fileName; std::unique_ptr astFile; @@ -138,7 +143,10 @@ ASTDecl *ProcessDecl(MapleAllocator &allocator, const clang::Decl &decl); MapleList globalVarDecles; MapleList funcDecles; MapleList recordDecles; + MapleList globalEnumDecles; ASTInput *astIn = nullptr; + + uint32 srcFileNum = 2; // src files start from 2, 1 is mpl file }; } // namespace maple #endif // MPLFE_AST_INPUT_INCLUDE_AST_PARSER_H diff --git a/src/mplfe/ast_input/include/ast_stmt.h b/src/mplfe/ast_input/include/ast_stmt.h index dfb7a62a0bd8a21d0f3436d126ee0f2177a5a815..825c325f36cbc6580ec507ed981e029c421b8fc5 100644 --- a/src/mplfe/ast_input/include/ast_stmt.h +++ b/src/mplfe/ast_input/include/ast_stmt.h @@ -295,9 +295,9 @@ class ASTCaseStmt : public ASTStmt { private: std::list Emit2FEStmtImpl() const override; - ASTExpr* lhs = nullptr; - ASTExpr* rhs = nullptr; - ASTStmt* subStmt = nullptr; + ASTExpr *lhs = nullptr; + ASTExpr *rhs = nullptr; + ASTStmt *subStmt = nullptr; int64 lCaseTag; int64 rCaseTag; }; diff --git a/src/mplfe/ast_input/lib/ast_interface.h b/src/mplfe/ast_input/lib/ast_interface.h index 9ab9e0468b870ddcd5df7d6d36c5859eee9dd3cd..3ebbb9abec3f965472ab4f6d20f89207a687fb53 100644 --- a/src/mplfe/ast_input/lib/ast_interface.h +++ b/src/mplfe/ast_input/lib/ast_interface.h @@ -68,6 +68,7 @@ class LibAstFile { MIRType *CvtFunctionType(const clang::QualType srcType); MIRType *CvtRecordType(const clang::QualType srcType); MIRType *CvtFieldType(const clang::NamedDecl &decl); + MIRType *CvtComplexType(const clang::QualType srcType); const clang::ASTContext *GetContext() { return astContext; diff --git a/src/mplfe/ast_input/lib/ast_type.cpp b/src/mplfe/ast_input/lib/ast_type.cpp index a0d35d8d9787be910d2acfd6e2c49befc8eb10db..b26a041cc36391f3f02c4d6c93c469e130068c18 100644 --- a/src/mplfe/ast_input/lib/ast_type.cpp +++ b/src/mplfe/ast_input/lib/ast_type.cpp @@ -82,8 +82,8 @@ PrimType LibAstFile::CvtPrimType(const clang::BuiltinType::Kind kind) const { case clang::BuiltinType::LongDouble: case clang::BuiltinType::Float128: return PTY_f128; - case clang::BuiltinType::NullPtr: - return kPtyInvalid; + case clang::BuiltinType::NullPtr: // default 64-bit, need to update + return PTY_a64; case clang::BuiltinType::Void: default: return PTY_void; @@ -120,8 +120,9 @@ MIRType *LibAstFile::CvtOtherType(const clang::QualType srcType) { destType = CvtArrayType(srcType); } else if (srcType->isRecordType()) { destType = CvtRecordType(srcType); + // isComplexType() does not include complex integers (a GCC extension) } else if (srcType->isAnyComplexType()) { - CHECK_FATAL(false, "NYI"); + destType = CvtComplexType(srcType); } else if (srcType->isFunctionType()) { destType = CvtFunctionType(srcType); } else if (srcType->isEnumeralType()) { @@ -195,6 +196,13 @@ MIRType *LibAstFile::CvtArrayType(const clang::QualType srcType) { return retType; } +MIRType *LibAstFile::CvtComplexType(const clang::QualType srcType) { + clang::QualType srcElemType = llvm::cast(srcType)->getElementType(); + MIRType *destElemType = CvtPrimType(srcElemType); + CHECK_NULL_FATAL(destElemType); + return FEManager::GetTypeManager().GetOrCreateComplexStructType(*destElemType); +} + MIRType *LibAstFile::CvtFunctionType(const clang::QualType srcType) { const auto *funcType = llvm::cast(srcType); MIRType *retType = CvtType(funcType->getReturnType()); diff --git a/src/mplfe/ast_input/src/ast_decl.cpp b/src/mplfe/ast_input/src/ast_decl.cpp index a038f0f9cab8deaa06cae58646c9c1becfad26e7..cdaa357930a3ceb3c1f1e32067f524a07541ea9c 100644 --- a/src/mplfe/ast_input/src/ast_decl.cpp +++ b/src/mplfe/ast_input/src/ast_decl.cpp @@ -17,6 +17,7 @@ #include "global_tables.h" #include "ast_stmt.h" #include "feir_var_name.h" +#include "feir_builder.h" namespace maple { // ---------- ASTDecl --------- @@ -38,6 +39,24 @@ std::unique_ptr ASTVar::Translate2FEIRVar() { return std::make_unique(name, std::make_unique(*(typeDesc[0]))); } +void ASTVar::GenerateInitStmtImpl(std::list &stmts) { + if (GetInitExpr() != nullptr) { + UniqueFEIRVar feirVar = Translate2FEIRVar(); + UniqueFEIRExpr expr = GetInitExpr()->Emit2FEExpr(stmts); + if (expr != nullptr) { // InitListExpr array not emit here + UniqueFEIRStmt stmt = FEIRBuilder::CreateStmtDAssign(std::move(feirVar), std::move(expr)); + stmts.emplace_back(std::move(stmt)); + } + } +} + +// ---------- ASTLocalEnumDecl ---------- +void ASTLocalEnumDecl::GenerateInitStmtImpl(std::list &stmts) { + for (auto var : vars) { + var->GenerateInitStmt(stmts); + } +} + // ---------- ASTFunc --------- void ASTFunc::SetCompoundStmt(ASTStmt *astCompoundStmt) { compound = astCompoundStmt; diff --git a/src/mplfe/ast_input/src/ast_expr.cpp b/src/mplfe/ast_input/src/ast_expr.cpp index 6c62eb00e5f1080bd18bdd160fbb9fc8efe84e10..bb222912ad17973a306f22436c5bc392fd820500 100644 --- a/src/mplfe/ast_input/src/ast_expr.cpp +++ b/src/mplfe/ast_input/src/ast_expr.cpp @@ -14,6 +14,7 @@ */ #include "ast_expr.h" #include "ast_decl.h" +#include "ast_macros.h" #include "mpl_logging.h" #include "feir_stmt.h" #include "feir_builder.h" @@ -27,7 +28,11 @@ UniqueFEIRExpr ASTExpr::Emit2FEExpr(std::list &stmts) const { return Emit2FEExprImpl(stmts); } -// ---------- ASTRefExpr --------- +// ---------- ASTDeclRefExpr --------- +void ASTDeclRefExpr::SetASTDecl(ASTDecl *astDecl) { + var = astDecl; +} + UniqueFEIRExpr ASTDeclRefExpr::Emit2FEExprImpl(std::list &stmts) const { UniqueFEIRVar feirVar = FEIRBuilder::CreateVarNameForC(var->GetName(), *(var->GetTypeDesc().front()), var->IsGlobal(), false); @@ -113,7 +118,6 @@ UniqueFEIRExpr ASTUOPostIncExpr::Emit2FEExprImpl(std::list &stmt CHECK_FATAL(childExpr != nullptr, "childExpr is nullptr"); PrimType subPrimType = subType->GetPrimType(); - // postinc_1 = a, subVar attr need update UniqueFEIRVar selfVar = FEIRBuilder::CreateVarNameForC(refName, *subType, isGlobal, false); UniqueFEIRVar selfMoveVar = selfVar->Clone(); UniqueFEIRVar tempVar = FEIRBuilder::CreateVarNameForC(FEUtils::GetSequentialName("postinc_"), *subType); @@ -122,25 +126,15 @@ UniqueFEIRExpr ASTUOPostIncExpr::Emit2FEExprImpl(std::list &stmt UniqueFEIRStmt readSelfstmt = FEIRBuilder::CreateStmtDAssign(std::move(tempMoveVar), std::move(readSelfExpr)); stmts.emplace_back(std::move(readSelfstmt)); - // a = a + 1 UniqueFEIRExpr childFEIRExpr = childExpr->Emit2FEExpr(stmts); - UniqueFEIRExpr incDecExpr; - if (subPrimType == PTY_f32) { - incDecExpr = FEIRBuilder::CreateExprConstI32(1); - } else if(subPrimType == PTY_ptr) { - incDecExpr = std::make_unique(static_cast(childExpr)->GetPointeeLen(), - PTY_ptr); - } else { - incDecExpr = std::make_unique((subType->GetKind() == kTypeScalar) ? - 1 : static_cast(subType->GetSize()), subType->GetPrimType()); - } - CHECK_FATAL(incDecExpr != nullptr, "incDecExpr is nullptr"); + UniqueFEIRExpr incIecExpr = (subPrimType == PTY_ptr) ? + std::make_unique(pointeeLen, PTY_ptr) : + FEIRBuilder::CreateExprConstAnyScalar(subPrimType, 1); UniqueFEIRExpr selfAddExpr = FEIRBuilder::CreateExprMathBinary(OP_add, std::move(childFEIRExpr), - std::move(incDecExpr)); + std::move(incIecExpr)); UniqueFEIRStmt selfAddStmt = FEIRBuilder::CreateStmtDAssign(std::move(selfVar), std::move(selfAddExpr)); stmts.emplace_back(std::move(selfAddStmt)); - // return postinc_1 UniqueFEIRExpr readTempExpr = FEIRBuilder::CreateExprDRead(std::move(tempVar)); return readTempExpr; } @@ -150,7 +144,6 @@ UniqueFEIRExpr ASTUOPostDecExpr::Emit2FEExprImpl(std::list &stmt CHECK_FATAL(childExpr != nullptr, "childExpr is nullptr"); PrimType subPrimType = subType->GetPrimType(); - // postdec_1 = a, selfVar attr need update UniqueFEIRVar selfVar = FEIRBuilder::CreateVarNameForC(refName, *subType, isGlobal, false); UniqueFEIRVar selfMoveVar = selfVar->Clone(); UniqueFEIRVar tempVar = FEIRBuilder::CreateVarNameForC(FEUtils::GetSequentialName("postinc_"), *subType); @@ -160,25 +153,15 @@ UniqueFEIRExpr ASTUOPostDecExpr::Emit2FEExprImpl(std::list &stmt std::move(readSelfExpr)); stmts.emplace_back(std::move(readSelfstmt)); - // a = a - 1 UniqueFEIRExpr childFEIRExpr = childExpr->Emit2FEExpr(stmts); - UniqueFEIRExpr incDecExpr; - if (subPrimType == PTY_f32) { - incDecExpr = FEIRBuilder::CreateExprConstI32(1); - } else if(subPrimType == PTY_ptr) { - incDecExpr = std::make_unique(static_cast(childExpr)->GetPointeeLen(), - PTY_ptr); - } else { - incDecExpr = std::make_unique((subType->GetKind() == kTypeScalar) ? - 1 : static_cast(subType->GetSize()), subType->GetPrimType()); - } - CHECK_FATAL(incDecExpr != nullptr, "incDecExpr is nullptr"); + UniqueFEIRExpr incDecExpr = (subPrimType == PTY_ptr) ? + std::make_unique(pointeeLen, PTY_ptr) : + FEIRBuilder::CreateExprConstAnyScalar(subPrimType, 1); UniqueFEIRExpr selfAddExpr = FEIRBuilder::CreateExprMathBinary(OP_sub, std::move(childFEIRExpr), std::move(incDecExpr)); UniqueFEIRStmt selfAddStmt = FEIRBuilder::CreateStmtDAssign(std::move(selfVar), std::move(selfAddExpr)); stmts.emplace_back(std::move(selfAddStmt)); - // return postdec_1 UniqueFEIRExpr readTempExpr = FEIRBuilder::CreateExprDRead(std::move(tempVar)); return readTempExpr; } @@ -187,26 +170,17 @@ UniqueFEIRExpr ASTUOPreIncExpr::Emit2FEExprImpl(std::list &stmts ASTExpr *childExpr = expr; CHECK_FATAL(childExpr != nullptr, "childExpr is nullptr"); UniqueFEIRExpr childFEIRExpr = childExpr->Emit2FEExpr(stmts); - UniqueFEIRExpr incDecExpr; PrimType subPrimType = subType->GetPrimType(); - if (subPrimType == PTY_f32) { - incDecExpr = FEIRBuilder::CreateExprConstI32(1); - } else if(subPrimType == PTY_ptr) { - incDecExpr = std::make_unique(static_cast(childExpr)->GetPointeeLen(), - PTY_ptr); - } else { - incDecExpr = std::make_unique((subType->GetKind() == kTypeScalar) ? - 1 : static_cast(subType->GetSize()), subType->GetPrimType()); - } - // a = a + 1, selfVar attr need update + UniqueFEIRExpr incIecExpr = (subPrimType == PTY_ptr) ? + std::make_unique(pointeeLen, PTY_ptr) : + FEIRBuilder::CreateExprConstAnyScalar(subPrimType, 1); UniqueFEIRExpr astUOPreIncExpr = FEIRBuilder::CreateExprMathBinary(OP_add, std::move(childFEIRExpr), - std::move(incDecExpr)); + std::move(incIecExpr)); UniqueFEIRVar selfVar = FEIRBuilder::CreateVarNameForC(refName, *subType, isGlobal, false); UniqueFEIRVar selfMoveVar = selfVar->Clone(); UniqueFEIRStmt stmt = FEIRBuilder::CreateStmtDAssign(std::move(selfMoveVar), std::move(astUOPreIncExpr)); stmts.emplace_back(std::move(stmt)); - // return a UniqueFEIRExpr feirRefExpr = FEIRBuilder::CreateExprDRead(std::move(selfVar)); return feirRefExpr; } @@ -215,19 +189,10 @@ UniqueFEIRExpr ASTUOPreDecExpr::Emit2FEExprImpl(std::list &stmts ASTExpr *childExpr = expr; CHECK_FATAL(childExpr != nullptr, "childExpr is nullptr"); UniqueFEIRExpr childFEIRExpr = childExpr->Emit2FEExpr(stmts); - UniqueFEIRExpr incDecExpr; PrimType subPrimType = subType->GetPrimType(); - if (subPrimType == PTY_f32) { - incDecExpr = FEIRBuilder::CreateExprConstI32(1); - } else if(subPrimType == PTY_ptr) { - incDecExpr = std::make_unique(static_cast(childExpr)->GetPointeeLen(), - PTY_ptr); - } else { - incDecExpr = std::make_unique((subType->GetKind() == kTypeScalar) ? - 1 : static_cast(subType->GetSize()), - subType->GetPrimType()); - } - // a = a - 1, selfVar attr need update + UniqueFEIRExpr incDecExpr = (subPrimType == PTY_ptr) ? + std::make_unique(pointeeLen, PTY_ptr) : + FEIRBuilder::CreateExprConstAnyScalar(subPrimType, 1); UniqueFEIRExpr astUOPreIncExpr = FEIRBuilder::CreateExprMathBinary(OP_sub, std::move(childFEIRExpr), std::move(incDecExpr)); UniqueFEIRVar selfVar = FEIRBuilder::CreateVarNameForC(refName, *subType, isGlobal, false); @@ -235,7 +200,6 @@ UniqueFEIRExpr ASTUOPreDecExpr::Emit2FEExprImpl(std::list &stmts UniqueFEIRStmt stmt = FEIRBuilder::CreateStmtDAssign(std::move(selfMoveVar), std::move(astUOPreIncExpr)); stmts.emplace_back(std::move(stmt)); - // return a UniqueFEIRExpr feirRefExpr = FEIRBuilder::CreateExprDRead(std::move(selfVar)); return feirRefExpr; } @@ -246,7 +210,6 @@ UniqueFEIRExpr ASTUOAddrOfExpr::Emit2FEExprImpl(std::list &stmts UniqueFEIRExpr addrOfExpr; if (childExpr->GetASTOp() == kASTOpRef) { ASTDecl *var = static_cast(childExpr)->GetASTDecl(); - // var attr should update UniqueFEIRVar addrOfVar = FEIRBuilder::CreateVarNameForC(var->GetName(), *(var->GetTypeDesc().front()), var->IsGlobal(), false); addrOfExpr = FEIRBuilder::CreateExprAddrofVar(std::move(addrOfVar)); @@ -262,31 +225,61 @@ UniqueFEIRExpr ASTUODerefExpr::Emit2FEExprImpl(std::list &stmts) ASTExpr *childExpr = expr; CHECK_FATAL(childExpr != nullptr, "childExpr is nullptr"); UniqueFEIRExpr childFEIRExpr = childExpr->Emit2FEExpr(stmts); - UniqueFEIRType retType = FEIRBuilder::CreateType(uoType->GetPrimType(), uoType->GetNameStrIdx(), 0); - UniqueFEIRType ptrBaseType = FEIRBuilder::CreateType(subType->GetPrimType(), subType->GetNameStrIdx(), 0); - UniqueFEIRType ptrType = FEIRTypeHelper::CreatePointerType(std::move(ptrBaseType)); + UniqueFEIRType retType = std::make_unique(*uoType); + UniqueFEIRType ptrType = std::make_unique(*subType); UniqueFEIRExpr derefExpr = FEIRBuilder::CreateExprIRead(std::move(retType), std::move(ptrType), 0, std::move(childFEIRExpr)); return derefExpr; } UniqueFEIRExpr ASTUORealExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NIY"); - return nullptr; + ASTExpr *childExpr = expr; + ASTOp astOP = childExpr->GetASTOp(); + UniqueFEIRExpr subFEIRExpr; + if (astOP == kASTStringLiteral || astOP == kASTIntegerLiteral || astOP == kASTFloatingLiteral || + astOP == kASTCharacterLiteral || astOP == kASTImaginaryLiteral) { + subFEIRExpr = childExpr->Emit2FEExpr(stmts); + } else { + subFEIRExpr = childExpr->Emit2FEExpr(stmts); + FEIRNodeKind subNodeKind = subFEIRExpr->GetKind(); + if (subNodeKind == kExprIRead) { + static_cast(subFEIRExpr.get())->SetFieldID(kComplexRealID); + } else if (subNodeKind == kExprDRead) { + static_cast(subFEIRExpr.get())->SetFieldID(kComplexRealID); + } else { + CHECK_FATAL(false, "NIY"); + } + } + return subFEIRExpr; } UniqueFEIRExpr ASTUOImagExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NIY"); - return nullptr; + ASTExpr *childExpr = expr; + ASTOp astOP = childExpr->GetASTOp(); + UniqueFEIRExpr subFEIRExpr; + if (astOP == kASTStringLiteral || astOP == kASTIntegerLiteral || astOP == kASTFloatingLiteral || + astOP == kASTCharacterLiteral || astOP == kASTImaginaryLiteral) { + subFEIRExpr = childExpr->Emit2FEExpr(stmts); + } else { + subFEIRExpr = childExpr->Emit2FEExpr(stmts); + FEIRNodeKind subNodeKind = subFEIRExpr->GetKind(); + if (subNodeKind == kExprIRead) { + static_cast(subFEIRExpr.get())->SetFieldID(kComplexImagID); + } else if (subNodeKind == kExprDRead) { + static_cast(subFEIRExpr.get())->SetFieldID(kComplexImagID); + } else { + CHECK_FATAL(false, "NIY"); + } + } + return subFEIRExpr; } UniqueFEIRExpr ASTUOExtensionExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NIY"); - return nullptr; + return expr->Emit2FEExpr(stmts); } UniqueFEIRExpr ASTUOCoawaitExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NIY"); + CHECK_FATAL(false, "C++ feature"); return nullptr; } @@ -310,28 +303,70 @@ void ASTOpaqueValueExpr::SetASTExpr(ASTExpr *astExpr) { // ---------- ASTBinaryConditionalOperator ---------- UniqueFEIRExpr ASTBinaryConditionalOperator::Emit2FEExprImpl(std::list &stmts) const { - UniqueFEIRExpr cFEIRExpr = cExpr->Emit2FEExpr(stmts); - UniqueFEIRExpr cFEIRExpr0 = cFEIRExpr->Clone(); - UniqueFEIRExpr cFEIRExpr1 = cFEIRExpr->Clone(); - UniqueFEIRExpr fFEIRExpr = fExpr->Emit2FEExpr(stmts); - return FEIRBuilder::CreateExprTernary(OP_select, std::move(cFEIRExpr0), - std::move(cFEIRExpr1), std::move(fFEIRExpr)); + UniqueFEIRExpr condFEIRExpr = condExpr->Emit2FEExpr(stmts); + UniqueFEIRExpr trueFEIRExpr; + CHECK_NULL_FATAL(mirType); + // if a conditional expr is noncomparative, e.g., b = a ?: c + // the conditional expr will be use for trueExpr before it will be converted to comparative expr + if (!(condFEIRExpr->GetKind() == kExprBinary && static_cast(condFEIRExpr.get())->IsComparative())) { + trueFEIRExpr = condFEIRExpr->Clone(); + UniqueFEIRExpr zeroConstExpr = (condFEIRExpr->GetPrimType() == PTY_ptr) ? + FEIRBuilder::CreateExprConstPtrNull() : + FEIRBuilder::CreateExprConstAnyScalar(condFEIRExpr->GetPrimType(), 0); + condFEIRExpr = FEIRBuilder::CreateExprMathBinary(OP_ne, std::move(condFEIRExpr), std::move(zeroConstExpr)); + } else { + // if a conditional expr already is comparative (only return u1 val 0 or 1), e.g., b = (a < 0) ?: c + // the conditional expr will be assigned var used for comparative expr and true expr meanwhile + MIRType *condType = condFEIRExpr->GetType()->GenerateMIRTypeAuto(); + ASSERT_NOT_NULL(condType); + CHECK_FATAL(condType->GetPrimType() == PTY_u1, + "invalid type of comparative conditional expr, %u", condType->GetPrimType()); + UniqueFEIRVar condVar = FEIRBuilder::CreateVarNameForC(FEUtils::GetSequentialName("condVal_"), *condType); + UniqueFEIRVar condVarCloned = condVar->Clone(); + UniqueFEIRVar condVarCloned2 = condVar->Clone(); + UniqueFEIRStmt condStmt = FEIRBuilder::CreateStmtDAssign(std::move(condVar), std::move(condFEIRExpr)); + stmts.emplace_back(std::move(condStmt)); + condFEIRExpr = FEIRBuilder::CreateExprDRead(std::move(condVarCloned)); + if (condType->GetPrimType() != mirType->GetPrimType()) { + trueFEIRExpr = FEIRBuilder::CreateExprCvtPrim(std::move(condVarCloned2), mirType->GetPrimType()); + } else { + trueFEIRExpr = FEIRBuilder::CreateExprDRead(std::move(condVarCloned2)); + } + } + std::list falseStmts; + UniqueFEIRExpr falseFEIRExpr = falseExpr->Emit2FEExpr(falseStmts); + // There are no extra nested statements in false expressions, (e.g., a < 1 ?: 2), use ternary FEIRExpr + if (falseStmts.empty()) { + UniqueFEIRType type = std::make_unique(*mirType); + return FEIRBuilder::CreateExprTernary(OP_select, std::move(type), std::move(condFEIRExpr), + std::move(trueFEIRExpr), std::move(falseFEIRExpr)); + } + // Otherwise, (e.g., a < 1 ?: a++) create a temporary var to hold the return trueExpr or falseExpr value + CHECK_FATAL(falseFEIRExpr->GetPrimType() == mirType->GetPrimType(), "The type of falseFEIRExpr are inconsistent"); + UniqueFEIRVar tempVar = FEIRBuilder::CreateVarNameForC(FEUtils::GetSequentialName("levVar_"), *mirType); + UniqueFEIRVar tempVarCloned1 = tempVar->Clone(); + UniqueFEIRVar tempVarCloned2 = tempVar->Clone(); + UniqueFEIRStmt retTrueStmt = FEIRBuilder::CreateStmtDAssign(std::move(tempVar), std::move(trueFEIRExpr)); + std::list trueStmts; + trueStmts.emplace_back(std::move(retTrueStmt)); + UniqueFEIRStmt retFalseStmt = FEIRBuilder::CreateStmtDAssign(std::move(tempVarCloned1), std::move(falseFEIRExpr)); + falseStmts.emplace_back(std::move(retFalseStmt)); + UniqueFEIRStmt stmtIf = FEIRBuilder::CreateStmtIf(std::move(condFEIRExpr), trueStmts, falseStmts); + stmts.emplace_back(std::move(stmtIf)); + return FEIRBuilder::CreateExprDRead(std::move(tempVarCloned2)); } -void ASTBinaryConditionalOperator::SetRetType(MIRType *returnType) { - retType = returnType; -} -void ASTBinaryConditionalOperator::SetCondExpr(ASTExpr *condExpr) { - cExpr = condExpr; +void ASTBinaryConditionalOperator::SetCondExpr(ASTExpr *expr) { + condExpr = expr; } -void ASTBinaryConditionalOperator::SetFalseExpr(ASTExpr *falseExpr) { - fExpr = falseExpr; + +void ASTBinaryConditionalOperator::SetFalseExpr(ASTExpr *expr) { + falseExpr = expr; } // ---------- ASTNoInitExpr ---------- UniqueFEIRExpr ASTNoInitExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NIY"); - return nullptr; + return FEIRBuilder::CreateExprConstAnyScalar(noInitType->GetPrimType(), 0); } void ASTNoInitExpr::SetNoInitType(MIRType *type) { @@ -340,8 +375,17 @@ void ASTNoInitExpr::SetNoInitType(MIRType *type) { // ---------- ASTCompoundLiteralExpr ---------- UniqueFEIRExpr ASTCompoundLiteralExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NIY"); - return nullptr; + UniqueFEIRExpr feirExpr; + if (child->GetASTOp() == kASTOpInitListExpr) { // other potential expr should concern + std::string tmpName = FEUtils::GetSequentialName("clvar_"); + static_cast(child)->SetInitListVarName(tmpName); + child->Emit2FEExpr(stmts); + UniqueFEIRVar tmpVar = FEIRBuilder::CreateVarNameForC(tmpName, *compoundLiteralType); + feirExpr = FEIRBuilder::CreateExprDRead(std::move(tmpVar)); + } else { + feirExpr = child->Emit2FEExpr(stmts); + } + return feirExpr; } void ASTCompoundLiteralExpr::SetCompoundLiteralType(MIRType *clType) { @@ -362,13 +406,57 @@ void ASTOffsetOfExpr::SetFieldName(std::string fName){ } UniqueFEIRExpr ASTOffsetOfExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NIY"); - return nullptr; + return FEIRBuilder::CreateExprConstU64(static_cast(offset)); } // ---------- ASTInitListExpr ---------- UniqueFEIRExpr ASTInitListExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NIY"); + if (!initListType->IsStructType()) { + UniqueFEIRType typeNative = FEIRTypeHelper::CreateTypeNative(*initListType); + UniqueFEIRVar feirVar = FEIRBuilder::CreateVarNameForC(varName, *initListType); + UniqueFEIRExpr arrayExpr = FEIRBuilder::CreateExprDRead(std::move(feirVar)); + for (int i = 0; i < fillers.size(); ++i) { + UniqueFEIRExpr exprIndex = FEIRBuilder::CreateExprConstI32(i); + UniqueFEIRExpr exprElem = fillers[i]->Emit2FEExpr(stmts); + UniqueFEIRType typeNativeTmp = typeNative->Clone(); + UniqueFEIRExpr arrayExprTmp = arrayExpr->Clone(); + auto stmt = FEIRBuilder::CreateStmtArrayStoreOneStmtForC(std::move(exprElem), std::move(arrayExprTmp), + std::move(exprIndex), std::move(typeNativeTmp)); + stmts.emplace_back(std::move(stmt)); + } + } else { + UniqueFEIRVar feirVar = FEIRBuilder::CreateVarNameForC(varName, *initListType); + MIRStructType *structType = static_cast(initListType); + for (uint32 i = 0; i < fillers.size(); i++) { + uint32 fieldID = 0; + if (fillers[i]->GetASTOp() == kASTOpInitListExpr) { + MIRType *mirType = static_cast(fillers[i])->GetInitListType(); + std::string tmpName = FEUtils::GetSequentialName("subInitListVar_"); + UniqueFEIRVar tmpVar = FEIRBuilder::CreateVarNameForC(tmpName, *mirType); + static_cast(fillers[i])->SetInitListVarName(tmpName); + (void)(fillers[i])->Emit2FEExpr(stmts); + UniqueFEIRExpr dreadAgg = FEIRBuilder::CreateExprDRead(std::move(tmpVar)); + FEManager::GetMIRBuilder().TraverseToNamedField(*structType, structType->GetElemStrIdx(i), fieldID); + UniqueFEIRStmt fieldStmt = std::make_unique(feirVar->Clone(), std::move(dreadAgg), fieldID); + stmts.emplace_back(std::move(fieldStmt)); + } else if (fillers[i]->GetASTOp() == kASTASTDesignatedInitUpdateExpr) { + MIRType *mirType = static_cast(fillers[i])->GetInitListType(); + std::string tmpName = FEUtils::GetSequentialName("subVarToBeUpdate_"); + UniqueFEIRVar tmpVar = FEIRBuilder::CreateVarNameForC(tmpName, *mirType); + static_cast(fillers[i])->SetInitListVarName(tmpName); + (void)(fillers[i])->Emit2FEExpr(stmts); + UniqueFEIRExpr dreadAgg = FEIRBuilder::CreateExprDRead(std::move(tmpVar)); + FEManager::GetMIRBuilder().TraverseToNamedField(*structType, structType->GetElemStrIdx(i), fieldID); + UniqueFEIRStmt fieldStmt = std::make_unique(feirVar->Clone(), std::move(dreadAgg), fieldID); + stmts.emplace_back(std::move(fieldStmt)); + } else { + FEManager::GetMIRBuilder().TraverseToNamedField(*structType, structType->GetElemStrIdx(i), fieldID); + UniqueFEIRExpr fieldFEExpr = fillers[i]->Emit2FEExpr(stmts); + UniqueFEIRStmt fieldStmt = std::make_unique(feirVar->Clone(), fieldFEExpr->Clone(), fieldID); + stmts.emplace_back(std::move(fieldStmt)); + } + } + } return nullptr; } @@ -406,12 +494,8 @@ UniqueFEIRExpr ASTExprUnaryExprOrTypeTraitExpr::Emit2FEExprImpl(std::list &stmts) const { UniqueFEIRExpr baseFEExpr = baseExpr->Emit2FEExpr(stmts); UniqueFEIRType baseFEType = std::make_unique(*baseType); - if (baseType->IsMIRPtrType()) { - MIRPtrType *mirPtrType = static_cast(baseType); - baseFEType = std::make_unique(*mirPtrType->GetPointedType()); - } if (isArrow) { - auto iread = std::make_unique(std::move(baseFEType), std::move(baseFEType), 0, + auto iread = std::make_unique(baseFEType->Clone(), std::move(baseFEType), 0, std::move(baseFEExpr)); iread->SetFieldName(memberName); return iread; @@ -432,7 +516,12 @@ UniqueFEIRExpr ASTMemberExpr::Emit2FEExprImpl(std::list &stmts) } UniqueFEIRExpr ASTDesignatedInitUpdateExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NIY"); + UniqueFEIRVar feirVar = FEIRBuilder::CreateVarNameForC(initListVarName, *initListType); + UniqueFEIRExpr baseFEIRExpr = baseExpr->Emit2FEExpr(stmts); + UniqueFEIRStmt baseFEIRStmt = std::make_unique(std::move(feirVar), std::move(baseFEIRExpr), 0); + stmts.emplace_back(std::move(baseFEIRStmt)); + static_cast(updaterExpr)->SetInitListVarName(initListVarName); + updaterExpr->Emit2FEExpr(stmts); return nullptr; } @@ -458,9 +547,8 @@ UniqueFEIRExpr ASTAssignExpr::ProcessAssign(std::list &stmts, Un } else if (leftFEExpr->GetKind() == FEIRNodeKind::kExprIRead) { auto ireadFEExpr = static_cast(leftFEExpr.get()); FieldID fieldID = ireadFEExpr->GetFieldID(); - UniqueFEIRExpr opnd = ireadFEExpr->GetOpnd()->Clone(); - UniqueFEIRType type = ireadFEExpr->GetType()->Clone(); - auto preStmt = std::make_unique(std::move(type), std::move(opnd), std::move(rightFEExpr), fieldID); + auto preStmt = std::make_unique(ireadFEExpr->GetClonedType(), ireadFEExpr->GetClonedOpnd(), + std::move(rightFEExpr), fieldID); preStmt->SetFieldName(ireadFEExpr->GetFieldName()); stmts.emplace_back(std::move(preStmt)); return leftFEExpr; @@ -488,8 +576,12 @@ UniqueFEIRExpr ASTAssignExpr::Emit2FEExprImpl(std::list &stmts) } UniqueFEIRExpr ASTBOComma::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; + auto leftFEExpr = leftExpr->Emit2FEExpr(stmts); + std::list exprs; + exprs.emplace_back(std::move(leftFEExpr)); + auto leftStmt = std::make_unique(OP_eval, std::move(exprs)); + stmts.emplace_back(std::move(leftStmt)); + return rightExpr->Emit2FEExpr(stmts); } UniqueFEIRExpr ASTBOPtrMemExpr::Emit2FEExprImpl(std::list &stmts) const { @@ -532,13 +624,22 @@ UniqueFEIRExpr ASTCharacterLiteral::Emit2FEExprImpl(std::list &s // ---------- ASTConditionalOperator ---------- UniqueFEIRExpr ASTConditionalOperator::Emit2FEExprImpl(std::list &stmts) const { UniqueFEIRExpr condFEIRExpr = condExpr->Emit2FEExpr(stmts); + // a noncomparative conditional expr need to be converted a comparative conditional expr + if (!(condFEIRExpr->GetKind() == kExprBinary && static_cast(condFEIRExpr.get())->IsComparative())) { + UniqueFEIRExpr zeroConstExpr = (condFEIRExpr->GetPrimType() == PTY_ptr) ? + FEIRBuilder::CreateExprConstPtrNull() : + FEIRBuilder::CreateExprConstAnyScalar(condFEIRExpr->GetPrimType(), 0); + condFEIRExpr = FEIRBuilder::CreateExprMathBinary(OP_ne, std::move(condFEIRExpr), std::move(zeroConstExpr)); + } std::list trueStmts; UniqueFEIRExpr trueFEIRExpr = trueExpr->Emit2FEExpr(trueStmts); std::list falseStmts; UniqueFEIRExpr falseFEIRExpr = falseExpr->Emit2FEExpr(falseStmts); // There are no extra nested statements in the expressions, (e.g., a < 1 ? 1 : 2), use ternary FEIRExpr if (trueStmts.empty() && falseStmts.empty()) { - return FEIRBuilder::CreateExprTernary(OP_select, std::move(condFEIRExpr), + CHECK_NULL_FATAL(mirType); + UniqueFEIRType type = std::make_unique(*mirType); + return FEIRBuilder::CreateExprTernary(OP_select, std::move(type), std::move(condFEIRExpr), std::move(trueFEIRExpr), std::move(falseFEIRExpr)); } // Otherwise, (e.g., a < 1 ? 1 : a++) create a temporary var to hold the return trueExpr or falseExpr value @@ -571,7 +672,7 @@ UniqueFEIRExpr ASTImaginaryLiteral::Emit2FEExprImpl(std::list &s UniqueFEIRVar clonedComplexVar = complexVar->Clone(); UniqueFEIRVar clonedComplexVar2 = complexVar->Clone(); // real number - UniqueFEIRExpr zeroConstExpr = FEIRBuilder::CreateExprZeroConst(elemType->GetPrimType()); + UniqueFEIRExpr zeroConstExpr = FEIRBuilder::CreateExprConstAnyScalar(elemType->GetPrimType(), 0); UniqueFEIRStmt realStmt = std::make_unique(std::move(complexVar), std::move(zeroConstExpr), 1); stmts.emplace_back(std::move(realStmt)); // imaginary number @@ -656,4 +757,4 @@ UniqueFEIRExpr ASTAtomicExpr::Emit2FEExprImpl(std::list &stmts) static_cast(atomicExpr.get())->SetVal2Type(val2Type); return atomicExpr; } -} \ No newline at end of file +} diff --git a/src/mplfe/ast_input/src/ast_input.cpp b/src/mplfe/ast_input/src/ast_input.cpp index 77673bcf1f2470aa772c3016528246f56c49bc4e..f2303dbb2d2e7352d950c9b5ba0c3ee34f6701cd 100644 --- a/src/mplfe/ast_input/src/ast_input.cpp +++ b/src/mplfe/ast_input/src/ast_input.cpp @@ -26,6 +26,7 @@ bool ASTInput::ReadASTFile(MapleAllocator &allocatorIn, uint32 index, const std: TRY_DO(astParser->OpenFile()); TRY_DO(astParser->Verify()); TRY_DO(astParser->PreProcessAST()); + TRY_DO(astParser->ProcessGlobalEnums(allocatorIn, astVars)); TRY_DO(astParser->RetrieveStructs(allocatorIn, astStructs)); TRY_DO(astParser->RetrieveFuncs(allocatorIn, astFuncs)); TRY_DO(astParser->RetrieveGlobalVars(allocatorIn, astVars)); diff --git a/src/mplfe/ast_input/src/ast_parser.cpp b/src/mplfe/ast_input/src/ast_parser.cpp index d5b498eed7174155d63abec059b965577bea382b..b2e2b46e50f977404b3968afa9888f735497679a 100644 --- a/src/mplfe/ast_input/src/ast_parser.cpp +++ b/src/mplfe/ast_input/src/ast_parser.cpp @@ -50,6 +50,9 @@ ASTBinaryOperatorExpr *ASTParser::AllocBinaryOperatorExpr(MapleAllocator &alloca return ASTDeclsBuilder::ASTExprBuilder(allocator); } } + if (bo.getOpcode() == clang::BO_Comma) { + return ASTDeclsBuilder::ASTExprBuilder(allocator); + } // [C++ 5.5] Pointer-to-member operators. if (bo.isPtrMemOp()) { return ASTDeclsBuilder::ASTExprBuilder(allocator); @@ -594,6 +597,8 @@ ASTExpr *ASTParser::ProcessExprUnaryOperator(MapleAllocator &allocator, const cl clang::UnaryOperator::Opcode clangOpCode = uo.getOpcode(); MIRType *subType = astFile->CvtType(subExpr->getType()); astUOExpr->SetSubType(subType); + MIRType *uoType = astFile->CvtType(uo.getType()); + astUOExpr->SetUOType(uoType); if (clangOpCode == clang::UO_PostInc || clangOpCode == clang::UO_PostDec || clangOpCode == clang::UO_PreInc || clangOpCode == clang::UO_PreDec) { const auto *declRefExpr = llvm::dyn_cast(subExpr); @@ -619,8 +624,6 @@ ASTExpr *ASTParser::ProcessExprUnaryOperator(MapleAllocator &allocator, const cl } } - MIRType *uoType = astFile->CvtType(uo.getType()); - astUOExpr->SetUOType(uoType); ASTExpr *astExpr = ProcessExpr(allocator, subExpr); if (astExpr == nullptr) { return nullptr; @@ -675,7 +678,7 @@ ASTExpr *ASTParser::ProcessExprBinaryConditionalOperator(MapleAllocator &allocat return nullptr; } astBinaryConditionalOperator->SetFalseExpr(falseExpr); - astBinaryConditionalOperator->SetRetType(astFile->CvtType(expr.getFalseExpr()->getType())); + astBinaryConditionalOperator->SetType(astFile->CvtType(expr.getType())); return astBinaryConditionalOperator; } @@ -710,7 +713,7 @@ ASTExpr *ASTParser::ProcessExprInitListExpr(MapleAllocator &allocator, const cla uint32 n = expr.getNumInits(); clang::Expr * const *le = expr.getInits(); for (uint32 i = 0; i < n; ++i) { - const clang::Expr *eExpr = expr.hasArrayFiller() ? expr.getArrayFiller() : le[i]; + const clang::Expr *eExpr = le[i]; ASTExpr *astExpr = ProcessExpr(allocator, eExpr); if (astExpr == nullptr) { return nullptr; @@ -724,11 +727,29 @@ ASTExpr *ASTParser::ProcessExprOffsetOfExpr(MapleAllocator &allocator, const cla ASTOffsetOfExpr *astOffsetOfExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astOffsetOfExpr != nullptr, "astOffsetOfExpr is nullptr"); clang::FieldDecl *field = expr.getComponent(0).getField(); - // structType should get from global struct map, temporarily don't have - MIRType *structType = astFile->CvtType(field->getParent()->getTypeForDecl()->getCanonicalTypeInternal()); + const clang::QualType qualType = field->getParent()->getTypeForDecl()->getCanonicalTypeInternal(); + MIRType *structType = astFile->CvtType(qualType); astOffsetOfExpr->SetStructType(structType); std::string filedName = astFile->GetMangledName(*field); astOffsetOfExpr->SetFieldName(filedName); + const auto *recordType = llvm::cast(qualType); + clang::RecordDecl *recordDecl = recordType->getDecl(); + const clang::ASTRecordLayout &recordLayout = astFile->GetContext()->getASTRecordLayout(recordDecl); + + clang::RecordDecl::field_iterator it; + uint64_t filedIdx = 0; + for (it = recordDecl->field_begin(); it != recordDecl->field_end(); ++it) { + std::string name = (*it)->getNameAsString(); + if (name == filedName) { + filedIdx = (*it)->getFieldIndex(); + break; + } + } + CHECK_FATAL(it != recordDecl->field_end(), "cann't find field %s in the struct", filedName.c_str()); + uint64 offsetInBits = recordLayout.getFieldOffset(filedIdx); + size_t offset = offsetInBits >> kBitToByteShift; + astOffsetOfExpr->SetOffset(offset); + return astOffsetOfExpr; } @@ -822,7 +843,10 @@ ASTExpr *ASTParser::ProcessExprDesignatedInitUpdateExpr(MapleAllocator &allocato return nullptr; } astDesignatedInitUpdateExpr->SetBaseExpr(baseExpr); - ASTExpr *updaterExpr = ProcessExpr(allocator, expr.getUpdater()); + clang::InitListExpr *initListExpr = expr.getUpdater(); + MIRType *initListType = astFile->CvtType(expr.getType()); + astDesignatedInitUpdateExpr->SetInitListType(initListType); + ASTExpr *updaterExpr = ProcessExpr(allocator, initListExpr); if (updaterExpr == nullptr) { return nullptr; } @@ -853,6 +877,7 @@ ASTExpr *ASTParser::ProcessExprConditionalOperator(MapleAllocator &allocator, co return nullptr; } astConditionalOperator->SetFalseExpr(astFalseExpr); + astConditionalOperator->SetType(astFile->CvtType(expr.getType())); return astConditionalOperator; } @@ -1046,6 +1071,7 @@ ASTExpr *ASTParser::ProcessExprImplicitCastExpr(MapleAllocator &allocator, const ASTImplicitCastExpr *astImplicitCastExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astImplicitCastExpr != nullptr, "astImplicitCastExpr is nullptr"); switch (expr.getCastKind()) { + case clang::CK_IntegralRealToComplex: case clang::CK_NoOp: case clang::CK_ArrayToPointerDecay: case clang::CK_FunctionToPointerDecay: @@ -1079,6 +1105,9 @@ ASTExpr *ASTParser::ProcessExprDeclRefExpr(MapleAllocator &allocator, const clan if (expr.getDecl()->getKind() == clang::Decl::Var) { const auto *varDecl = llvm::cast(expr.getDecl()->getCanonicalDecl()); astDecl->SetGlobal(!varDecl->isLocalVarDeclOrParm()); + } else { + // For comes from `EnumConstant` + astDecl->SetGlobal(expr.getDecl()->getParentFunctionOrMethod() == nullptr); } astRefExpr->SetASTDecl(astDecl); astRefExpr->SetType(refType); @@ -1105,7 +1134,6 @@ ASTExpr *ASTParser::ProcessExprBinaryOperator(MapleAllocator &allocator, const c return nullptr; } astBinOpExpr->SetRetType(retType); - clang::Expr *lExpr = bo.getLHS(); if (lExpr != nullptr) { ASTExpr *astLExpr = ProcessExpr(allocator, lExpr); @@ -1301,6 +1329,7 @@ bool ASTParser::PreProcessAST() { case clang::Decl::Typedef: break; case clang::Decl::Enum: + globalEnumDecles.emplace_back(child); break; default: { WARN(kLncWarn, "Unsupported decl kind: %u", child->getKind()); @@ -1319,6 +1348,7 @@ ASTDecl *ASTParser::ProcessDecl(MapleAllocator &allocator, const clang::Decl &de DECL_CASE(Field); DECL_CASE(Record); DECL_CASE(Var); + DECL_CASE(Enum); default: CHECK_FATAL(false, "NIY"); return nullptr; @@ -1432,6 +1462,12 @@ ASTDecl *ASTParser::ProcessDeclFieldDecl(MapleAllocator &allocator, const clang: if (fieldType == nullptr) { return nullptr; } + if (decl.isBitField()) { + unsigned bitSize = decl.getBitWidthValue(*(astFile->GetContext())); + MIRBitFieldType mirBFType(static_cast(bitSize), fieldType->GetPrimType()); + auto bfTypeIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&mirBFType); + fieldType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(bfTypeIdx); + } GenericAttrs attrs; astFile->CollectAttrs(decl, attrs, kPublic); return ASTDeclsBuilder::ASTFieldBuilder(allocator, fileName, fieldName, std::vector{fieldType}, attrs); @@ -1451,11 +1487,40 @@ ASTDecl *ASTParser::ProcessDeclVarDecl(MapleAllocator &allocator, const clang::V astFile->CollectAttrs(varDecl, attrs, kPublic); ASTVar *astVar = ASTDeclsBuilder::ASTVarBuilder(allocator, fileName, varName, std::vector{varType}, attrs); if (varDecl.hasInit()) { - astVar->SetInitExpr(ProcessExpr(allocator, varDecl.getInit())); + auto initExpr = varDecl.getInit(); + auto astInitExpr = ProcessExpr(allocator, initExpr); + if (initExpr->getStmtClass() == clang::Stmt::InitListExprClass) { + static_cast(astInitExpr)->SetInitListVarName(varName); + } + astVar->SetInitExpr(astInitExpr); } return astVar; } +ASTDecl *ASTParser::ProcessDeclEnumDecl(MapleAllocator &allocator, const clang::EnumDecl &enumDecl) { + GenericAttrs attrs; + astFile->CollectAttrs(*clang::dyn_cast(&enumDecl), attrs, kPublic); + const std::string &enumName = clang::dyn_cast(&enumDecl)->getNameAsString(); + ASTLocalEnumDecl *localEnumDecl = ASTDeclsBuilder::ASTLocalEnumDeclBuilder(allocator, fileName, enumName, + std::vector{}, attrs); + TraverseDecl(&enumDecl, [&](clang::Decl *child) { + CHECK_FATAL(child->getKind() == clang::Decl::EnumConstant, "Unsupported decl kind: %u", child->getKind()); + GenericAttrs attrs0; + astFile->CollectAttrs(*clang::dyn_cast(child), attrs0, kPublic); + const std::string &varName = clang::dyn_cast(child)->getNameAsString(); + MIRType *mirType = astFile->CvtType(clang::dyn_cast(child)->getType()); + ASTVar *astVar = + ASTDeclsBuilder::ASTVarBuilder(allocator, fileName, varName, std::vector{mirType}, attrs0); + auto constExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + constExpr->SetVal( + static_cast(clang::dyn_cast(child)->getInitVal().getExtValue())); + constExpr->SetType(mirType->GetPrimType()); + astVar->SetInitExpr(constExpr); + localEnumDecl->PushConstantVar(astVar); + }); + return localEnumDecl; +} + bool ASTParser::RetrieveStructs(MapleAllocator &allocator, MapleList &structs) { for (auto &decl : recordDecles) { clang::RecordDecl *recDecl = llvm::cast(decl->getCanonicalDecl()); @@ -1499,6 +1564,28 @@ bool ASTParser::RetrieveGlobalVars(MapleAllocator &allocator, MapleList return true; } +bool ASTParser::ProcessGlobalEnums(MapleAllocator &allocator, MapleList &vars) { + for (auto gEnumDecl : globalEnumDecles) { + TraverseDecl(gEnumDecl, [&](clang::Decl *child) { + CHECK_FATAL(child->getKind() == clang::Decl::EnumConstant, "Unsupported decl kind: %u", child->getKind()); + GenericAttrs attrs; + astFile->CollectAttrs(*clang::dyn_cast(child), attrs, kPublic); + const std::string &varName = clang::dyn_cast(child)->getNameAsString(); + MIRType *mirType = astFile->CvtType(clang::dyn_cast(child)->getType()); + ASTVar *astVar = + ASTDeclsBuilder::ASTVarBuilder(allocator, fileName, varName, std::vector{mirType}, attrs); + auto constExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + constExpr->SetVal( + static_cast(clang::dyn_cast(child)->getInitVal().getExtValue())); + constExpr->SetType(mirType->GetPrimType()); + astVar->SetInitExpr(constExpr); + astVar->SetGlobal(true); + vars.emplace_back(astVar); + }); + } + return true; +} + const std::string &ASTParser::GetSourceFileName() const { return fileName; } @@ -1507,24 +1594,27 @@ const uint32 ASTParser::GetFileIdx() const { return fileIdx; } -void ASTParser::TraverseDecl(clang::Decl *decl, std::function const &functor) { - uint32 srcFileNum = 2; // src files start from 2, 1 is mpl file +void ASTParser::TraverseDecl(const clang::Decl *decl, std::function const &functor) { if (decl == nullptr) { return; } - // set srcfileinfo - for (auto *declRange : clang::dyn_cast(decl)->decls()) { - clang::FullSourceLoc fullLocation = astFile->GetAstContext()->getFullLoc(declRange->getBeginLoc()); - if (fullLocation.isValid() && fullLocation.isFileID()) { - const clang::FileEntry *fileEntry = fullLocation.getFileEntry(); - ASSERT_NOT_NULL(fileEntry); - GStrIdx idx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fileEntry->getName().data()); + for (auto *child : clang::dyn_cast(decl)->decls()) { + SetSourceFileInfo(child); + functor(child); + } +} + +void ASTParser::SetSourceFileInfo(clang::Decl *decl) { + clang::FullSourceLoc fullLocation = astFile->GetAstContext()->getFullLoc(decl->getBeginLoc()); + if (fullLocation.isValid() && fullLocation.isFileID()) { + const clang::FileEntry *fileEntry = fullLocation.getFileEntry(); + ASSERT_NOT_NULL(fileEntry); + size_t oldSize = GlobalTables::GetStrTable().StringTableSize(); + GStrIdx idx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fileEntry->getName().data()); + // Not duplicate + if (oldSize != GlobalTables::GetStrTable().StringTableSize()) { FEManager::GetModule().PushbackFileInfo(MIRInfoPair(idx, srcFileNum++)); - break; } } - for (auto *child : clang::dyn_cast(decl)->decls()) { - functor(child); - } } } // namespace maple diff --git a/src/mplfe/ast_input/src/ast_stmt.cpp b/src/mplfe/ast_input/src/ast_stmt.cpp index 042aaa72084e38dfa758044e3c0834a96d25214e..c3707df9e7bcec6c00aabf3d72888631c98e5335 100644 --- a/src/mplfe/ast_input/src/ast_stmt.cpp +++ b/src/mplfe/ast_input/src/ast_stmt.cpp @@ -53,14 +53,13 @@ std::list ASTReturnStmt::Emit2FEStmtImpl() const { return stmts; } -void ASTDeclRefExpr::SetASTDecl(ASTDecl *astDecl) { - var = astDecl; -} - std::list ASTIfStmt::Emit2FEStmtImpl() const { std::list stmts; std::list thenStmts = thenStmt->Emit2FEStmt(); - std::list elseStmts = elseStmt->Emit2FEStmt(); + std::list elseStmts; + if (elseStmt != nullptr) { + elseStmts = elseStmt->Emit2FEStmt(); + } UniqueFEIRExpr condFEExpr = condExpr->Emit2FEExpr(stmts); UniqueFEIRStmt ifStmt; ifStmt = FEIRBuilder::CreateStmtIf(std::move(condFEExpr), thenStmts, elseStmts); @@ -70,6 +69,11 @@ std::list ASTIfStmt::Emit2FEStmtImpl() const { std::list ASTForStmt::Emit2FEStmtImpl() const { std::list stmts; + std::string loopBodyEndLabelName = FEUtils::GetSequentialName("dowhile_body_end_"); + std::string loopEndLabelName = FEUtils::GetSequentialName("dowhile_end_"); + AstLoopUtil::Instance().PushLoop(std::make_pair(loopBodyEndLabelName, loopEndLabelName)); + auto labelBodyEndStmt = std::make_unique(loopBodyEndLabelName); + auto labelLoopEndStmt = std::make_unique(loopEndLabelName); if (initStmt != nullptr) { std::list feStmts = initStmt->Emit2FEStmt(); stmts.splice(stmts.cend(), feStmts); @@ -81,6 +85,7 @@ std::list ASTForStmt::Emit2FEStmtImpl() const { condFEExpr = std::make_unique(static_cast(1), PTY_i32); } std::list bodyFEStmts = bodyStmt->Emit2FEStmt(); + bodyFEStmts.emplace_back(std::move(labelBodyEndStmt)); if (incExpr != nullptr) { std::list exprs; std::list incStmts; @@ -92,38 +97,67 @@ std::list ASTForStmt::Emit2FEStmtImpl() const { } UniqueFEIRStmt whileStmt = std::make_unique(OP_while, std::move(condFEExpr), std::move(bodyFEStmts)); stmts.emplace_back(std::move(whileStmt)); + stmts.emplace_back(std::move(labelLoopEndStmt)); + AstLoopUtil::Instance().PopCurrentLoop(); return stmts; } std::list ASTWhileStmt::Emit2FEStmtImpl() const { std::list stmts; - UniqueFEIRExpr condFEExpr = condExpr->Emit2FEExpr(stmts); + std::string loopBodyEndLabelName = FEUtils::GetSequentialName("dowhile_body_end_"); + std::string loopEndLabelName = FEUtils::GetSequentialName("dowhile_end_"); + AstLoopUtil::Instance().PushLoop(std::make_pair(loopBodyEndLabelName, loopEndLabelName)); + auto labelBodyEndStmt = std::make_unique(loopBodyEndLabelName); + auto labelLoopEndStmt = std::make_unique(loopEndLabelName); std::list bodyFEStmts = bodyStmt->Emit2FEStmt(); - UniqueFEIRStmt whileStmt = std::make_unique(OP_while, std::move(condFEExpr), std::move(bodyFEStmts)); + std::list condStmts; + std::list condPreStmts; + UniqueFEIRExpr condFEExpr = condExpr->Emit2FEExpr(condStmts); + (void)condExpr->Emit2FEExpr(condPreStmts); + bodyFEStmts.emplace_back(std::move(labelBodyEndStmt)); + bodyFEStmts.splice(bodyFEStmts.end(), condPreStmts); + auto whileStmt = std::make_unique(OP_while, std::move(condFEExpr), std::move(bodyFEStmts)); + stmts.splice(stmts.end(), condStmts); stmts.emplace_back(std::move(whileStmt)); + stmts.emplace_back(std::move(labelLoopEndStmt)); + AstLoopUtil::Instance().PopCurrentLoop(); return stmts; } std::list ASTDoStmt::Emit2FEStmtImpl() const { std::list stmts; - UniqueFEIRExpr condFEExpr = condExpr->Emit2FEExpr(stmts); + std::string loopBodyEndLabelName = FEUtils::GetSequentialName("dowhile_body_end_"); + std::string loopEndLabelName = FEUtils::GetSequentialName("dowhile_end_"); + AstLoopUtil::Instance().PushLoop(std::make_pair(loopBodyEndLabelName, loopEndLabelName)); + auto labelBodyEndStmt = std::make_unique(loopBodyEndLabelName); + auto labelLoopEndStmt = std::make_unique(loopEndLabelName); std::list bodyFEStmts = bodyStmt->Emit2FEStmt(); + bodyFEStmts.emplace_back(std::move(labelBodyEndStmt)); + std::list condStmts; + UniqueFEIRExpr condFEExpr = condExpr->Emit2FEExpr(condStmts); + bodyFEStmts.splice(bodyFEStmts.end(), condStmts); UniqueFEIRStmt whileStmt = std::make_unique(OP_dowhile, std::move(condFEExpr), std::move(bodyFEStmts)); stmts.emplace_back(std::move(whileStmt)); + stmts.emplace_back(std::move(labelLoopEndStmt)); + AstLoopUtil::Instance().PopCurrentLoop(); return stmts; } std::list ASTBreakStmt::Emit2FEStmtImpl() const { std::list stmts; - UniqueFEIRStmt stmt = std::make_unique(); + auto stmt = std::make_unique(); + if (!AstLoopUtil::Instance().IsLoopLabelsEmpty()) { + stmt->SetLoopLabelName(AstLoopUtil::Instance().GetCurrentLoop().second); + } stmts.emplace_back(std::move(stmt)); return stmts; } std::list ASTContinueStmt::Emit2FEStmtImpl() const { std::list stmts; - UniqueFEIRStmt stmt = std::make_unique(); + auto stmt = std::make_unique(); + stmt->SetLabelName(AstLoopUtil::Instance().GetCurrentLoop().first); stmts.emplace_back(std::move(stmt)); return stmts; } @@ -190,14 +224,7 @@ std::list ASTNullStmt::Emit2FEStmtImpl() const { std::list ASTDeclStmt::Emit2FEStmtImpl() const { std::list stmts; for (auto decl : subDecls) { - auto localVar = static_cast(decl); - if (localVar->GetInitExpr() != nullptr) { - UniqueFEIRVar feirVar = FEIRBuilder::CreateVarNameForC(localVar->GetName(), *(localVar->GetTypeDesc().front()), - false, false); - UniqueFEIRExpr expr = localVar->GetInitExpr()->Emit2FEExpr(stmts); - UniqueFEIRStmt stmt = FEIRBuilder::CreateStmtDAssign(std::move(feirVar), std::move(expr)); - stmts.emplace_back(std::move(stmt)); - } + decl->GenerateInitStmt(stmts); } return stmts; } @@ -305,16 +332,16 @@ std::list ASTBinaryOperatorStmt::Emit2FEStmtImpl() const { CHECK_FATAL(exprs.size() == 1, "ASTBinaryOperatorStmt must contain only one bo expr!"); std::list stmts; auto boExpr = static_cast(exprs.front()); - if (static_cast(boExpr) != nullptr) { - // has been processed by child expr emit, skip here - UniqueFEIRExpr boFEExpr = boExpr->Emit2FEExpr(stmts); - return stmts; - } else { + if (boExpr->GetASTOp() == kASTOpBO) { UniqueFEIRExpr boFEExpr = boExpr->Emit2FEExpr(stmts); std::list exprs; exprs.emplace_back(std::move(boFEExpr)); auto stmt = std::make_unique(OP_eval, std::move(exprs)); stmts.emplace_back(std::move(stmt)); + } else { + // has been processed by child expr emit, skip here + UniqueFEIRExpr boFEExpr = boExpr->Emit2FEExpr(stmts); + return stmts; } return stmts; } diff --git a/src/mplfe/bc_input/include/ark_annotation_processor.h b/src/mplfe/bc_input/include/ark_annotation_processor.h index d77e0bfb10fe9a58c378234a5af928d87e51cdf5..45797a55893bc71647951f5a94d95d1528b01161 100644 --- a/src/mplfe/bc_input/include/ark_annotation_processor.h +++ b/src/mplfe/bc_input/include/ark_annotation_processor.h @@ -26,19 +26,19 @@ class ArkAnnotationProcessor { class ArkAnnotation { public: void Init(); - bool IsFastNative(TyIdx tyIdx); - bool IsCriticalNative(TyIdx tyIdx); - bool IsCallerSensitive(TyIdx tyIdx); - bool IsPermanent(TyIdx tyIdx); + bool IsFastNative(const TyIdx &tyIdx) const; + bool IsCriticalNative(const TyIdx &tyIdx) const; + bool IsCallerSensitive(const TyIdx &tyIdx) const; + bool IsPermanent(const TyIdx &tyIdx) const; bool IsPermanent(const std::string &str) const; - bool IsRCUnowned(TyIdx tyIdx); - bool IsRCUnownedCap(TyIdx tyIdx); - bool IsRCUnownedCapList(TyIdx tyIdx); - bool IsRCUnownedLocal(TyIdx tyIdx); - bool IsRCUnownedLocalOld(TyIdx tyIdx); - bool IsRCUnownedThis(TyIdx tyIdx); - bool IsRCUnownedOuter(TyIdx tyIdx); - bool IsRCWeak(TyIdx tyIdx); + bool IsRCUnowned(const TyIdx &tyIdx) const; + bool IsRCUnownedCap(const TyIdx &tyIdx) const; + bool IsRCUnownedCapList(const TyIdx &tyIdx) const; + bool IsRCUnownedLocal(const TyIdx &tyIdx) const; + bool IsRCUnownedLocalOld(const TyIdx &tyIdx) const; + bool IsRCUnownedThis(const TyIdx &tyIdx) const; + bool IsRCUnownedOuter(const TyIdx &tyIdx) const; + bool IsRCWeak(const TyIdx &tyIdx) const; static ArkAnnotation &GetInstance() { return instance; } @@ -50,7 +50,7 @@ class ArkAnnotation { private: ArkAnnotation() = default; ~ArkAnnotation() = default; - MIRStructType *GetStructType(TyIdx tyIdx); + static MIRStructType *GetStructType(const TyIdx &tyIdx); static ArkAnnotation instance; std::set typeNameSetForFastNative; diff --git a/src/mplfe/bc_input/include/bc_class.h b/src/mplfe/bc_input/include/bc_class.h index 222432139f6cd2b30589682d21335053559da383..20448e02311890739e784cf64d8c6633d732add9 100644 --- a/src/mplfe/bc_input/include/bc_class.h +++ b/src/mplfe/bc_input/include/bc_class.h @@ -168,7 +168,7 @@ class BCClassMethod : public BCClassElem { tryInfos = std::move(infos); } - uint16 GetTriesSize() const { + std::size_t GetTriesSize() const { return tryInfos->size(); } @@ -291,7 +291,7 @@ class BCClass { } void SetSrcFileInfo(const std::string &name); - void SetIRSrcFileSigIdx(GStrIdx strIdx) { + void SetIRSrcFileSigIdx(const GStrIdx &strIdx) { irSrcFileSigIdx = strIdx; } @@ -334,7 +334,7 @@ class BCClass { std::string GetSourceFileName() const; GStrIdx GetIRSrcFileSigIdx() const; uint32 GetAccessFlag() const; - uint32 GetFileNameHashId() const; + int32 GetFileNameHashId() const; const std::vector> &GetFields() const; std::vector> &GetMethods(); diff --git a/src/mplfe/bc_input/include/bc_input-inl.h b/src/mplfe/bc_input/include/bc_input-inl.h index ad43262404d8c1195acf8aa971caf93165b76c38..27e5a3f7a7bcac848c7ee2079dc66507a6880e03 100644 --- a/src/mplfe/bc_input/include/bc_input-inl.h +++ b/src/mplfe/bc_input/include/bc_input-inl.h @@ -115,7 +115,7 @@ bool BCInput::CollectAllDepTypeNamesOnAllBCFiles(std::unordered_set classSet; - CollectClassNamesOnAllBCFiles(classSet); + (void)CollectClassNamesOnAllBCFiles(classSet); for (const auto &elem : classSet) { (void)allDepSet.erase(elem); } @@ -137,7 +137,7 @@ bool BCInput::CollectMethodDepTypeNamesOnAllBCFiles(std::unordered_setGetBCParser().CollectMethodDepTypeNames(depSet, *method); + (void)klass->GetBCParser().CollectMethodDepTypeNames(depSet, *method); } } std::unordered_set classSet; diff --git a/src/mplfe/bc_input/include/bc_instruction.h b/src/mplfe/bc_input/include/bc_instruction.h index 69805752dc730630bb64918662181ce9f6222f69..b1dc4db45c3de2f19989ffbe12e46ca901b40601 100644 --- a/src/mplfe/bc_input/include/bc_instruction.h +++ b/src/mplfe/bc_input/include/bc_instruction.h @@ -227,9 +227,9 @@ class BCRegType { void PrecisifyTypes(bool isTry = false); - void PrecisifyRelatedTypes(BCRegTypeItem *realType); + void PrecisifyRelatedTypes(const BCRegTypeItem *realType); - void PrecisifyElemTypes(BCRegTypeItem *realType); + void PrecisifyElemTypes(const BCRegTypeItem *realType); bool IsPrecisified() const { return precisified; @@ -257,13 +257,13 @@ class BCRegType { relatedBCRegTypes.emplace_back(ty); } - void RegisterLivesInfo(uint32 pos) { - livesBegins.emplace_back(pos); + void RegisterLivesInfo(uint32 posStart) { + livesBegins.emplace_back(posStart); } - bool IsBefore(uint32 pos, uint32 end) const { + bool IsBefore(uint32 posCurr, uint32 end) const { for (auto p : livesBegins) { - if (p == pos) { + if (p == posCurr) { return true; } if (p == end) { @@ -300,7 +300,7 @@ struct BCReg { BCReg() = default; virtual ~BCReg() = default; bool isDef = false; - uint32 regNum; + uint32 regNum = UINT32_MAX; BCRegType *regType = nullptr; BCRegValue *regValue = nullptr; BCRegTypeItem *regTypeItem = nullptr; @@ -350,7 +350,7 @@ struct TypeInferItem { return true; } - void InsertUniqueAliveTypes(TypeInferItem *end, const MapleList *types) { + void InsertUniqueAliveTypes(const TypeInferItem *end, const MapleList *types) { if (end != nullptr && end->reg == this->reg && end->reg->regType->IsBefore(this->beginPos, end->beginPos)) { return; } @@ -392,7 +392,7 @@ struct TypeInferItem { } } - void InsertUniqueAliveType(TypeInferItem *end, BCRegTypeItem *type) { + void InsertUniqueAliveType(const TypeInferItem *end, BCRegTypeItem *type) { if (end != nullptr && end->reg == this->reg && end->reg->regType->IsBefore(this->beginPos, end->beginPos)) { return; } diff --git a/src/mplfe/bc_input/include/bc_parser_base.h b/src/mplfe/bc_input/include/bc_parser_base.h index 0e53d5eef7b3c9d92f82295e45cd3f78263fa506..9bf0eedd3b1bd36ef51eacfe94d58d0b09bdf139 100644 --- a/src/mplfe/bc_input/include/bc_parser_base.h +++ b/src/mplfe/bc_input/include/bc_parser_base.h @@ -31,7 +31,7 @@ class BCParserBase { bool OpenFile(); bool ParseHeader(); bool Verify(); - uint32 GetFileNameHashId() const { + int32 GetFileNameHashId() const { return fileNameHashId; } uint32 CalculateCheckSum(const uint8 *data, uint32 size); diff --git a/src/mplfe/bc_input/src/ark_annotation_processor.cpp b/src/mplfe/bc_input/src/ark_annotation_processor.cpp index 9d11e74ecb5a40b0392f2eb5a1a28bbedd8fbe9b..86d37127bc922c06fd2286071018347d6729368f 100644 --- a/src/mplfe/bc_input/src/ark_annotation_processor.cpp +++ b/src/mplfe/bc_input/src/ark_annotation_processor.cpp @@ -72,25 +72,25 @@ void ArkAnnotation::Init() { typeNameSetForRCWeak.insert(GetStrIdxFromDexName("Lark/annotation/Weak;")); } -bool ArkAnnotation::IsFastNative(TyIdx tyIdx) { +bool ArkAnnotation::IsFastNative(const TyIdx &tyIdx) const { MIRStructType *sType = GetStructType(tyIdx); return sType == nullptr ? false : typeNameSetForFastNative.find(sType->GetNameStrIdx()) != typeNameSetForFastNative.end(); } -bool ArkAnnotation::IsCriticalNative(TyIdx tyIdx) { +bool ArkAnnotation::IsCriticalNative(const TyIdx &tyIdx) const { MIRStructType *sType = GetStructType(tyIdx); return sType == nullptr ? false : typeNameSetForCriticalNative.find(sType->GetNameStrIdx()) != typeNameSetForCriticalNative.end(); } -bool ArkAnnotation::IsCallerSensitive(TyIdx tyIdx) { +bool ArkAnnotation::IsCallerSensitive(const TyIdx &tyIdx) const { MIRStructType *sType = GetStructType(tyIdx); return sType == nullptr ? false : typeNameSetForCallerSensitive.find(sType->GetNameStrIdx()) != typeNameSetForCallerSensitive.end(); } -bool ArkAnnotation::IsPermanent(TyIdx tyIdx) { +bool ArkAnnotation::IsPermanent(const TyIdx &tyIdx) const { MIRStructType *sType = GetStructType(tyIdx); return sType == nullptr ? false : typeNameSetForPermanent.find(sType->GetNameStrIdx()) != typeNameSetForPermanent.end(); @@ -107,55 +107,55 @@ bool ArkAnnotation::IsPermanent(const std::string &str) const { return false; } -bool ArkAnnotation::IsRCUnowned(TyIdx tyIdx) { +bool ArkAnnotation::IsRCUnowned(const TyIdx &tyIdx) const { MIRStructType *sType = GetStructType(tyIdx); return sType == nullptr ? false : typeNameSetForRCUnowned.find(sType->GetNameStrIdx()) != typeNameSetForRCUnowned.end(); } -bool ArkAnnotation::IsRCUnownedCap(TyIdx tyIdx) { +bool ArkAnnotation::IsRCUnownedCap(const TyIdx &tyIdx) const { MIRStructType *sType = GetStructType(tyIdx); return sType == nullptr ? false : typeNameSetForRCUnownedCap.find(sType->GetNameStrIdx()) != typeNameSetForRCUnownedCap.end(); } -bool ArkAnnotation::IsRCUnownedCapList(TyIdx tyIdx) { +bool ArkAnnotation::IsRCUnownedCapList(const TyIdx &tyIdx) const { MIRStructType *sType = GetStructType(tyIdx); return sType == nullptr ? false : typeNameSetForRCUnownedCapList.find(sType->GetNameStrIdx()) != typeNameSetForRCUnownedCapList.end(); } -bool ArkAnnotation::IsRCUnownedLocal(TyIdx tyIdx) { +bool ArkAnnotation::IsRCUnownedLocal(const TyIdx &tyIdx) const { MIRStructType *sType = GetStructType(tyIdx); return sType == nullptr ? false : typeNameSetForRCUnownedLocal.find(sType->GetNameStrIdx()) != typeNameSetForRCUnownedLocal.end(); } -bool ArkAnnotation::IsRCUnownedLocalOld(TyIdx tyIdx) { +bool ArkAnnotation::IsRCUnownedLocalOld(const TyIdx &tyIdx) const { MIRStructType *sType = GetStructType(tyIdx); return sType == nullptr ? false : typeNameIdxForRCUnownedLocalOld == sType->GetNameStrIdx(); } -bool ArkAnnotation::IsRCUnownedThis(TyIdx tyIdx) { +bool ArkAnnotation::IsRCUnownedThis(const TyIdx &tyIdx) const { MIRStructType *sType = GetStructType(tyIdx); return sType == nullptr ? false : typeNameSetForRCUnownedThis.find(sType->GetNameStrIdx()) != typeNameSetForRCUnownedThis.end(); } -bool ArkAnnotation::IsRCUnownedOuter(TyIdx tyIdx) { +bool ArkAnnotation::IsRCUnownedOuter(const TyIdx &tyIdx) const { MIRStructType *sType = GetStructType(tyIdx); return sType == nullptr ? false : typeNameSetForRCUnownedOuter.find(sType->GetNameStrIdx()) != typeNameSetForRCUnownedOuter.end(); } -bool ArkAnnotation::IsRCWeak(TyIdx tyIdx) { +bool ArkAnnotation::IsRCWeak(const TyIdx &tyIdx) const { MIRStructType *sType = GetStructType(tyIdx); return sType == nullptr ? false : typeNameSetForRCWeak.find(sType->GetNameStrIdx()) != typeNameSetForRCWeak.end(); } -MIRStructType *ArkAnnotation::GetStructType(TyIdx tyIdx) { +MIRStructType *ArkAnnotation::GetStructType(const TyIdx &tyIdx) { MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); if (!type->IsMIRClassType() && !type->IsMIRInterfaceType()) { return nullptr; diff --git a/src/mplfe/bc_input/src/bc_class.cpp b/src/mplfe/bc_input/src/bc_class.cpp index 0e8073e70a354c9eed0e13166884b1a22ed1b93e..1cfb6e5ac6be776790882c66d9bfdc5e29489ab2 100644 --- a/src/mplfe/bc_input/src/bc_class.cpp +++ b/src/mplfe/bc_input/src/bc_class.cpp @@ -528,12 +528,12 @@ void BCClass::SetAccFlag(uint32 flag) { } void BCClass::SetField(std::unique_ptr field) { - (void)fields.push_back(std::move(field)); + fields.push_back(std::move(field)); } void BCClass::SetMethod(std::unique_ptr method) { std::lock_guard lock(bcClassMtx); - (void)methods.push_back(std::move(method)); + methods.push_back(std::move(method)); } void BCClass::InsertFinalStaticStringID(uint32 stringID) { @@ -582,7 +582,7 @@ GStrIdx BCClass::GetIRSrcFileSigIdx() const { return irSrcFileSigIdx; } -uint32 BCClass::GetFileNameHashId() const { +int32 BCClass::GetFileNameHashId() const { return parser.GetFileNameHashId(); } diff --git a/src/mplfe/bc_input/src/bc_instruction.cpp b/src/mplfe/bc_input/src/bc_instruction.cpp index 8a255561bfbfa767c55cbdb43151a30f84efeb04..2f4ccfdfaadda59dbc6371b98cb7f4b8a7786cc2 100644 --- a/src/mplfe/bc_input/src/bc_instruction.cpp +++ b/src/mplfe/bc_input/src/bc_instruction.cpp @@ -383,7 +383,7 @@ void BCRegType::PrecisifyTypes(bool isTry) { } } -void BCRegType::PrecisifyRelatedTypes(BCRegTypeItem *realType) { +void BCRegType::PrecisifyRelatedTypes(const BCRegTypeItem *realType) { for (auto rType : relatedBCRegTypes) { // try to get type from use first. // if failed, get type from def. @@ -406,7 +406,7 @@ void BCRegType::PrecisifyRelatedTypes(BCRegTypeItem *realType) { } } -void BCRegType::PrecisifyElemTypes(BCRegTypeItem *arrayType) { +void BCRegType::PrecisifyElemTypes(const BCRegTypeItem *arrayType) { for (auto elem : elemTypes) { if (elem->isIndeterminate) { const std::string &arrTypeName = GlobalTables::GetStrTable().GetStringFromStrIdx(arrayType->typeNameIdx); diff --git a/src/mplfe/bc_input/src/bc_io.cpp b/src/mplfe/bc_input/src/bc_io.cpp index bda1cec582d0182d181e4b50119ba9ff5807798f..fab0438a6a3f3e437d0d38ca056382726f08d714 100644 --- a/src/mplfe/bc_input/src/bc_io.cpp +++ b/src/mplfe/bc_input/src/bc_io.cpp @@ -32,6 +32,8 @@ void BCReader::SetEndianTag(bool isBigEndianIn) { } bool BCReader::RetrieveHeaderImpl(RawData &data) { + (void)data; + CHECK_FATAL(false, "NIY"); return false; } diff --git a/src/mplfe/bc_input/src/bc_util.cpp b/src/mplfe/bc_input/src/bc_util.cpp index 05d308f1645f5336fe959d87947b70baae960b93..474c27a11086c3e196aca430e088155264366b90 100644 --- a/src/mplfe/bc_input/src/bc_util.cpp +++ b/src/mplfe/bc_input/src/bc_util.cpp @@ -148,7 +148,7 @@ bool BCUtil::IsArrayType(const GStrIdx &typeNameIdx) { } std::string BCUtil::TrimArrayModifier(const std::string &typeName) { - int index = 0; + std::size_t index = 0; for (; index < typeName.size(); ++index) { if (typeName[index] != '[') { break; @@ -185,15 +185,15 @@ void BCUtil::AddDefaultDepSet(std::unordered_set &typeTable) { // get the serial number in register name, for example 2 in Reg2_I uint32 BCUtil::Name2RegNum(const std::string &name) { - const uint16 regPrefixLen = strlen("Reg"); - int numLen = name.length() - regPrefixLen; + const std::size_t regPrefixLen = strlen("Reg"); + std::size_t numLen = name.length() - regPrefixLen; // Nonreg names also reach here, e.g. "_this". Make sure they are not handle. - const uint16 regVarMinLen = 6; + const std::size_t regVarMinLen = 6; if (numLen < regVarMinLen - regPrefixLen || name.compare(0, regPrefixLen, "Reg") != 0) { return UINT32_MAX; } std::string regName = name.substr(regPrefixLen); - int i = 0; + std::size_t i = 0; for (; i < numLen; i++) { if (regName[i] < '0' || regName[i] > '9') { break; @@ -204,7 +204,7 @@ uint32 BCUtil::Name2RegNum(const std::string &name) { return UINT32_MAX; } int regNum = std::stoi(regName.substr(0, i)); - return regNum; + return static_cast(regNum); } bool BCUtil::HasContainSuffix(const std::string &value, const std::string &suffix) { diff --git a/src/mplfe/common/include/basic_io.h b/src/mplfe/common/include/basic_io.h index c29b21b25471e36e864e48cce6394dbde95380e7..22b0b74e0c7609e797bd0c5eb451b35410f6dc22 100644 --- a/src/mplfe/common/include/basic_io.h +++ b/src/mplfe/common/include/basic_io.h @@ -94,7 +94,9 @@ class BasicIOMapFile { explicit BasicIOMapFile(const std::string &name); BasicIOMapFile(const std::string &name, const uint8 *ptrIn, long lengthIn); virtual ~BasicIOMapFile(); - virtual bool OpenAndMap(); + bool OpenAndMap() { + return OpenAndMapImpl(); + } void Close(); static std::unique_ptr GenFileInMemory(const std::string &name, const uint8 *buf, size_t len); @@ -119,6 +121,7 @@ class BasicIOMapFile { } protected: + virtual bool OpenAndMapImpl(); int fd; const uint8 *ptr; uint8 *ptrMemMap; diff --git a/src/mplfe/common/include/fe_utils.h b/src/mplfe/common/include/fe_utils.h index 77e8207b5d6183bd81a76c4b0c71444b917cfad3..6a0d16068424eaa4f76a9eb0e7986b3292d912ab 100644 --- a/src/mplfe/common/include/fe_utils.h +++ b/src/mplfe/common/include/fe_utils.h @@ -71,11 +71,7 @@ class FEUtils { static const std::string kMCCStaticFieldSetObject; static inline MemPool *NewMempool(const std::string &name, bool isLocalPool) { -#ifndef USE_OPS return memPoolCtrler.NewMemPool(name, isLocalPool); -#else - return memPoolCtrler.NewMemPool(name); -#endif } static inline void DeleteMempoolPtr(MemPool *memPoolPtr) { @@ -298,18 +294,17 @@ class AstSwitchUtil { static AstSwitchUtil local; return local; } - using BlockLabel = std::pair; - - BlockLabel AllocateLoopOrSwitchLabels(MIRBuilder &mirBuilder); - void MarkLabelUsed(LabelIdx label); - void MarkLabelUnUsed(LabelIdx label); - void PushNestedBreakLabels(LabelIdx label); + std::string CreateEndOrExitLabelName() const; + void MarkLabelUsed(const std::string &label); + void MarkLabelUnUsed(const std::string &label); + void PushNestedBreakLabels(const std::string &label); void PopNestedBreakLabels(); - void PushNestedCaseVectors(std::pair); + void PushNestedCaseVectors(const std::pair &caseVec); void PopNestedCaseVectors(); - bool CheckLabelUsed(LabelIdx label); + bool CheckLabelUsed(const std::string &label); const std::pair &GetTopOfNestedCaseVectors() const; - std::map &GetLabelUseMap() { + const std::string &GetTopOfBreakLabels() const; + std::map &GetLabelUseMap() { return labelUsed; } static uint32_t tempVarNo; @@ -322,10 +317,28 @@ class AstSwitchUtil { private: AstSwitchUtil() = default; - std::map labelUsed = std::map(); - std::stack nestedBreakLabels = std::stack(); // loop and switch blocks + std::map labelUsed = std::map(); + std::stack nestedBreakLabels = std::stack(); // loop and switch blocks std::stack nestedContinueLabels = std::stack(); // loop blocks only std::stack> nestedCaseVectors = std::stack>(); }; // end of AstSwitchUtil + +class AstLoopUtil { + public: + static AstLoopUtil &Instance() { + static AstLoopUtil local; + return local; + } + + ~AstLoopUtil() = default; + void PushLoop(const std::pair &labelPair); + std::pair GetCurrentLoop(); + void PopCurrentLoop(); + bool IsLoopLabelsEmpty () const; + + private: + AstLoopUtil() = default; + std::stack> loopLabels = std::stack>(); +}; } // namespace maple #endif // MPLFE_INCLUDE_FE_UTILS_H \ No newline at end of file diff --git a/src/mplfe/common/include/fe_utils_ast.h b/src/mplfe/common/include/fe_utils_ast.h index 7ca86a52146ad2217ba12c52b2cf892dd451abb7..81136a728ab9c06b9b468c0f449063fb65220a20 100644 --- a/src/mplfe/common/include/fe_utils_ast.h +++ b/src/mplfe/common/include/fe_utils_ast.h @@ -16,7 +16,8 @@ #define MPLFE_INCLUDE_FE_UTILS_AST_H #include #include -#include "feir_type.h" +#include "types_def.h" +#include "cfg_primitive_types.h" namespace maple { class FEUtilAST { diff --git a/src/mplfe/common/include/feir_builder.h b/src/mplfe/common/include/feir_builder.h index 09711b5055e70a27ba3822210063ebd147aaab48..32a9c500893f4d915fbe3f76982d5496f86ba1d2 100644 --- a/src/mplfe/common/include/feir_builder.h +++ b/src/mplfe/common/include/feir_builder.h @@ -38,25 +38,27 @@ class FEIRBuilder { static UniqueFEIRVar CreateVarName(const std::string &name, PrimType primType, bool isGlobal = false, bool withType = false); static UniqueFEIRVar CreateVarNameForC(GStrIdx nameIdx, MIRType &mirType, bool isGlobal = false, - bool withType = false, TypeDim dim = 0); + bool withType = false); static UniqueFEIRVar CreateVarNameForC(const std::string &name, MIRType &mirType, bool isGlobal = false, - bool withType = false, TypeDim dim = 0); + bool withType = false); // Expr static UniqueFEIRExpr CreateExprDRead(UniqueFEIRVar srcVar); static UniqueFEIRExpr CreateExprAddrof(const std::vector &array); static UniqueFEIRExpr CreateExprAddrofVar(UniqueFEIRVar srcVar); static UniqueFEIRExpr CreateExprIRead(UniqueFEIRType returnType, UniqueFEIRType ptrType, FieldID id, UniqueFEIRExpr expr); - static UniqueFEIRExpr CreateExprTernary(Opcode op, UniqueFEIRExpr cExpr, + static UniqueFEIRExpr CreateExprTernary(Opcode op, UniqueFEIRType type, UniqueFEIRExpr cExpr, UniqueFEIRExpr tExpr, UniqueFEIRExpr fExpr); static UniqueFEIRExpr CreateExprConstRefNull(); + static UniqueFEIRExpr CreateExprConstPtrNull(); static UniqueFEIRExpr CreateExprConstI8(int8 val); static UniqueFEIRExpr CreateExprConstI16(int16 val); static UniqueFEIRExpr CreateExprConstI32(int32 val); static UniqueFEIRExpr CreateExprConstI64(int64 val); + static UniqueFEIRExpr CreateExprConstU64(uint64 val); static UniqueFEIRExpr CreateExprConstF32(float val); static UniqueFEIRExpr CreateExprConstF64(double val); - static UniqueFEIRExpr CreateExprZeroConst(PrimType primType); + static UniqueFEIRExpr CreateExprConstAnyScalar(PrimType primType, int8 val); static UniqueFEIRExpr CreateExprMathUnary(Opcode op, UniqueFEIRVar var0); static UniqueFEIRExpr CreateExprMathUnary(Opcode op, UniqueFEIRExpr expr); static UniqueFEIRExpr CreateExprMathBinary(Opcode op, UniqueFEIRVar var0, UniqueFEIRVar var1); @@ -81,7 +83,7 @@ class FEIRBuilder { // Stmt static UniqueFEIRStmt CreateStmtDAssign(UniqueFEIRVar dstVar, UniqueFEIRExpr srcExpr, bool hasException = false); static UniqueFEIRStmt CreateStmtGoto(uint32 targetLabelIdx); - static UniqueFEIRStmt CreateStmtGoto(std::string labelName); + static UniqueFEIRStmt CreateStmtGoto(const std::string &labelName); static UniqueFEIRStmt CreateStmtCondGoto(uint32 targetLabelIdx, Opcode op, UniqueFEIRExpr expr); static UniqueFEIRStmt CreateStmtSwitch(UniqueFEIRExpr expr); static UniqueFEIRStmt CreateStmtIfWithoutElse(UniqueFEIRExpr cond, std::list &thenStmts); @@ -101,6 +103,8 @@ class FEIRBuilder { UniqueFEIRVar varIndex); static UniqueFEIRStmt CreateStmtArrayStoreOneStmt(UniqueFEIRVar varElem, UniqueFEIRVar varArray, UniqueFEIRExpr exprIndex); + static UniqueFEIRStmt CreateStmtArrayStoreOneStmtForC(UniqueFEIRExpr exprElem, UniqueFEIRExpr exprArray, + UniqueFEIRExpr exprIndex, UniqueFEIRType arrayType); static std::list CreateStmtArrayLoad(UniqueFEIRVar varElem, UniqueFEIRVar varArray, UniqueFEIRVar varIndex); static UniqueFEIRStmt CreateStmtArrayLength(UniqueFEIRVar varLength, UniqueFEIRVar varArray); diff --git a/src/mplfe/common/include/feir_node_kind.def b/src/mplfe/common/include/feir_node_kind.def index 3c5275a7f25cf7dcd49817ea3c1f076f639c190d..20276d07a4780b8485f37ea53fa60c0e70bd48a8 100644 --- a/src/mplfe/common/include/feir_node_kind.def +++ b/src/mplfe/common/include/feir_node_kind.def @@ -68,3 +68,4 @@ FEIR_NODE_KIND(StmtIf, "StmtIf") FEIR_NODE_KIND(StmtDoWhile, "StmtDoWhile") FEIR_NODE_KIND(StmtBreak, "StmtBreak") FEIR_NODE_KIND(StmtContinue, "StmtContinue") +FEIR_NODE_KIND(StmtLabel, "StmtLabel") diff --git a/src/mplfe/common/include/feir_stmt.h b/src/mplfe/common/include/feir_stmt.h index 9547217686771691694d67c54a130ba66a00d87a..1ff7d0231ad8240927d9a9b03e0a102b7e129d89 100644 --- a/src/mplfe/common/include/feir_stmt.h +++ b/src/mplfe/common/include/feir_stmt.h @@ -145,7 +145,7 @@ class FEIRStmt : public GeneralStmt { return HasDefImpl(); } - bool SetHexPC(uint32 argHexPC) { + void SetHexPC(uint32 argHexPC) { return SetHexPCImpl(argHexPC); } @@ -190,9 +190,8 @@ class FEIRStmt : public GeneralStmt { return false; } - bool SetHexPCImpl(uint32 argHexPC) { + void SetHexPCImpl(uint32 argHexPC) { hexPC = argHexPC; - return true; } uint32 GetHexPCImpl(void) const { @@ -403,7 +402,7 @@ class FEIRExprDRead : public FEIRExpr { return trans; } - FieldID GetFieldID() { + FieldID GetFieldID() const { return fieldID; } @@ -411,7 +410,7 @@ class FEIRExprDRead : public FEIRExpr { return varSrc; } - void SetFieldName(std::string argFieldName){ + void SetFieldName(const std::string &argFieldName){ fieldName = argFieldName; } @@ -582,28 +581,28 @@ class FEIRExprIRead : public FEIRExpr { fieldID(id), subExpr(std::move(expr)) {} ~FEIRExprIRead() override = default; - void SetFieldID(FieldID argFieldID){ + void SetFieldID(FieldID argFieldID) { fieldID = argFieldID; } - FieldID GetFieldID(){ + FieldID GetFieldID() const { return fieldID; } - void SetFieldName(std::string argFieldName){ + void SetFieldName(const std::string &argFieldName) { fieldName = argFieldName; } - std::string GetFieldName(){ + std::string GetFieldName() const { return fieldName; } - UniqueFEIRExpr &GetOpnd(){ - return opnd; + UniqueFEIRExpr GetClonedOpnd() const { + return subExpr->Clone(); } - UniqueFEIRType &GetType(){ - return type; + UniqueFEIRType GetClonedType() const { + return ptrType->Clone(); } protected: @@ -615,8 +614,6 @@ class FEIRExprIRead : public FEIRExpr { UniqueFEIRType ptrType; FieldID fieldID; UniqueFEIRExpr subExpr; - UniqueFEIRExpr opnd; - UniqueFEIRType type; std::string fieldName; }; @@ -629,6 +626,7 @@ class FEIRExprBinary : public FEIRExpr { ~FEIRExprBinary() = default; void SetOpnd0(std::unique_ptr argOpnd); void SetOpnd1(std::unique_ptr argOpnd); + bool IsComparative() const; protected: std::unique_ptr CloneImpl() const override; @@ -662,6 +660,8 @@ class FEIRExprTernary : public FEIRExpr { public: FEIRExprTernary(Opcode argOp, std::unique_ptr argOpnd0, std::unique_ptr argOpnd1, std::unique_ptr argOpnd2); + FEIRExprTernary(Opcode argOp, std::unique_ptr argType, std::unique_ptr argOpnd0, + std::unique_ptr argOpnd1, std::unique_ptr argOpnd2); ~FEIRExprTernary() = default; void SetOpnd(std::unique_ptr argOpnd, uint32 idx); @@ -687,7 +687,7 @@ class FEIRExprTernary : public FEIRExpr { class FEIRExprNary : public FEIRExpr { public: explicit FEIRExprNary(Opcode argOp); - ~FEIRExprNary() = default; + virtual ~FEIRExprNary() = default; void AddOpnd(std::unique_ptr argOpnd); void AddOpnds(const std::vector> &argOpnds); void ResetOpnd(); @@ -750,6 +750,7 @@ class FEIRExprIntrinsicop : public FEIRExprNary { class FEIRExprJavaMerge : public FEIRExprNary { public: FEIRExprJavaMerge(std::unique_ptr mergedTypeArg, const std::vector> &argOpnds); + ~FEIRExprJavaMerge() = default; protected: std::unique_ptr CloneImpl() const override; @@ -835,8 +836,6 @@ class FEIRExprArrayStoreForC : public FEIRExpr { FEIRExprArrayStoreForC(UniqueFEIRExpr argExprArray, UniqueFEIRExpr argExprIndex, UniqueFEIRType argTypeNative); ~FEIRExprArrayStoreForC() = default; - std::unique_ptr CloneImpl() const override; - FEIRExpr &GetExprArray() const { ASSERT(exprArray != nullptr, "exprArray is nullptr"); return *exprArray.get(); @@ -852,8 +851,11 @@ class FEIRExprArrayStoreForC : public FEIRExpr { return *typeNative.get(); } - private: + protected: + std::unique_ptr CloneImpl() const override; BaseNode *GenMIRNodeImpl(MIRBuilder &mirBuilder) const override; + + private: UniqueFEIRExpr exprArray; UniqueFEIRExpr exprIndex; UniqueFEIRType typeNative; @@ -901,7 +903,7 @@ class FEIRExprCStyleCast : public FEIRExpr { void SetArray2Pointer(bool isArr2Ptr) { isArray2Pointer = isArr2Ptr; } - void SetRefName(std::string name) { + void SetRefName(const std::string &name) { refName = name; } @@ -949,16 +951,15 @@ class FEIRExprAtomic : public FEIRExpr { private: void ProcessAtomicBinary(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, - MIRSymbol &valueVar, ASTAtomicOp opcode) const; + MIRSymbol &valueVar) const; void ProcessAtomicLoad(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, - MIRSymbol &valueVar) const; - void ProcessAtomicStore(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, - MIRSymbol &valueVar) const; + const MIRSymbol &valueVar) const; + void ProcessAtomicStore(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode) const; void ProcessAtomicExchange(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, - MIRSymbol &valueVar) const; + const MIRSymbol &valueVar) const; void ProcessAtomicCompareExchange(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, - MIRSymbol *valueVar) const; - MIRType *type = nullptr; + const MIRSymbol *valueVar) const; + MIRType *mirType = nullptr; MIRType *refType = nullptr; MIRType *val1Type = nullptr; MIRType *val2Type = nullptr; @@ -1037,7 +1038,7 @@ class FEIRStmtDAssign : public FEIRStmtAssign { expr = std::move(argExpr); } - void SetFieldName(std::string argFieldName) { + void SetFieldName(const std::string &argFieldName) { fieldName = argFieldName; } @@ -1343,7 +1344,7 @@ class FEIRStmtGoto2 : public FEIRStmt { // ---------- FEIRStmtGoto ---------- class FEIRStmtGotoForC : public FEIRStmt { public: - explicit FEIRStmtGotoForC(std::string labelName); + explicit FEIRStmtGotoForC(const std::string &labelName); virtual ~FEIRStmtGotoForC() = default; void SetLabelName(std::string name) { labelName = std::move(name); @@ -2013,8 +2014,16 @@ class FEIRStmtBreak : public FEIRStmt { FEIRStmtBreak(): FEIRStmt(FEIRNodeKind::kStmtBreak) {} ~FEIRStmtBreak() = default; - void SetLabelName(std::string name){ - labelName = std::move(name); + void SetLoopLabelName(std::string name){ + loopLabelName = std::move(name); + } + + void SetSwitchLabelName(std::string name){ + switchLabelName = std::move(name); + } + + void SetIsFromSwitch(bool fromSwitch) { + isFromSwitch = fromSwitch; } protected: @@ -2024,7 +2033,9 @@ class FEIRStmtBreak : public FEIRStmt { std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; private: - std::string labelName; + std::string loopLabelName; + std::string switchLabelName; + bool isFromSwitch = false; }; class FEIRStmtContinue : public FEIRStmt { @@ -2045,5 +2056,21 @@ class FEIRStmtContinue : public FEIRStmt { private: std::string labelName; }; + +class FEIRStmtLabel : public FEIRStmt { + public: + explicit FEIRStmtLabel(const std::string &name): FEIRStmt(FEIRNodeKind::kStmtLabel), labelName(name) {} + ~FEIRStmtLabel() = default; + + protected: + bool IsBranchImpl() const override { + return true; + } + + std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + + private: + std::string labelName; +}; } // namespace maple #endif // MPLFE_INCLUDE_COMMON_FEIR_STMT_H diff --git a/src/mplfe/common/src/basic_io.cpp b/src/mplfe/common/src/basic_io.cpp index 8701b9e20a6e5bfae9ef1cf34d33d1ab583ad0ca..c8849c7d5d93adeb36897149b8e7976983ad84e3 100644 --- a/src/mplfe/common/src/basic_io.cpp +++ b/src/mplfe/common/src/basic_io.cpp @@ -34,7 +34,7 @@ BasicIOMapFile::~BasicIOMapFile() { ptrMemMap = nullptr; } -bool BasicIOMapFile::OpenAndMap() { +bool BasicIOMapFile::OpenAndMapImpl() { fd = -1; fd = open(fileName.c_str(), O_RDONLY); if (fd < 0) { diff --git a/src/mplfe/common/src/fe_utils.cpp b/src/mplfe/common/src/fe_utils.cpp index 81154dad3a95c657a4383122aa3a8776a740795c..7b10e1b148ac71100516460d907627a0eabe9b78 100644 --- a/src/mplfe/common/src/fe_utils.cpp +++ b/src/mplfe/common/src/fe_utils.cpp @@ -243,24 +243,21 @@ const char *AstSwitchUtil::caseLabel = "case"; const char *AstSwitchUtil::catchLabel = "catch"; const char *AstSwitchUtil::endehLabel = "endeh"; -AstSwitchUtil::BlockLabel AstSwitchUtil::AllocateLoopOrSwitchLabels(MIRBuilder &mirBuilder) { - std::string tempName = FEUtils::GetSequentialName0(blockLabel, tempVarNo); - LabelIdx endLab = mirBuilder.GetOrCreateMIRLabel(tempName); - tempName = FEUtils::GetSequentialName0(blockLabel, tempVarNo); - LabelIdx exitLab = mirBuilder.GetOrCreateMIRLabel(tempName); +std::string AstSwitchUtil::CreateEndOrExitLabelName() const { + std::string labelName = FEUtils::GetSequentialName0(blockLabel, tempVarNo); ++tempVarNo; - return BlockLabel(endLab, exitLab); + return labelName; } -void AstSwitchUtil::MarkLabelUsed(LabelIdx label) { +void AstSwitchUtil::MarkLabelUsed(const std::string &label) { labelUsed[label] = true; } -void AstSwitchUtil::MarkLabelUnUsed(LabelIdx label) { +void AstSwitchUtil::MarkLabelUnUsed(const std::string &label) { labelUsed[label] = false; } -void AstSwitchUtil::PushNestedBreakLabels(LabelIdx label) { +void AstSwitchUtil::PushNestedBreakLabels(const std::string &label) { nestedBreakLabels.push(label); } @@ -268,7 +265,7 @@ void AstSwitchUtil::PopNestedBreakLabels() { nestedBreakLabels.pop(); } -void AstSwitchUtil::PushNestedCaseVectors(std::pair caseVec) { +void AstSwitchUtil::PushNestedCaseVectors(const std::pair &caseVec) { nestedCaseVectors.push(caseVec); } @@ -276,11 +273,31 @@ void AstSwitchUtil::PopNestedCaseVectors() { nestedCaseVectors.pop(); } -bool AstSwitchUtil::CheckLabelUsed(LabelIdx label) { +bool AstSwitchUtil::CheckLabelUsed(const std::string &label) { return labelUsed[label]; } const std::pair &AstSwitchUtil::GetTopOfNestedCaseVectors() const { return nestedCaseVectors.top(); } + +const std::string &AstSwitchUtil::GetTopOfBreakLabels() const { + return nestedBreakLabels.top(); +} + +void AstLoopUtil::PushLoop(const std::pair &labelPair) { + loopLabels.push(labelPair); +} + +std::pair AstLoopUtil::GetCurrentLoop(){ + return loopLabels.top(); +} + +bool AstLoopUtil::IsLoopLabelsEmpty() const { + return loopLabels.empty(); +} + +void AstLoopUtil::PopCurrentLoop(){ + loopLabels.pop(); +} } // namespace maple \ No newline at end of file diff --git a/src/mplfe/common/src/fe_utils_ast.cpp b/src/mplfe/common/src/fe_utils_ast.cpp index dfece44405f54e58227856c35eeb327047f70f60..c10ca129c5da7473f6b1b288e1ec002aa43f6a9b 100644 --- a/src/mplfe/common/src/fe_utils_ast.cpp +++ b/src/mplfe/common/src/fe_utils_ast.cpp @@ -13,6 +13,8 @@ * See the Mulan PSL v2 for more details. */ #include "fe_utils_ast.h" +#include +#include "mpl_logging.h" namespace maple { PrimType FEUtilAST::GetTypeFromASTTypeName(const std::string &typeName) { diff --git a/src/mplfe/common/src/feir_builder.cpp b/src/mplfe/common/src/feir_builder.cpp index de76844e2bc959621da52625132ca508d22c900e..a8850053984601b03ea847c0fb6f2409ceac6c71 100644 --- a/src/mplfe/common/src/feir_builder.cpp +++ b/src/mplfe/common/src/feir_builder.cpp @@ -78,18 +78,16 @@ UniqueFEIRVar FEIRBuilder::CreateVarName(const std::string &name, PrimType primT return CreateVarName(nameIdx, primType, isGlobal, withType); } -UniqueFEIRVar FEIRBuilder::CreateVarNameForC(GStrIdx nameIdx, MIRType &mirType, bool isGlobal, bool withType, - TypeDim dim) { +UniqueFEIRVar FEIRBuilder::CreateVarNameForC(GStrIdx nameIdx, MIRType &mirType, bool isGlobal, bool withType) { UniqueFEIRType type = std::make_unique(mirType); UniqueFEIRVar var = std::make_unique(nameIdx, std::move(type), withType); var->SetGlobal(isGlobal); return var; } -UniqueFEIRVar FEIRBuilder::CreateVarNameForC(const std::string &name, MIRType &mirType, bool isGlobal, bool withType, - TypeDim dim) { +UniqueFEIRVar FEIRBuilder::CreateVarNameForC(const std::string &name, MIRType &mirType, bool isGlobal, bool withType) { GStrIdx nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name); - return CreateVarNameForC(nameIdx, mirType, isGlobal, withType, dim); + return CreateVarNameForC(nameIdx, mirType, isGlobal, withType); } UniqueFEIRExpr FEIRBuilder::CreateExprDRead(UniqueFEIRVar srcVar) { @@ -116,9 +114,10 @@ UniqueFEIRExpr FEIRBuilder::CreateExprAddrofVar(UniqueFEIRVar srcVar) { return expr; } -UniqueFEIRExpr FEIRBuilder::CreateExprTernary(Opcode op, UniqueFEIRExpr cExpr, +UniqueFEIRExpr FEIRBuilder::CreateExprTernary(Opcode op, UniqueFEIRType type, UniqueFEIRExpr cExpr, UniqueFEIRExpr tExpr, UniqueFEIRExpr fExpr) { - UniqueFEIRExpr expr = std::make_unique(op, std::move(cExpr), std::move(tExpr), std::move(fExpr)); + UniqueFEIRExpr expr = std::make_unique(op, std::move(type), std::move(cExpr), + std::move(tExpr), std::move(fExpr)); return expr; } @@ -126,6 +125,10 @@ UniqueFEIRExpr FEIRBuilder::CreateExprConstRefNull() { return std::make_unique(int64{ 0 }, PTY_ref); } +UniqueFEIRExpr FEIRBuilder::CreateExprConstPtrNull() { + return std::make_unique(int64{ 0 }, PTY_ptr); +} + UniqueFEIRExpr FEIRBuilder::CreateExprConstI8(int8 val) { return std::make_unique(int64{ val }, PTY_i8); } @@ -142,6 +145,10 @@ UniqueFEIRExpr FEIRBuilder::CreateExprConstI64(int64 val) { return std::make_unique(val, PTY_i64); } +UniqueFEIRExpr FEIRBuilder::CreateExprConstU64(uint64 val) { + return std::make_unique(val, PTY_u64); +} + UniqueFEIRExpr FEIRBuilder::CreateExprConstF32(float val) { return std::make_unique(val); } @@ -150,18 +157,30 @@ UniqueFEIRExpr FEIRBuilder::CreateExprConstF64(double val) { return std::make_unique(val); } -UniqueFEIRExpr FEIRBuilder::CreateExprZeroConst(PrimType primType) { +// Create a const expr of specified prime type with fixed value. +// Note that loss of precision, byte value is only supported. +UniqueFEIRExpr FEIRBuilder::CreateExprConstAnyScalar(PrimType primType, int8 val) { switch (primType) { - case PTY_f32: - return CreateExprConstF32(0.0f); - case PTY_f64: - return CreateExprConstF64(0.0); + case PTY_u8: + case PTY_u16: + case PTY_u32: + case PTY_u64: + case PTY_i8: + case PTY_i16: + case PTY_i32: + case PTY_i64: + return std::make_unique(static_cast(val), primType); case PTY_f128: // Not Implemented CHECK_FATAL(false, "Not Implemented"); return nullptr; + case PTY_f32: + return CreateExprConstF32(static_cast(val)); + case PTY_f64: + return CreateExprConstF64(static_cast(val)); default: - return std::make_unique(int64{ 0 }, primType); + CHECK_FATAL(false, "unsupported const prime type"); + return nullptr; } } @@ -283,8 +302,8 @@ UniqueFEIRStmt FEIRBuilder::CreateStmtGoto(uint32 targetLabelIdx) { return stmt; } -UniqueFEIRStmt FEIRBuilder::CreateStmtGoto(std::string labelName) { - UniqueFEIRStmt stmt = std::make_unique(std::move(labelName)); +UniqueFEIRStmt FEIRBuilder::CreateStmtGoto(const std::string &labelName) { + UniqueFEIRStmt stmt = std::make_unique(labelName); CHECK_NULL_FATAL(stmt); return stmt; } @@ -392,6 +411,13 @@ UniqueFEIRStmt FEIRBuilder::CreateStmtArrayStoreOneStmt(UniqueFEIRVar varElem, U return stmt; } +UniqueFEIRStmt FEIRBuilder::CreateStmtArrayStoreOneStmtForC(UniqueFEIRExpr exprElem, UniqueFEIRExpr exprArray, + UniqueFEIRExpr exprIndex, UniqueFEIRType arrayType) { + UniqueFEIRStmt stmt = std::make_unique(std::move(exprElem), std::move(exprArray), + std::move(exprIndex), std::move(arrayType)); + return stmt; +} + std::list FEIRBuilder::CreateStmtArrayLoad(UniqueFEIRVar varElem, UniqueFEIRVar varArray, UniqueFEIRVar varIndex) { std::list ans; diff --git a/src/mplfe/common/src/feir_stmt.cpp b/src/mplfe/common/src/feir_stmt.cpp index 515288c0a51ea2d18c1c6eea5a69ec5271b4ec33..3712714a349f17895e478c88e294f8e64bcee3fc 100644 --- a/src/mplfe/common/src/feir_stmt.cpp +++ b/src/mplfe/common/src/feir_stmt.cpp @@ -774,7 +774,7 @@ std::pair FEIRStmtGoto2::GetLabelIdx() const { return std::make_pair(labelIdxOuter, labelIdxInner); } -FEIRStmtGotoForC::FEIRStmtGotoForC(std::string name) +FEIRStmtGotoForC::FEIRStmtGotoForC(const std::string &name) : FEIRStmt(FEIRNodeKind::kStmtGoto), labelName(name) {} @@ -933,7 +933,7 @@ FEIRStmtIf::FEIRStmtIf(UniqueFEIRExpr argCondExpr, std::list FEIRStmtIf::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { BaseNode *condBase = condExpr->GenMIRNode(mirBuilder); - IfStmtNode *stmt; + IfStmtNode *stmt = nullptr; if (hasElse) { stmt = mirBuilder.CreateStmtIfThenElse(condBase); } else { @@ -978,11 +978,12 @@ std::list FEIRStmtSwitchForC::GenMIRStmtsImpl(MIRBuilder &mirBuilder) std::list ans; MIRModule &module = mirBuilder.GetMirModule(); CaseVector *caseVec = module.CurFuncCodeMemPool()->New(module.CurFuncCodeMemPoolAllocator()->Adapter()); - AstSwitchUtil::BlockLabel allocateLabel = AstSwitchUtil::Instance().AllocateLoopOrSwitchLabels(mirBuilder); - AstSwitchUtil::Instance().MarkLabelUnUsed(allocateLabel.first); - AstSwitchUtil::Instance().MarkLabelUnUsed(allocateLabel.second); - LabelIdx swDefaultLabel = allocateLabel.first; // end label - AstSwitchUtil::Instance().PushNestedBreakLabels(allocateLabel.second); // exit label + std::string endName = AstSwitchUtil::Instance().CreateEndOrExitLabelName(); + std::string exitName = AstSwitchUtil::Instance().CreateEndOrExitLabelName(); + AstSwitchUtil::Instance().MarkLabelUnUsed(endName); + AstSwitchUtil::Instance().MarkLabelUnUsed(exitName); + LabelIdx swDefaultLabel = mirBuilder.GetOrCreateMIRLabel(endName); // end label + AstSwitchUtil::Instance().PushNestedBreakLabels(exitName); // exit label AstSwitchUtil::Instance().PushNestedCaseVectors(std::pair(caseVec, swDefaultLabel)); BaseNode *exprNode = expr->GenMIRNode(mirBuilder); CaseVector &switchTable = *AstSwitchUtil::Instance().GetTopOfNestedCaseVectors().first; @@ -994,6 +995,12 @@ std::list FEIRStmtSwitchForC::GenMIRStmtsImpl(MIRBuilder &mirBuilder) switchTable.push_back(std::make_pair(targetPair.first, targetPair.second->GetMIRLabelIdx())); } } + if (sub.get()->GetKind() == FEIRNodeKind::kStmtBreak) { + AstSwitchUtil::Instance().MarkLabelUsed(exitName); + auto feirStmtBreak = static_cast(sub.get()); + feirStmtBreak->SetSwitchLabelName(exitName); + feirStmtBreak->SetIsFromSwitch(true); + } } SwitchNode *mirSwitchStmt = mirBuilder.CreateStmtSwitch(exprNode, swDefaultLabel, switchTable); ans.push_back(mirSwitchStmt); @@ -1001,12 +1008,14 @@ std::list FEIRStmtSwitchForC::GenMIRStmtsImpl(MIRBuilder &mirBuilder) ans.splice(ans.end(), sub.get()->GenMIRStmts(mirBuilder)); } if (!hasDefault) { - StmtNode *mirSwExitLabelStmt = mirBuilder.CreateStmtLabel(allocateLabel.first); + LabelIdx endLab = mirBuilder.GetOrCreateMIRLabel(endName); + StmtNode *mirSwExitLabelStmt = mirBuilder.CreateStmtLabel(endLab); ans.push_back(mirSwExitLabelStmt); } - if (AstSwitchUtil::Instance().CheckLabelUsed(allocateLabel.second)) { - StmtNode *mirSwExitLabelStmt = mirBuilder.CreateStmtLabel(allocateLabel.second); + if (AstSwitchUtil::Instance().CheckLabelUsed(exitName)) { + LabelIdx exitLab = mirBuilder.GetOrCreateMIRLabel(exitName); + StmtNode *mirSwExitLabelStmt = mirBuilder.CreateStmtLabel(exitLab); ans.push_back(mirSwExitLabelStmt); } AstSwitchUtil::Instance().PopNestedBreakLabels(); @@ -1043,6 +1052,13 @@ std::list FEIRStmtCaseForC::GenMIRStmtsImpl(MIRBuilder &mirBuilder) c } for (auto &sub : subStmts) { + if (sub.get()->GetKind() == FEIRNodeKind::kStmtBreak) { + std::string switchBreakLabelName = AstSwitchUtil::Instance().GetTopOfBreakLabels(); + AstSwitchUtil::Instance().MarkLabelUsed(switchBreakLabelName); + auto feirStmtBreak = static_cast(sub.get()); + feirStmtBreak->SetSwitchLabelName(switchBreakLabelName); + feirStmtBreak->SetIsFromSwitch(true); + } ans.splice(ans.end(), sub.get()->GenMIRStmts(mirBuilder)); } return ans; @@ -1062,6 +1078,13 @@ std::list FEIRStmtDefaultForC::GenMIRStmtsImpl(MIRBuilder &mirBuilder StmtNode *mirLabelStmt = mirBuilder.CreateStmtLabel(AstSwitchUtil::Instance().GetTopOfNestedCaseVectors().second); ans.emplace_back(mirLabelStmt); for (auto &sub : subStmts) { + if (sub.get()->GetKind() == FEIRNodeKind::kStmtBreak) { + std::string switchBreakLabelName = AstSwitchUtil::Instance().GetTopOfBreakLabels(); + AstSwitchUtil::Instance().MarkLabelUsed(switchBreakLabelName); + auto feirStmtBreak = static_cast(sub.get()); + feirStmtBreak->SetSwitchLabelName(switchBreakLabelName); + feirStmtBreak->SetIsFromSwitch(true); + } ans.splice(ans.end(), sub.get()->GenMIRStmts(mirBuilder)); } return ans; @@ -1991,8 +2014,8 @@ std::unique_ptr FEIRExprIRead::CloneImpl() const { } BaseNode *FEIRExprIRead::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { - MIRType *returnType = retType->GenerateMIRTypeAuto(kSrcLangC); - MIRType *pointerType = ptrType->GenerateMIRTypeAuto(kSrcLangC); + MIRType *returnType = retType->GenerateMIRTypeAuto(); + MIRType *pointerType = ptrType->GenerateMIRTypeAuto(); BaseNode *node = subExpr->GenMIRNode(mirBuilder); CHECK_FATAL(pointerType->IsMIRPtrType(), "Must be ptr type!"); MIRPtrType *mirPtrType = static_cast(pointerType); @@ -2004,7 +2027,8 @@ BaseNode *FEIRExprIRead::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { fid = mirBuilder.GetStructFieldIDFromFieldName(*pointedMirType, fieldName); } MIRStructType *structMirType = static_cast(pointedMirType); - FieldPair fieldPair = structMirType->TraverseToFieldRef(fid); + FieldID id = fid; + FieldPair fieldPair = structMirType->TraverseToFieldRef(id); returnType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldPair.second.first); } else { CHECK_FATAL(fid == 0, "fieldid must be 0!"); @@ -2043,7 +2067,7 @@ std::unique_ptr FEIRExprAddrofVar::CloneImpl() const { } BaseNode *FEIRExprAddrofVar::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { - MIRSymbol *varSymbol = varSrc->GenerateGlobalMIRSymbol(mirBuilder); + MIRSymbol *varSymbol = varSrc->GenerateMIRSymbol(mirBuilder); return mirBuilder.CreateExprAddrof(0, *varSymbol); } @@ -2381,6 +2405,23 @@ void FEIRExprBinary::SetOpnd1(std::unique_ptr argOpnd) { opnd1 = std::move(argOpnd); } +bool FEIRExprBinary::IsComparative() const { + switch (op) { + case OP_cmp: + case OP_cmpl: + case OP_cmpg: + case OP_eq: + case OP_ge: + case OP_gt: + case OP_le: + case OP_lt: + case OP_ne: + return true; + default: + return false; + } +} + std::map FEIRExprBinary::InitFuncPtrMapForGenMIRNode() { std::map ans; ans[OP_add] = &FEIRExprBinary::GenMIRNodeNormal; @@ -2519,7 +2560,11 @@ void FEIRExprBinary::SetExprTypeByOpCompare() { (opnd0->GetKind() == kExprConst && static_cast(opnd0.get())->GetValue().u64 == 0) || (opnd1->GetKind() == kExprConst && static_cast(opnd1.get())->GetValue().u64 == 0), "primtype of opnds must be the same"); - type->SetPrimType(PTY_i32); + if (op == OP_cmp || op == OP_cmpl || op == OP_cmpg) { + type->SetPrimType(PTY_i32); + } else { + type->SetPrimType(PTY_u1); + } } // ---------- FEIRExprTernary ---------- @@ -2533,8 +2578,20 @@ FEIRExprTernary::FEIRExprTernary(Opcode argOp, std::unique_ptr argOpnd SetExprTypeByOp(); } +FEIRExprTernary::FEIRExprTernary(Opcode argOp, std::unique_ptr argType, std::unique_ptr argOpnd0, + std::unique_ptr argOpnd1, std::unique_ptr argOpnd2) + : FEIRExpr(FEIRNodeKind::kExprTernary, std::move(argType)), + op(argOp) { + SetOpnd(std::move(argOpnd0), 0); + SetOpnd(std::move(argOpnd1), 1); + SetOpnd(std::move(argOpnd2), 2); + PrimType primType = type->GetPrimType(); + CHECK_FATAL(primType == opnd1->GetPrimType(), "primtype of true opnd must be the same"); + CHECK_FATAL(primType == opnd2->GetPrimType(), "primtype of false opnd must be the same"); +} + std::unique_ptr FEIRExprTernary::CloneImpl() const { - std::unique_ptr expr = std::make_unique(op, opnd0->Clone(), opnd1->Clone(), + std::unique_ptr expr = std::make_unique(op, type->Clone(), opnd0->Clone(), opnd1->Clone(), opnd2->Clone()); return expr; } @@ -3043,7 +3100,10 @@ BaseNode *FEIRExprCStyleCast::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { } return true; }; - if (sub != nullptr && srcType != nullptr && destType != nullptr && isCvtNeeded(*srcType, *destType, *sub)) { + if (!isCvtNeeded(*srcType, *destType, *sub)) { + return sub; + } + if (sub != nullptr && srcType != nullptr && destType != nullptr) { PrimType fromType = srcType->GetPrimType(); PrimType toType = destType->GetPrimType(); if (fromType == toType || toType == PTY_void) { @@ -3063,7 +3123,7 @@ FEIRExprAtomic::FEIRExprAtomic(MIRType *ty, MIRType *ref, UniqueFEIRExpr obj, Un UniqueFEIRExpr val2, ASTAtomicOp atomOp) : FEIRExpr(FEIRNodeKind::kExprAtomic), - type(ty), + mirType(ty), refType(ref), objExpr(std::move(obj)), valExpr1(std::move(val1)), @@ -3071,15 +3131,15 @@ FEIRExprAtomic::FEIRExprAtomic(MIRType *ty, MIRType *ref, UniqueFEIRExpr obj, Un atomicOp(atomOp) {} std::unique_ptr FEIRExprAtomic::CloneImpl() const { - std::unique_ptr expr = std::make_unique(type, refType, objExpr->Clone(), + std::unique_ptr expr = std::make_unique(mirType, refType, objExpr->Clone(), valExpr1->Clone(), valExpr2->Clone(), atomicOp); return expr; } void FEIRExprAtomic::ProcessAtomicBinary(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, - MIRSymbol &valueVar, ASTAtomicOp atomicOp) const { + MIRSymbol &valueVar) const { BaseNode *constNode = valExpr1.get()->GenMIRNode(mirBuilder); - BaseNode *ireadNode = mirBuilder.CreateExprIread(*refType, *type, 0, &lockNode); + BaseNode *ireadNode = mirBuilder.CreateExprIread(*refType, *mirType, 0, &lockNode); BaseNode *valueNode = mirBuilder.CreateExprDread(valueVar); StmtNode *storeStmt = mirBuilder.CreateStmtDassign(valueVar, 0, ireadNode); block.AddStatement(storeStmt); @@ -3097,7 +3157,7 @@ void FEIRExprAtomic::ProcessAtomicBinary(MIRBuilder &mirBuilder, BlockNode &bloc } else { } BinaryNode *binNode = mirBuilder.CreateExprBinary(opcode, *val1Type, ireadNode, constNode); - StmtNode *addStmt = mirBuilder.CreateStmtIassign(*type, 0, &lockNode, binNode); + StmtNode *addStmt = mirBuilder.CreateStmtIassign(*mirType, 0, &lockNode, binNode); block.AddStatement(addStmt); if (kAtomicBinaryOpAdd <= atomicOp && atomicOp <= kAtomicBinaryOpXor) { BinaryNode *vbinNode = mirBuilder.CreateExprBinary(opcode, *val1Type, valueNode, constNode); @@ -3107,30 +3167,29 @@ void FEIRExprAtomic::ProcessAtomicBinary(MIRBuilder &mirBuilder, BlockNode &bloc } void FEIRExprAtomic::ProcessAtomicLoad(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, - MIRSymbol &valueVar) const { - BaseNode *ireadNode = mirBuilder.CreateExprIread(*refType, *type, 0, &lockNode); + const MIRSymbol &valueVar) const { + BaseNode *ireadNode = mirBuilder.CreateExprIread(*refType, *mirType, 0, &lockNode); StmtNode *loadStmt = mirBuilder.CreateStmtDassign(valueVar, 0, ireadNode); block.AddStatement(loadStmt); } -void FEIRExprAtomic::ProcessAtomicStore(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, - MIRSymbol &valueVar) const { +void FEIRExprAtomic::ProcessAtomicStore(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode) const { BaseNode *constNode = valExpr1.get()->GenMIRNode(mirBuilder); - StmtNode *storeStmt = mirBuilder.CreateStmtIassign(*type, 0, &lockNode, constNode); + StmtNode *storeStmt = mirBuilder.CreateStmtIassign(*mirType, 0, &lockNode, constNode); block.AddStatement(storeStmt); } void FEIRExprAtomic::ProcessAtomicExchange(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, - MIRSymbol &valueVar) const { - BaseNode *ireadNode = mirBuilder.CreateExprIread(*refType, *type, 0, &lockNode); + const MIRSymbol &valueVar) const { + BaseNode *ireadNode = mirBuilder.CreateExprIread(*refType, *mirType, 0, &lockNode); StmtNode *storeStmt = mirBuilder.CreateStmtDassign(valueVar, 0, ireadNode); block.AddStatement(storeStmt); BaseNode *constNode = valExpr1.get()->GenMIRNode(mirBuilder); - StmtNode *setStmt = mirBuilder.CreateStmtIassign(*type, 0, &lockNode, constNode); + StmtNode *setStmt = mirBuilder.CreateStmtIassign(*mirType, 0, &lockNode, constNode); block.AddStatement(setStmt); } void FEIRExprAtomic::ProcessAtomicCompareExchange(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, - MIRSymbol *valueVar) const { + const MIRSymbol *valueVar) const { #ifndef USE_OPS valueVar = SymbolBuilder::Instance().GetOrCreateLocalSymbol(*GlobalTables::GetTypeTable().GetUInt1(), FEUtils::GetSequentialName("valueVar"), @@ -3141,14 +3200,14 @@ void FEIRExprAtomic::ProcessAtomicCompareExchange(MIRBuilder &mirBuilder, BlockN #endif StmtNode *retStmt = mirBuilder.CreateStmtDassign(*valueVar, 0, mirBuilder.GetConstUInt1(false)); block.AddStatement(retStmt); - BaseNode *expectNode = mirBuilder.CreateExprIread(*refType, *type, 0, valExpr1.get()->GenMIRNode(mirBuilder)); + BaseNode *expectNode = mirBuilder.CreateExprIread(*refType, *mirType, 0, valExpr1.get()->GenMIRNode(mirBuilder)); BaseNode *desiredNode = valExpr2.get()->GenMIRNode(mirBuilder); - BaseNode *ireadNode = mirBuilder.CreateExprIread(*refType, *type, 0, &lockNode); + BaseNode *ireadNode = mirBuilder.CreateExprIread(*refType, *mirType, 0, &lockNode); BaseNode *cond = mirBuilder.CreateExprCompare(OP_eq, *(GlobalTables::GetTypeTable().GetUInt1()), *refType, expectNode, ireadNode); IfStmtNode *ifStmt = mirBuilder.CreateStmtIf(cond); block.AddStatement(ifStmt); - StmtNode *setStmt = mirBuilder.CreateStmtIassign(*type, 0, &lockNode, desiredNode); + StmtNode *setStmt = mirBuilder.CreateStmtIassign(*mirType, 0, &lockNode, desiredNode); ifStmt->GetThenPart()->AddStatement(setStmt); StmtNode *storeStmt = mirBuilder.CreateStmtDassign(*valueVar, 0, mirBuilder.GetConstUInt1(true)); ifStmt->GetThenPart()->AddStatement(storeStmt); @@ -3158,17 +3217,17 @@ BaseNode *FEIRExprAtomic::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { BlockNode *block = nullptr; BaseNode *objNode = objExpr.get()->GenMIRNode(mirBuilder); #ifndef USE_OPS - MIRSymbol *lockVar = SymbolBuilder::Instance().GetOrCreateLocalSymbol(*type, FEUtils::GetSequentialName("lockVar"), + MIRSymbol *lockVar = SymbolBuilder::Instance().GetOrCreateLocalSymbol(*mirType, FEUtils::GetSequentialName("lockVar"), *mirBuilder.GetCurrentFunction()); MIRSymbol *valueVar = SymbolBuilder::Instance().GetOrCreateLocalSymbol(*refType, FEUtils::GetSequentialName("valueVar"), *mirBuilder.GetCurrentFunction()); #else - MIRSymbol *lockVar = mirBuilder.GetOrCreateLocalDecl(FEUtils::GetSequentialName("lockVar").c_str(), *type); + MIRSymbol *lockVar = mirBuilder.GetOrCreateLocalDecl(FEUtils::GetSequentialName("lockVar").c_str(), *mirType); MIRSymbol *valueVar = mirBuilder.GetOrCreateLocalDecl(FEUtils::GetSequentialName("valueVar").c_str(), *refType); #endif BaseNode *lockNode = mirBuilder.CreateExprDread(*lockVar); - StmtNode *fetchStmt = mirBuilder.CreateStmtIassign(*type, 0, lockNode, objNode); + StmtNode *fetchStmt = mirBuilder.CreateStmtIassign(*mirType, 0, lockNode, objNode); ASSERT_NOT_NULL(fetchStmt); MIRModule &module = FEManager::GetModule(); block = module.CurFuncCodeMemPool()->New(); @@ -3181,7 +3240,7 @@ BaseNode *FEIRExprAtomic::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { case kAtomicBinaryOpAnd: case kAtomicBinaryOpOr: case kAtomicBinaryOpXor: { - ProcessAtomicBinary(mirBuilder, *block, *lockNode, *valueVar, atomicOp); + ProcessAtomicBinary(mirBuilder, *block, *lockNode, *valueVar); break; } case kAtomicOpLoad: { @@ -3189,7 +3248,7 @@ BaseNode *FEIRExprAtomic::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { break; } case kAtomicOpStore: { - ProcessAtomicStore(mirBuilder, *block, *lockNode, *valueVar); + ProcessAtomicStore(mirBuilder, *block, *lockNode); break; } case kAtomicOpExchange: { @@ -3443,7 +3502,7 @@ std::string FEIRStmtPesudoCommentForInst::DumpDotStringImpl() const { std::list FEIRStmtIAssign::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { std::list ans; - MIRType *mirType = addrType->GenerateMIRTypeAuto(kSrcLangC); + MIRType *mirType = addrType->GenerateMIRTypeAuto(); BaseNode *addrNode = addrExpr->GenMIRNode(mirBuilder); BaseNode *baseNode = baseExpr->GenMIRNode(mirBuilder); FieldID fid = fieldID; @@ -3466,35 +3525,19 @@ std::list FEIRStmtDoWhile::GenMIRStmtsImpl(MIRBuilder &mirBuilder) co BaseNode *mirCond = condExpr->GenMIRNode(mirBuilder); whileStmtNode->SetOpnd(mirCond, 0); auto *bodyBlock = mirBuilder.GetCurrentFuncCodeMp()->New(); - std::list breakFEIRStmts; - std::list continueFEIRStmts; - std::string loopBodyStartLabelName = FEUtils::GetSequentialName("dowhile_body_start_"); - std::string loopEndLabelName = FEUtils::GetSequentialName("dowhile_end_"); - for (auto &stmt : bodyStmts) { - if (stmt->GetKind() == FEIRNodeKind::kStmtBreak) { - auto feirStmtBreak = static_cast(stmt.get()); - feirStmtBreak->SetLabelName(loopEndLabelName); - } else if (stmt->GetKind() == FEIRNodeKind::kStmtContinue) { - auto feirStmtBreak = static_cast(stmt.get()); - feirStmtBreak->SetLabelName(loopBodyStartLabelName); - } - } for (auto &stmt : bodyStmts) { for (auto mirStmt : stmt->GenMIRStmts(mirBuilder)) { bodyBlock->AddStatement(mirStmt); } } - LabelIdx loopBodyStartLabelIdx = mirBuilder.GetOrCreateMIRLabel(loopBodyStartLabelName); - LabelIdx loopEndLabelIdx = mirBuilder.GetOrCreateMIRLabel(loopEndLabelName); - bodyBlock->InsertFirst(mirBuilder.CreateStmtLabel(loopBodyStartLabelIdx)); whileStmtNode->SetBody(bodyBlock); stmts.emplace_back(whileStmtNode); - stmts.emplace_back(mirBuilder.CreateStmtLabel(loopEndLabelIdx)); return stmts; } -std::list FEIRStmtBreak::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { - std::list stmts; +std::list FEIRStmtBreak::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { + std::list stmts; + std::string labelName = isFromSwitch ? switchLabelName : loopLabelName; CHECK_FATAL(!labelName.empty(), "labelName is null!"); LabelIdx labelIdx = mirBuilder.GetOrCreateMIRLabel(labelName); GotoNode *gotoNode = mirBuilder.CreateStmtGoto(OP_goto, labelIdx); @@ -3502,12 +3545,16 @@ std::list FEIRStmtBreak::GenMIRStmtsImpl(MIRBuilder &mirBuilder) con return stmts; } -std::list FEIRStmtContinue::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { - std::list stmts; +std::list FEIRStmtContinue::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { + std::list stmts; CHECK_FATAL(!labelName.empty(), "labelName is null!"); LabelIdx labelIdx = mirBuilder.GetOrCreateMIRLabel(labelName); GotoNode *gotoNode = mirBuilder.CreateStmtGoto(OP_goto, labelIdx); stmts.emplace_back(gotoNode); return stmts; } + +std::list FEIRStmtLabel::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { + return std::list{mirBuilder.CreateStmtLabel(mirBuilder.GetOrCreateMIRLabel(labelName))}; +} } // namespace maple diff --git a/src/mplfe/dex_input/include/dex_reader.h b/src/mplfe/dex_input/include/dex_reader.h index 6cb7fcda51a1db296e2c0f060b8591d1f2bdd615..b1e41334808cd3369561df8262fe037740d21b90 100644 --- a/src/mplfe/dex_input/include/dex_reader.h +++ b/src/mplfe/dex_input/include/dex_reader.h @@ -29,7 +29,6 @@ class DexReader : public BCReader { DexReader(uint32 fileIdxIn, const std::string &fileNameIn) : BCReader(fileNameIn), fileIdx(fileIdxIn) {} ~DexReader() = default; - bool OpenAndMap() override; void SetDexFile(std::unique_ptr dexFile); uint32 GetClassItemsSize() const; const char *GetClassJavaSourceFileName(uint32 classIdx) const; @@ -64,6 +63,9 @@ class DexReader : public BCReader { uint16 GetClassMethodRegisterInSize(const IDexMethodItem* dexMethodItem) const; uint32 GetCodeOff(const IDexMethodItem* dexMethodItem) const; + protected: + bool OpenAndMapImpl() override; + private: std::string GetStringFromIdxImpl(uint32 idx) const override; std::string GetTypeNameFromIdxImpl(uint32 idx) const override; diff --git a/src/mplfe/dex_input/src/dex_reader.cpp b/src/mplfe/dex_input/src/dex_reader.cpp index 1e05ec271e8931e2b83bb785102373b9dd7b810f..d484a9f6ec05443ba0847fa773e3170453482218 100644 --- a/src/mplfe/dex_input/src/dex_reader.cpp +++ b/src/mplfe/dex_input/src/dex_reader.cpp @@ -22,7 +22,7 @@ namespace maple { namespace bc { -bool DexReader::OpenAndMap() { +bool DexReader::OpenAndMapImpl() { DexFileFactory dexFileFactory; iDexFile = dexFileFactory.NewInstance(); bool openResult = iDexFile->Open(fileName); diff --git a/src/mplfe/jbc_input/src/jbc_class_const.cpp b/src/mplfe/jbc_input/src/jbc_class_const.cpp index 8dc5dd3839a590a9dcdba50793e3eec43970cea8..455c3054102bcb0042178960766a38f671108f42 100644 --- a/src/mplfe/jbc_input/src/jbc_class_const.cpp +++ b/src/mplfe/jbc_input/src/jbc_class_const.cpp @@ -45,7 +45,7 @@ std::string JBCConstTagName::GetTagName(JBCConstTag tag) { } // ---------- JBCConst ---------- -SimpleXMLElem *JBCConst::GenXMLElemImpl(MapleAllocator &alloc, uint32 id) const { +SimpleXMLElem *JBCConst::GenXMLElemImpl(MapleAllocator &allocIn, uint32 id) const { return nullptr; } diff --git a/src/mplfe/test/feir_builder_test.cpp b/src/mplfe/test/feir_builder_test.cpp index a4a4c6bd5c4f28f0b0b146304784d3a62a92e69c..ce7ddb9c27ac7de7f097fd1edc35d36229fcf996 100644 --- a/src/mplfe/test/feir_builder_test.cpp +++ b/src/mplfe/test/feir_builder_test.cpp @@ -33,6 +33,35 @@ class FEIRBuilderTest : public FEIRTestBase { virtual ~FEIRBuilderTest() = default; }; +// ---------- FEIRExprConst ---------- +TEST_F(FEIRBuilderTest, CreateExprConst_Any) { + RedirectCout(); + UniqueFEIRExpr expr1 = FEIRBuilder::CreateExprConstAnyScalar(PTY_i8, 127); + expr1->GenMIRNode(mirBuilder)->Dump(); + EXPECT_EQ(GetBufferString(), "constval i8 127\n"); + ClearBufferString(); + UniqueFEIRExpr expr2 = FEIRBuilder::CreateExprConstAnyScalar(PTY_i64, 127); + expr2->GenMIRNode(mirBuilder)->Dump(); + EXPECT_EQ(GetBufferString(), "constval i64 127\n"); + ClearBufferString(); + UniqueFEIRExpr expr3 = FEIRBuilder::CreateExprConstAnyScalar(PTY_f32, 127); + expr3->GenMIRNode(mirBuilder)->Dump(); + EXPECT_EQ(GetBufferString(), "constval f32 127f\n"); + ClearBufferString(); + UniqueFEIRExpr expr4 = FEIRBuilder::CreateExprConstAnyScalar(PTY_f64, 127); + expr4->GenMIRNode(mirBuilder)->Dump(); + EXPECT_EQ(GetBufferString(), "constval f64 127\n"); + ClearBufferString(); + UniqueFEIRExpr expr5 = FEIRBuilder::CreateExprConstAnyScalar(PTY_u8, -1); + expr5->GenMIRNode(mirBuilder)->Dump(); + EXPECT_EQ(GetBufferString(), "constval u8 255\n"); + ClearBufferString(); + UniqueFEIRExpr expr6 = FEIRBuilder::CreateExprConstAnyScalar(PTY_i8, -1); + expr6->GenMIRNode(mirBuilder)->Dump(); + EXPECT_EQ(GetBufferString(), "constval i8 -1\n"); + RestoreCout(); +} + // ---------- FEIRStmtDAssign ---------- TEST_F(FEIRBuilderTest, CreateExprDRead) { UniqueFEIRExpr expr = FEIRBuilder::CreateExprDRead(FEIRBuilder::CreateVarReg(0, PTY_i32));