diff --git a/src/mapleall/bin/dex2mpl b/src/mapleall/bin/dex2mpl index 85c8dc5d9f078ebcd85a80c5066121df18a98fd9..b71a9cc794138738aa9876ba8a7cf46ff4d64c82 100755 Binary files a/src/mapleall/bin/dex2mpl and b/src/mapleall/bin/dex2mpl differ diff --git a/src/mapleall/bin/dex2mpl_android b/src/mapleall/bin/dex2mpl_android index 45d9757b35beae3cdf0314d827b7dec13b410171..c82f201abf066f8fe2c36ed1b30877337cff6d8a 100755 Binary files a/src/mapleall/bin/dex2mpl_android and b/src/mapleall/bin/dex2mpl_android differ diff --git a/src/mapleall/bin/jbc2mpl b/src/mapleall/bin/jbc2mpl index c1e0b8225bb2efd214e5d44dc9a342de93aa60c8..7a6ea3ef59cc978a6ce8536241373cbce7d6e1e9 100755 Binary files a/src/mapleall/bin/jbc2mpl and b/src/mapleall/bin/jbc2mpl differ diff --git a/src/mapleall/maple_ipa/include/interleaved_manager.h b/src/mapleall/maple_ipa/include/interleaved_manager.h index 811849dd0caa5b245af9e0006efa84c63981cc3c..ac769833640e4626755f2410e00e23712a4f7063 100644 --- a/src/mapleall/maple_ipa/include/interleaved_manager.h +++ b/src/mapleall/maple_ipa/include/interleaved_manager.h @@ -67,6 +67,7 @@ class InterleavedManager { private: void InitSupportPhaseManagers(); void OptimizeFuncs(MeFuncPhaseManager &fpm, MapleVector &compList); + void OptimizeFuncsParallel(const MeFuncPhaseManager &fpm, MapleVector &compList, uint32 nThreads); MapleAllocator allocator; MIRModule &mirModule; diff --git a/src/mapleall/maple_ipa/include/module_phases.def b/src/mapleall/maple_ipa/include/module_phases.def index 2df3487eaf7f54436fa34ac0bb813ac7991675b1..35bcd8dd9e11933b185abb0305a0e35f5cce7b99 100644 --- a/src/mapleall/maple_ipa/include/module_phases.def +++ b/src/mapleall/maple_ipa/include/module_phases.def @@ -32,6 +32,7 @@ MODTPHASE(MoPhase_JAVAINTRNLOWERING, DoJavaIntrnLowering) MODTPHASE(MoPhase_BARRIERINSERTION, BarrierInsertion) MODTPHASE(MoPhase_JAVAEHLOWER, JavaEHLowererPhase) MODTPHASE(MoPhase_MUIDREPLACEMENT, DoMUIDReplacement) +MODTPHASE(MoPhase_PRECHECKCAST, DoPreCheckCast) MODTPHASE(MoPhase_CHECKCASTGENERATION, DoCheckCastGeneration) MODTPHASE(MoPhase_CodeReLayout, DoCodeReLayout) MODTPHASE(MoPhase_SCALARREPLACEMENT, DoScalarReplacement) diff --git a/src/mapleall/maple_ipa/src/interleaved_manager.cpp b/src/mapleall/maple_ipa/src/interleaved_manager.cpp index 0f335a7e718a318559bb1fd8f498d0c93817b31b..56b8bbcd8e7301d51ef523e235938c54bcc6dd1a 100644 --- a/src/mapleall/maple_ipa/src/interleaved_manager.cpp +++ b/src/mapleall/maple_ipa/src/interleaved_manager.cpp @@ -199,6 +199,28 @@ void InterleavedManager::OptimizeFuncs(MeFuncPhaseManager &fpm, MapleVector &compList, + uint32 nThreads) { + auto mainMpCtrler = std::make_unique(); + MemPool *mainMp = mainMpCtrler->NewMemPool("main thread mempool"); + MeFuncPhaseManager &fpmCopy = fpm.Clone(*mainMp, *mainMpCtrler); + auto funcOpt = std::make_unique(std::move(mainMpCtrler), fpmCopy); + MeFuncOptScheduler funcOptScheduler("me func opt", std::move(funcOpt)); + funcOptScheduler.Init(); + for (size_t i = 0; i < compList.size(); ++i) { + MIRFunction *func = compList[i]; + ASSERT_NOT_NULL(func); + // skip empty func, and skip the func out of range if `useRange` is true + if (func->GetBody() == nullptr || (MeOption::useRange && (i < MeOption::range[0] || i > MeOption::range[1]))) { + continue; + } + funcOptScheduler.AddFuncOptTask(mirModule, *func, i, meInput); + } + // lower, create BB and build cfg + ThreadEnv::SetMeParallel(true); + (void)funcOptScheduler.RunTask(nThreads, false); + ThreadEnv::SetMeParallel(false); +} void InterleavedManager::Run() { MPLTimer optTimer; @@ -236,7 +258,16 @@ void InterleavedManager::RunMeOptimize(MeFuncPhaseManager &fpm) { MPLTimer optTimer; optTimer.Start(); std::string logPrefix = mirModule.IsInIPA() ? "[ipa]" : "[me]"; - OptimizeFuncs(fpm, *compList); + uint32 nThreads = MeOption::threads; + bool enableMultithreading = (nThreads > 1); + if (enableMultithreading && !mirModule.IsInIPA()) { // parallel + MeOption::ignoreInferredRetType = true; // parallel optimization always ignore return type inferred by ssadevirt + LogInfo::MapleLogger() << logPrefix << " Parallel optimization (" << nThreads << " threads)\n"; + OptimizeFuncsParallel(fpm, *compList, nThreads); + } else { // serial + LogInfo::MapleLogger() << logPrefix << " Serial optimization\n"; + OptimizeFuncs(fpm, *compList); + } optTimer.Stop(); LogInfo::MapleLogger() << logPrefix << " Function phases cost " << optTimer.ElapsedMilliseconds() << "ms\n"; optTimer.Start(); diff --git a/src/mapleall/maple_ipa/src/ipa_option.cpp b/src/mapleall/maple_ipa/src/ipa_option.cpp index ada6efc5e28bd3d9046b0a9524cdbec8842b3f8a..822b38f562b9895135d64174d3d049bad4135f7e 100644 --- a/src/mapleall/maple_ipa/src/ipa_option.cpp +++ b/src/mapleall/maple_ipa/src/ipa_option.cpp @@ -140,6 +140,8 @@ bool IpaOption::SolveOptions(const mapleOption::OptionParser &optionParser) cons } bool IpaOption::ParseCmdline(int argc, char **argv, std::vector &fileNames) { + // Default value + MeOption::inlineFuncList = ""; OptionParser optionParser; optionParser.RegisteUsages(DriverOptionCommon::GetInstance()); optionParser.RegisteUsages(IpaOption::GetInstance()); diff --git a/src/mapleall/maple_ir/include/mir_type.h b/src/mapleall/maple_ir/include/mir_type.h index 1d382e26a28631c10dc20a0ab32718cebeebb92e..13c000477a45a3f54642f88795e24520003020af 100644 --- a/src/mapleall/maple_ir/include/mir_type.h +++ b/src/mapleall/maple_ir/include/mir_type.h @@ -51,8 +51,8 @@ inline uint32 GetPrimTypeBitSize(PrimType primType) { #endif // MIR_FEATURE_FULL // return the same type with size increased to register size PrimType GetRegPrimType(PrimType primType); -PrimType GetReg64PrimType(PrimType primType); PrimType GetDynType(PrimType primType); +PrimType GetReg64PrimType(PrimType primType); PrimType GetNonDynType(PrimType primType); inline bool IsAddress(PrimitiveType primitiveType) { diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 96ee881185b0337e8b9f51312fa9c8f664537189..26af5516b2fd3dcf96a7af95dfa83b13430586b9 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -173,7 +173,7 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { MIRAggConst *aggConst = mod.GetMemPool()->New(mod, *type); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { - auto fieldId = static_cast(ReadInt64()); + auto fieldId = static_cast(ReadNum()); auto fieldConst = ImportConst(func); aggConst->AddItem(fieldConst, fieldId); } diff --git a/src/mapleall/maple_ir/src/mir_symbol.cpp b/src/mapleall/maple_ir/src/mir_symbol.cpp index 35edfe7a4fdc24b1f482607652367cb537313bdc..c193d4edfe4ac7097a422f5de1187714a773ee11 100644 --- a/src/mapleall/maple_ir/src/mir_symbol.cpp +++ b/src/mapleall/maple_ir/src/mir_symbol.cpp @@ -387,7 +387,7 @@ void MIRSymbolTable::Dump(bool isLocal, int32 indent, bool printDeleted) const { if (!printDeleted && symbol->IsDeleted()) { continue; } - symbol->Dump(isLocal, indent, false/*suppressinit*/, this); + symbol->Dump(isLocal, indent, false /* suppressinit */, this); } } diff --git a/src/mapleall/maple_me/BUILD.gn b/src/mapleall/maple_me/BUILD.gn index af26501e5f11cf1788d494fd275215157497e8b4..05176512029a7d26e472125cbb155e253621909d 100755 --- a/src/mapleall/maple_me/BUILD.gn +++ b/src/mapleall/maple_me/BUILD.gn @@ -86,6 +86,7 @@ src_libmplme = [ "src/me_gc_lowering.cpp", "src/me_gc_write_barrier_opt.cpp", "src/me_subsum_rc.cpp", + "src/me_func_opt.cpp", "src/me_verify.cpp", ] diff --git a/src/mapleall/maple_me/include/orig_symbol.h b/src/mapleall/maple_me/include/orig_symbol.h index 3c34b86a173b8063e322089215b385e608e9f48d..c97d769ae4092adbc4eb683bbbd105fe9aeabaf8 100644 --- a/src/mapleall/maple_me/include/orig_symbol.h +++ b/src/mapleall/maple_me/include/orig_symbol.h @@ -121,7 +121,7 @@ class OriginalSt { return ostType == kPregOst && symOrPreg.pregIdx < 0; } - bool IsSameSymOrPreg(OriginalSt *ost) const { + bool IsSameSymOrPreg(const OriginalSt *ost) const { if (ostType != ost->ostType) { return false; } diff --git a/src/mapleall/maple_me/src/hdse.cpp b/src/mapleall/maple_me/src/hdse.cpp index a4b61a1bb2af0615813ba8cc64ac31ef8a33e18e..2e4b289c864a8ac496077d8dd034db5854b0a531 100644 --- a/src/mapleall/maple_me/src/hdse.cpp +++ b/src/mapleall/maple_me/src/hdse.cpp @@ -174,7 +174,7 @@ void HDSE::MarkRegDefByStmt(RegMeExpr ®MeExpr) { MarkPhiRequired(regMeExpr.GetDefPhi()); break; case kDefByChi: { - ASSERT(regMeExpr.GetOst()->GetIndirectLev() > 0, + ASSERT(regMeExpr.GetOst()->GetIndirectLev() > 0, "MarkRegDefByStmt: preg cannot be defined by chi"); auto *defChi = ®MeExpr.GetDefChi(); if (defChi != nullptr) { @@ -439,7 +439,7 @@ void HDSE::MarkSingleUseLive(MeExpr &meExpr) { MapleMap *chiList = GenericGetChiListFromVarMeExpr(*mu); if (chiList != nullptr) { MapleMap::iterator it = chiList->begin(); - for (; it != chiList->end(); it++) { + for (; it != chiList->end(); ++it) { MarkChiNodeRequired(*it->second); } } diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index 752c0aa6429ae7301791028d646e10f7e87722f6..1342d1a3558beba480f8e763b575ff059561c05f 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -92,6 +92,15 @@ void MeFuncPhaseManager::RunFuncPhase(MeFunction *func, MeFuncPhase *phase) { phase->ClearMemPoolsExcept(analysisRes == nullptr ? nullptr : analysisRes->GetMempool()); phase->ClearString(); } +#ifdef DEBUG_TIMER + constexpr float kMillion = 1000000.0; + timer.Stop(); + LogInfo::MapleLogger() << " Phase " << phase->PhaseName() << " function " << func->mirfunc->GetName() << " takes " + << (timer.ElapsedMicroseconds() / kMillion) << " seconds\b" << '\n'; + if (!strcmp(phase->PhaseName(), "hdse")) { + LogInfo::MapleLogger() << '\n'; + } +#endif if (analysisRes != nullptr) { // if phase is an analysis Phase, add result to arm arFuncManager.AddResult(phase->GetPhaseId(), *func, *analysisRes); @@ -132,12 +141,47 @@ void MeFuncPhaseManager::AddPhases(const std::unordered_set &skipPh PhaseManager::AddPhase(phase); } }; + bool o2 = (MeOption::optLevel == 2); if (mePhaseType == kMePhaseMainopt) { // default phase sequence + if (o2) { + addPhase("loopcanon"); + addPhase("splitcriticaledge"); + } addPhase("ssatab"); addPhase("aliasclass"); addPhase("ssa"); - addPhase("rclowering"); + addPhase("dse"); + addPhase("hprop"); + addPhase("hdse"); + if (JAVALANG) { + addPhase("may2dassign"); + addPhase("condbasednpc"); + addPhase("checkcastopt"); + } + if (JAVALANG && !MeOption::noRC) { + addPhase("placementrc"); + } + if (JAVALANG && o2 && MeOption::lazyDecouple) { + addPhase("lazydecouple"); + } + if (o2) { + addPhase("epre"); + if (JAVALANG) { + addPhase("stmtpre"); + } + } + if (JAVALANG && !MeOption::noRC) { + addPhase("analyzerc"); + if (MeOption::rcLowering) { + addPhase("rclowering"); + } + } + addPhase("rename2preg"); + if (o2) { + addPhase("lpre"); + addPhase("pregrename"); + } addPhase("bblayout"); addPhase("emit"); addPhase("meverify"); @@ -203,17 +247,41 @@ void MeFuncPhaseManager::Run(MIRFunction *mirFunc, uint64 rangeNum, const std::s } PhaseID id = GetPhaseId(it); auto *p = static_cast(GetPhase(id)); + if (MeOption::skipFrom.compare(p->PhaseName()) == 0) { + // fast-forward to emit pass, which is last pass + while (++it != PhaseSequenceEnd()) { } + --it; // restore iterator + id = GetPhaseId(it); + p = static_cast(GetPhase(id)); + } p->SetPreviousPhaseName(phaseName); // prev phase name is for filename used in emission after phase phaseName = p->PhaseName(); // new phase name bool dumpPhase = MeOption::DumpPhase(phaseName); + if (MeOption::dumpBefore && dumpFunc && dumpPhase) { + LogInfo::MapleLogger() << ">>>>> Dump before " << phaseName << " <<<<<\n"; + if (phaseName != "emit") { + func.Dump(false); + } else { + func.DumpFunctionNoSSA(); + } + LogInfo::MapleLogger() << ">>>>> Dump before End <<<<<\n"; + } RunFuncPhase(&func, p); if ((MeOption::dumpAfter || dumpPhase) && dumpFunc) { LogInfo::MapleLogger() << ">>>>> Dump after " << phaseName << " <<<<<\n"; if (phaseName != "emit") { func.Dump(false); + } else { + func.DumpFunctionNoSSA(); } LogInfo::MapleLogger() << ">>>>> Dump after End <<<<<\n\n"; } + if (MeOption::skipAfter.compare(phaseName) == 0) { + // fast-forward to emit pass, which is last pass + while (++it != PhaseSequenceEnd()) { } + --it; + --it; // restore iterator to emit + } if (p->IsChangedCFG()) { changeCFGPhase = p; p->ClearChangeCFG(); @@ -263,17 +331,41 @@ void MeFuncPhaseManager::Run(MIRFunction *mirFunc, uint64 rangeNum, const std::s if (p == changeCFGPhase) { continue; } + if (MeOption::skipFrom.compare(p->PhaseName()) == 0) { + // fast-forward to emit pass, which is last pass + while (++it != PhaseSequenceEnd()) { } + --it; // restore iterator + id = GetPhaseId(it); + p = static_cast(GetPhase(id)); + } p->SetPreviousPhaseName(phaseName); // prev phase name is for filename used in emission after phase phaseName = p->PhaseName(); // new phase name bool dumpPhase = MeOption::DumpPhase(phaseName); + if (MeOption::dumpBefore && dumpFunc && dumpPhase) { + LogInfo::MapleLogger() << ">>>>>Second time Dump before " << phaseName << " <<<<<\n"; + if (phaseName != "emit") { + function.Dump(false); + } else { + function.DumpFunctionNoSSA(); + } + LogInfo::MapleLogger() << ">>>>> Second time Dump before End <<<<<\n"; + } RunFuncPhase(&function, p); if ((MeOption::dumpAfter || dumpPhase) && dumpFunc) { LogInfo::MapleLogger() << ">>>>>Second time Dump after " << phaseName << " <<<<<\n"; if (phaseName != "emit") { function.Dump(false); + } else { + function.DumpFunctionNoSSA(); } LogInfo::MapleLogger() << ">>>>> Second time Dump after End <<<<<\n\n"; } + if (MeOption::skipAfter.compare(phaseName) == 0) { + // fast-forward to emit pass, which is last pass + while (++it != PhaseSequenceEnd()) { } + --it; + --it; // restore iterator to emit + } if (timePhases) { runPhasetimer.Stop(); phaseTimers[phaseIndex] += runPhasetimer.ElapsedMicroseconds(); diff --git a/src/mapleall/maple_phase/include/phase_impl.h b/src/mapleall/maple_phase/include/phase_impl.h index 094f183155a955b041d6433061d68f7cb438a337..5bed971bd8189b705dab91d2cc42fdfac7766150 100644 --- a/src/mapleall/maple_phase/include/phase_impl.h +++ b/src/mapleall/maple_phase/include/phase_impl.h @@ -34,6 +34,7 @@ class FuncOptimizeImpl : public MplTaskParam { return *module; } + virtual void CreateLocalBuilder(pthread_mutex_t &mtx); virtual void ProcessFunc(MIRFunction *func); virtual void Finish() {} @@ -41,6 +42,7 @@ class FuncOptimizeImpl : public MplTaskParam { void SetCurrentFunction(MIRFunction &func) { currFunc = &func; ASSERT(builder != nullptr, "builder is null in FuncOptimizeImpl::SetCurrentFunction"); + builder->SetCurrentFunction(func); module->SetCurFunction(&func); } @@ -50,21 +52,66 @@ class FuncOptimizeImpl : public MplTaskParam { KlassHierarchy *klassHierarchy = nullptr; MIRFunction *currFunc = nullptr; - MIRBuilder *builder = nullptr; + MIRBuilderExt *builder = nullptr; bool trace = false; private: MIRModule *module = nullptr; }; -class FuncOptimizeIterator { +class FuncOptimizeIterator : public MplScheduler { public: + class Task : public MplTask { + public: + explicit Task(MIRFunction &func) : function(&func) {} + + ~Task() = default; + + protected: + int RunImpl(MplTaskParam *param) override { + auto &impl = static_cast(utils::ToRef(param)); + impl.ProcessFunc(function); + return 0; + } + + int FinishImpl(MplTaskParam*) override { + return 0; + } + + private: + MIRFunction *function; + }; + FuncOptimizeIterator(const std::string &phaseName, std::unique_ptr phaseImpl); virtual ~FuncOptimizeIterator(); - virtual void Run(); + virtual void Run(uint32 threadNum = 1, bool isSeq = false); protected: + thread_local static FuncOptimizeImpl *phaseImplLocal; + void RunSerial(); + void RunParallel(uint32 threadNum, bool isSeq = false); + virtual MplTaskParam *CallbackGetTaskRunParam() const { + return phaseImplLocal; + } + + virtual MplTaskParam *CallbackGetTaskFinishParam() const { + return phaseImplLocal; + } + + virtual void CallbackThreadMainStart() { + phaseImplLocal = phaseImpl->Clone(); + utils::ToRef(phaseImplLocal).CreateLocalBuilder(mutexGlobal); + } + + virtual void CallbackThreadMainEnd() { + delete phaseImplLocal; + phaseImplLocal = nullptr; + } + + private: + bool mplDumpTime = false; std::unique_ptr phaseImpl; + std::vector> tasksUniquePtr; }; #define OPT_TEMPLATE(OPT_NAME) \ @@ -73,6 +120,7 @@ class FuncOptimizeIterator { std::unique_ptr funcOptImpl = std::make_unique(*mod, kh, TRACE_PHASE); \ ASSERT_NOT_NULL(funcOptImpl); \ FuncOptimizeIterator opt(PhaseName(), std::move(funcOptImpl)); \ + opt.Init(); \ opt.Run(); } // namespace maple #endif // MAPLE_PHASE_INCLUDE_PHASE_IMPL_H diff --git a/src/mapleall/maple_phase/src/phase_impl.cpp b/src/mapleall/maple_phase/src/phase_impl.cpp index ec21c7033abf6600fc4defb4bb900b793c938efe..013f95560a7059b34db1dca46274b0f5c302513a 100644 --- a/src/mapleall/maple_phase/src/phase_impl.cpp +++ b/src/mapleall/maple_phase/src/phase_impl.cpp @@ -20,15 +20,25 @@ namespace maple { // ========== FuncOptimizeImpl ========== FuncOptimizeImpl::FuncOptimizeImpl(MIRModule &mod, KlassHierarchy *kh, bool currTrace) : klassHierarchy(kh), trace(currTrace), module(&mod) { - builder = module->GetMIRBuilder(); + builder = new (std::nothrow) MIRBuilderExt(module); + ASSERT_NOT_NULL(builder); } FuncOptimizeImpl::~FuncOptimizeImpl() { + if (builder != nullptr) { + delete builder; + builder = nullptr; + } klassHierarchy = nullptr; currFunc = nullptr; module = nullptr; } +void FuncOptimizeImpl::CreateLocalBuilder(pthread_mutex_t &mtx) { + // Each thread needs to use its own MIRBuilderExt. + builder = new (std::nothrow) MIRBuilderExt(module, &mtx); + ASSERT_NOT_NULL(builder); +} void FuncOptimizeImpl::ProcessFunc(MIRFunction *func) { currFunc = func; @@ -70,16 +80,89 @@ void FuncOptimizeImpl::ProcessBlock(StmtNode &stmt) { } } +// ========== FuncOptimizeIterator ========== +thread_local FuncOptimizeImpl *FuncOptimizeIterator::phaseImplLocal = nullptr; + FuncOptimizeIterator::FuncOptimizeIterator(const std::string &phaseName, std::unique_ptr phaseImpl) - : phaseImpl(std::move(phaseImpl)) {} + : MplScheduler(phaseName), phaseImpl(std::move(phaseImpl)) { + char *envStr = getenv("MP_DUMPTIME"); + mplDumpTime = (envStr != nullptr && atoi(envStr) == 1); +} FuncOptimizeIterator::~FuncOptimizeIterator() = default; -void FuncOptimizeIterator::Run() { +void FuncOptimizeIterator::Run(uint32 threadNum, bool isSeq) { + if (threadNum == 1) { + RunSerial(); + } else { + RunParallel(threadNum, isSeq); + } +} + +void FuncOptimizeIterator::RunSerial() { + MPLTimer timer; + if (mplDumpTime) { + timer.Start(); + } + CHECK_NULL_FATAL(phaseImpl); for (MIRFunction *func : phaseImpl->GetMIRModule().GetFunctionList()) { + auto dumpPhase = [func](bool dump, std::string &&s, std::string &name) { + if (dump && + (Options::dumpFunc == "*" || func->GetName().find(Options::dumpFunc) != std::string::npos) && + (Options::dumpPhase == name || Options::dumpPhase == "*")) { + LogInfo::MapleLogger() << ">>>>> Dump " << s << name << " <<<<<\n"; + func->Dump(); + LogInfo::MapleLogger() << ">>>>> Dump " << s << name << " end <<<<<\n"; + } + }; + + dumpPhase(Options::dumpBefore, "before ", schedulerName); phaseImpl->ProcessFunc(func); + dumpPhase(Options::dumpAfter, "after ", schedulerName); + } + + phaseImpl->Finish(); + + if (mplDumpTime) { + timer.Stop(); + INFO(kLncInfo, "FuncOptimizeIterator::RunSerial (%s): %lf ms", schedulerName.c_str(), + timer.ElapsedMicroseconds() / 1000.0); + } +} + +void FuncOptimizeIterator::RunParallel(uint32 threadNum, bool isSeq) { + MPLTimer timer; + if (mplDumpTime) { + timer.Start(); + } + Reset(); + + CHECK_NULL_FATAL(phaseImpl); + for (MIRFunction *func : phaseImpl->GetMIRModule().GetFunctionList()) { + std::unique_ptr task = std::make_unique(*func); + ASSERT_NOT_NULL(task); + AddTask(task.get()); + tasksUniquePtr.emplace_back(std::move(task)); + } + + if (mplDumpTime) { + timer.Stop(); + INFO(kLncInfo, "FuncOptimizeIterator::RunParallel (%s): AddTask() = %lf ms", schedulerName.c_str(), + timer.ElapsedMicroseconds() / 1000.0); + + timer.Start(); } + + int ret = RunTask(threadNum, isSeq); + CHECK_FATAL(ret == 0, "RunTask failed"); phaseImpl->Finish(); + Reset(); + + if (mplDumpTime) { + timer.Stop(); + INFO(kLncInfo, "FuncOptimizeIterator::RunParallel (%s): RunTask() = %lf ms", schedulerName.c_str(), + timer.ElapsedMicroseconds() / 1000.0); + } } } // namespace maple diff --git a/src/mapleall/maple_util/include/factory.h b/src/mapleall/maple_util/include/factory.h index fe97390af3a5ecbcf1d139f2360d1de812344ac9..9487fe2b7b21dd8d04a9f2d4f6e2ce67ed9892a9 100644 --- a/src/mapleall/maple_util/include/factory.h +++ b/src/mapleall/maple_util/include/factory.h @@ -87,6 +87,8 @@ class FunctionFactory final { } creator_type Create(const key_type &key) const { + static std::mutex mtx; + ParallelGuard guard(mtx, ThreadEnv::IsMeParallel()); auto it = creator.find(key); return it == creator.end() ? nullptr : it->second; } diff --git a/src/mapleall/maple_util/src/profile.cpp b/src/mapleall/maple_util/src/profile.cpp index aa653705ae3def879f4399a0077557df37676df7..64481835308f001f5fbcba061e9f364dac54b055 100644 --- a/src/mapleall/maple_util/src/profile.cpp +++ b/src/mapleall/maple_util/src/profile.cpp @@ -45,12 +45,10 @@ const std::string Profile::preClassHot[] = { "Ljava/lang/String;" }; -#ifndef HUAWEI_EXTERNAL_RELEASE_JBC const std::string Profile::preMethodHot[] = { "Landroid/util/ContainerHelpers;", "Landroid/util/SparseArray;" }; -#endif Profile::Profile() {} @@ -255,7 +253,6 @@ void Profile::ParseReflectionStr(const char *data, int32 fileNum) { } void Profile::InitPreHot() { -#ifndef HUAWEI_EXTERNAL_RELEASE_JBC std::string frameworkDexName = "framework"; std::string coreDexName = "core-all"; if (dexName.find(frameworkDexName) != std::string::npos) { @@ -268,7 +265,6 @@ void Profile::InitPreHot() { } isCoreSo = true; } -#endif } bool Profile::DeCompress(const std::string &path, const std::string &dexNameInner, ProfileType type) { diff --git a/src/mplfe/ast_input/include/ast_decl.h b/src/mplfe/ast_input/include/ast_decl.h index 9c1374d3978a7270af7bf19ce2c7b84d79ba042d..d6dc8073b90dc331be866af2df877e778b0e96b3 100644 --- a/src/mplfe/ast_input/include/ast_decl.h +++ b/src/mplfe/ast_input/include/ast_decl.h @@ -135,6 +135,8 @@ class ASTVar : public ASTDecl { return initExpr; } + std::unique_ptr Translate2FEIRVar(); + private: ASTExpr *initExpr = nullptr; }; diff --git a/src/mplfe/ast_input/include/ast_decl_builder.h b/src/mplfe/ast_input/include/ast_decl_builder.h index 4fb2d3733d0c4ecf9a86bbcc94e6e81d26e66c53..006828b6eb6adc93ddb1d7ded81949f68ceb6562 100644 --- a/src/mplfe/ast_input/include/ast_decl_builder.h +++ b/src/mplfe/ast_input/include/ast_decl_builder.h @@ -18,40 +18,43 @@ #include "mempool_allocator.h" namespace maple { -ASTDecl *ASTDeclBuilder(MapleAllocator &allocator, const std::string &srcFile, - const std::string &nameIn, const std::vector &typeDescIn) { - return allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn); -} +class ASTDeclsBuilder { + public: + static ASTDecl *ASTDeclBuilder(MapleAllocator &allocator, const std::string &srcFile, + const std::string &nameIn, const std::vector &typeDescIn) { + return allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn); + } -ASTVar *ASTVarBuilder(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 ASTVar *ASTVarBuilder(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); + } -ASTFunc *ASTFuncBuilder(MapleAllocator &allocator, const std::string &srcFile, const std::string &nameIn, - const std::vector &typeDescIn, const GenericAttrs &genAttrsIn, - const std::vector &parmNamesIn) { - return allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn, genAttrsIn, parmNamesIn); -} + static ASTFunc *ASTFuncBuilder(MapleAllocator &allocator, const std::string &srcFile, const std::string &nameIn, + const std::vector &typeDescIn, const GenericAttrs &genAttrsIn, + const std::vector &parmNamesIn) { + return allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn, genAttrsIn, parmNamesIn); + } -template -T *ASTStmtBuilder(MapleAllocator &allocator) { - return allocator.GetMemPool()->New(); -} + template + static T *ASTStmtBuilder(MapleAllocator &allocator) { + return allocator.GetMemPool()->New(); + } -template -T *ASTExprBuilder(MapleAllocator &allocator) { - return allocator.GetMemPool()->New(); -} + template + static T *ASTExprBuilder(MapleAllocator &allocator) { + return allocator.GetMemPool()->New(); + } -ASTStruct *ASTStructBuilder(MapleAllocator &allocator, const std::string &srcFile, const std::string &nameIn, - const std::vector &typeDescIn, const GenericAttrs &genAttrsIn) { - return allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn, genAttrsIn); -} + static ASTStruct *ASTStructBuilder(MapleAllocator &allocator, const std::string &srcFile, const std::string &nameIn, + const std::vector &typeDescIn, const GenericAttrs &genAttrsIn) { + return allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn, genAttrsIn); + } -ASTField *ASTFieldBuilder(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 ASTField *ASTFieldBuilder(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); + } +}; } // namespace maple #endif // MPLFE_AST_INPUT_INCLUDE_AST_DECL_BUILDER_H diff --git a/src/mplfe/ast_input/include/ast_expr.h b/src/mplfe/ast_input/include/ast_expr.h index 93962d1d93558c6ba615b7dbad0cccbd7b2c7331..6942383f0a6fb3ddeb8283652fcbc0a0e95cf21e 100644 --- a/src/mplfe/ast_input/include/ast_expr.h +++ b/src/mplfe/ast_input/include/ast_expr.h @@ -25,6 +25,14 @@ class ASTExpr { virtual ~ASTExpr() = default; UniqueFEIRExpr Emit2FEExpr(std::list &stmts) const; + virtual MIRType *GetType() { + return mirType; + } + + void SetType(MIRType *type) { + mirType = type; + } + ASTOp GetASTOp() { return op; } @@ -32,6 +40,7 @@ class ASTExpr { protected: virtual UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const = 0; ASTOp op; + MIRType *mirType; }; class ASTImplicitCastExpr : public ASTExpr { @@ -47,6 +56,10 @@ class ASTImplicitCastExpr : public ASTExpr { return child; } + MIRType *GetType() override { + return child->GetType(); + } + protected: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; ASTExpr *child = nullptr; @@ -101,7 +114,16 @@ class ASTUnaryOperatorExpr : public ASTExpr { return pointeeLen; } + void SetGlobal(bool isGlobalArg) { + isGlobal = isGlobalArg; + } + + bool IsGlobal() { + return isGlobal; + } + protected: + bool isGlobal = false; ASTExpr *expr = nullptr; MIRType *subType; MIRType *uoType; @@ -325,24 +347,32 @@ class ASTBinaryConditionalOperator : public ASTExpr { class ASTBinaryOperatorExpr : public ASTExpr { public: explicit ASTBinaryOperatorExpr(ASTOp o) : ASTExpr(o) {} + ASTBinaryOperatorExpr() : ASTExpr(kASTOpBO) {} + ~ASTBinaryOperatorExpr() override = default; void SetRetType(MIRType *type) { retType = type; } - void SetLeftExpr(ASTExpr *leftExpr) { - left = leftExpr; + void SetLeftExpr(ASTExpr *expr) { + leftExpr = expr; } - void SetRightExpr(ASTExpr *rightExpr) { - right = rightExpr; + void SetRightExpr(ASTExpr *expr) { + rightExpr = expr; + } + + void SetOpcode(Opcode op) { + opcode = op; } protected: + UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; + Opcode opcode; MIRType *retType; - ASTExpr *left = nullptr; - ASTExpr *right = nullptr; + ASTExpr *leftExpr = nullptr; + ASTExpr *rightExpr = nullptr; }; class ASTImplicitValueInitExpr : public ASTExpr { @@ -368,7 +398,7 @@ class ASTStringLiteral : public ASTExpr { type = srcType; } - MIRType *GetType() const { + MIRType *GetType() override { return type; } @@ -447,6 +477,14 @@ class ASTMemberExpr : public ASTExpr { memberName = std::move(name); } + void SetMemberType(MIRType *type) { + memberType = type; + } + + void SetBaseType(MIRType *type) { + baseType = type; + } + void SetIsArrow(bool arrow) { isArrow = arrow; } @@ -455,6 +493,8 @@ class ASTMemberExpr : public ASTExpr { UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; ASTExpr *baseExpr; std::string memberName; + MIRType *memberType; + MIRType *baseType; bool isArrow; }; @@ -477,6 +517,15 @@ class ASTDesignatedInitUpdateExpr : public ASTExpr { 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) {} @@ -648,11 +697,15 @@ class ASTBOEqExpr : public ASTBinaryOperatorExpr { UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; }; -class ASTBOAssign : public ASTBinaryOperatorExpr { +class ASTAssignExpr : public ASTBinaryOperatorExpr { public: - ASTBOAssign() : ASTBinaryOperatorExpr(kASTOpAssign) {} - ASTBOAssign(ASTOp o) : ASTBinaryOperatorExpr(o) {} - ~ASTBOAssign() override = default; + ASTAssignExpr() : ASTBinaryOperatorExpr(kASTOpAssign) {} + ASTAssignExpr(ASTOp o) : ASTBinaryOperatorExpr(o) {} + ~ASTAssignExpr() override = default; + + protected: + UniqueFEIRExpr ProcessAssign(std::list &stmts, UniqueFEIRExpr leftExpr, + UniqueFEIRExpr rightExpr) const; private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; @@ -667,19 +720,10 @@ class ASTBOComma : public ASTBinaryOperatorExpr { UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; }; -class ASTBOPtrMemD : public ASTBinaryOperatorExpr { - public: - ASTBOPtrMemD() : ASTBinaryOperatorExpr(kASTOpPtrMemD) {} - ~ASTBOPtrMemD() override = default; - - private: - UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; -}; - -class ASTBOPtrMemI : public ASTBinaryOperatorExpr { +class ASTBOPtrMemExpr : public ASTBinaryOperatorExpr { public: - ASTBOPtrMemI() : ASTBinaryOperatorExpr(kASTOpPtrMemI) {} - ~ASTBOPtrMemI() override = default; + ASTBOPtrMemExpr() : ASTBinaryOperatorExpr(kASTOpPtrMemD) {} + ~ASTBOPtrMemExpr() override = default; private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; @@ -827,16 +871,20 @@ class ASTVAArgExpr : public ASTExpr { UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; }; -class ASTCompoundAssignOperatorExpr : public ASTBinaryOperatorExpr { +class ASTCompoundAssignOperatorExpr : public ASTAssignExpr { public: - ASTCompoundAssignOperatorExpr() : ASTBinaryOperatorExpr(kCpdAssignOp) {} + ASTCompoundAssignOperatorExpr() : ASTAssignExpr(kASTOpCompoundAssign) {} ~ASTCompoundAssignOperatorExpr() override = default; + void SetOpForCompoundAssign(Opcode opcode){ + opForCompoundAssign = opcode; + } + protected: + Opcode opForCompoundAssign; UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; }; - class ASTConstantExpr : public ASTExpr { public: ASTConstantExpr() : ASTExpr(kConstantExpr) {} @@ -922,11 +970,25 @@ class ASTCStyleCastExpr : public ASTExpr { return destType; } + void SetCanCastArray(bool shouldCastArr) { + canCastArray = shouldCastArr; + } + + bool CanCastArray() const { + return canCastArray; + } + + void SetDecl(ASTDecl *d) { + decl = d; + } + private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; ASTExpr *child = nullptr; - MIRType *srcType; - MIRType *destType; + MIRType *srcType = nullptr; + MIRType *destType = nullptr; + bool canCastArray = false; + ASTDecl *decl = nullptr; }; class ASTArrayInitLoopExpr : public ASTExpr { @@ -1036,7 +1098,7 @@ class ASTAtomicExpr : public ASTExpr { atomicOp = op; } - MIRType *GetType() const { + MIRType *GetType() override { return type; } @@ -1048,10 +1110,47 @@ class ASTAtomicExpr : public ASTExpr { return atomicOp; } + void SetValExpr1(ASTExpr *val) { + valExpr1 = val; + } + + void SetValExpr2(ASTExpr *val) { + valExpr2 = val; + } + + void SetObjExpr(ASTExpr *obj) { + objExpr = obj; + } + + ASTExpr *GetValExpr1() const { + return valExpr1; + } + + ASTExpr *GetValExpr2() const { + return valExpr2; + } + + ASTExpr *GetObjExpr() const { + return objExpr; + } + + void SetVal1Type(MIRType *ty) { + val1Type = ty; + } + + void SetVal2Type(MIRType *ty) { + val2Type = ty; + } + private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; - MIRType *type; - MIRType *refType; + MIRType *type = nullptr; + MIRType *refType = nullptr; + MIRType *val1Type = nullptr; + MIRType *val2Type = nullptr; + ASTExpr *objExpr = nullptr; + ASTExpr *valExpr1 = nullptr; + ASTExpr *valExpr2 = nullptr; ASTAtomicOp atomicOp; }; } diff --git a/src/mplfe/ast_input/include/ast_op.h b/src/mplfe/ast_input/include/ast_op.h index 20bf210b9dbf5fc47d84b8665161cfd084ec9cd5..cbf71db489898a1c582e38bfa703befecc6c0d81 100644 --- a/src/mplfe/ast_input/include/ast_op.h +++ b/src/mplfe/ast_input/include/ast_op.h @@ -43,6 +43,8 @@ enum ASTOp { // BinaryOperators // [C++ 5.5] Pointer-to-member operators. + kASTOpBO, + kASTOpCompoundAssign, kASTOpPtrMemD, kASTOpPtrMemI, // [C99 6.5.5] Multiplicative operators. @@ -136,6 +138,8 @@ enum ASTStmtOp { kASTStmtReturn, kASTStmtBO, + kASTStmtBOAssign, + kASTStmtBOCompoundAssign, kASTStmtUO, kASTStmtCompound, kASTStmtSwitch, @@ -154,18 +158,5 @@ enum ASTStmtOp { kASTStmtCStyleCastExpr, kASTStmtCallExpr, }; - -enum ASTAtomicOp { - kAtomicBinaryOpAdd, - kAtomicBinaryOpSub, - kAtomicBinaryOpAnd, - kAtomicBinaryOpOr, - kAtomicBinaryOpXor, - kAtomicOpLoad, - kAtomicOpStore, - kAtomicOpExchange, - kAtomicOpCompareExchange, - kAtomicOpLast, -}; } // namespace maple #endif // MPLFE_AST_INPUT_INCLUDE_AST_OP_H diff --git a/src/mplfe/ast_input/include/ast_parser.h b/src/mplfe/ast_input/include/ast_parser.h index d7a076173efed1d83d1e0297bcf137d100dea7d4..3bb966044d63f0640fd3a541aa669dab62677d7f 100644 --- a/src/mplfe/ast_input/include/ast_parser.h +++ b/src/mplfe/ast_input/include/ast_parser.h @@ -130,6 +130,7 @@ ASTDecl *ProcessDecl(MapleAllocator &allocator, const clang::Decl &decl); private: void TraverseDecl(clang::Decl *decl, std::function const &functor); + ASTDecl *GetAstDeclOfDeclRefExpr(MapleAllocator &allocator, const clang::Expr &expr); uint32 fileIdx; const std::string fileName; std::unique_ptr astFile; diff --git a/src/mplfe/ast_input/include/ast_stmt.h b/src/mplfe/ast_input/include/ast_stmt.h index c4956d554f064af93584df14a068d948bf61926f..dfb7a62a0bd8a21d0f3436d126ee0f2177a5a815 100644 --- a/src/mplfe/ast_input/include/ast_stmt.h +++ b/src/mplfe/ast_input/include/ast_stmt.h @@ -232,11 +232,20 @@ class ASTSwitchStmt : public ASTStmt { return bodyStmt; } + void SetHasDefault(bool argHasDefault) { + hasDefualt = argHasDefault; + } + + bool HasDefault() const { + return hasDefualt; + } + private: std::list Emit2FEStmtImpl() const override; ASTStmt *condStmt; ASTExpr *condExpr; ASTStmt *bodyStmt; + bool hasDefualt = false; }; class ASTCaseStmt : public ASTStmt { @@ -268,11 +277,29 @@ class ASTCaseStmt : public ASTStmt { return subStmt; } + int64 GetLCaseTag() const { + return lCaseTag; + } + + int64 GetRCaseTag() const { + return rCaseTag; + } + + void SetLCaseTag(int64 l) { + lCaseTag = l; + } + + void SetRCaseTag(int64 r) { + rCaseTag = r; + } + private: std::list Emit2FEStmtImpl() const override; - ASTExpr* lhs; - ASTExpr* rhs; - ASTStmt* subStmt; + ASTExpr* lhs = nullptr; + ASTExpr* rhs = nullptr; + ASTStmt* subStmt = nullptr; + int64 lCaseTag; + int64 rCaseTag; }; class ASTDefaultStmt : public ASTStmt { diff --git a/src/mplfe/ast_input/src/ast_decl.cpp b/src/mplfe/ast_input/src/ast_decl.cpp index eb7d35fe9dea7d88b7812ad2713d500c069ff519..a038f0f9cab8deaa06cae58646c9c1becfad26e7 100644 --- a/src/mplfe/ast_input/src/ast_decl.cpp +++ b/src/mplfe/ast_input/src/ast_decl.cpp @@ -16,6 +16,7 @@ #include "ast_parser.h" #include "global_tables.h" #include "ast_stmt.h" +#include "feir_var_name.h" namespace maple { // ---------- ASTDecl --------- @@ -31,6 +32,12 @@ const std::vector &ASTDecl::GetTypeDesc() const { return typeDesc; } +// ---------- ASTVar ---------- +std::unique_ptr ASTVar::Translate2FEIRVar() { + CHECK_FATAL(typeDesc.size() == 1, "Invalid ASTVar"); + return std::make_unique(name, std::make_unique(*(typeDesc[0]))); +} + // ---------- 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 49550063880d55b829ed8ff8085d7ad5a4c2f88a..c2534bc9bb2c9fe4c69f4e85f0cc6332b76ced41 100644 --- a/src/mplfe/ast_input/src/ast_expr.cpp +++ b/src/mplfe/ast_input/src/ast_expr.cpp @@ -114,7 +114,7 @@ UniqueFEIRExpr ASTUOPostIncExpr::Emit2FEExprImpl(std::list &stmt PrimType subPrimType = subType->GetPrimType(); // postinc_1 = a, subVar attr need update - UniqueFEIRVar selfVar = FEIRBuilder::CreateVarNameForC(refName, *subType, false, false); + UniqueFEIRVar selfVar = FEIRBuilder::CreateVarNameForC(refName, *subType, isGlobal, false); UniqueFEIRVar selfMoveVar = selfVar->Clone(); UniqueFEIRVar tempVar = FEIRBuilder::CreateVarNameForC(FEUtils::GetSequentialName("postinc_"), *subType); UniqueFEIRVar tempMoveVar = tempVar->Clone(); @@ -151,7 +151,7 @@ UniqueFEIRExpr ASTUOPostDecExpr::Emit2FEExprImpl(std::list &stmt PrimType subPrimType = subType->GetPrimType(); // postdec_1 = a, selfVar attr need update - UniqueFEIRVar selfVar = FEIRBuilder::CreateVarNameForC(refName, *subType, false, false); + UniqueFEIRVar selfVar = FEIRBuilder::CreateVarNameForC(refName, *subType, isGlobal, false); UniqueFEIRVar selfMoveVar = selfVar->Clone(); UniqueFEIRVar tempVar = FEIRBuilder::CreateVarNameForC(FEUtils::GetSequentialName("postinc_"), *subType); UniqueFEIRVar tempMoveVar = tempVar->Clone(); @@ -201,7 +201,7 @@ UniqueFEIRExpr ASTUOPreIncExpr::Emit2FEExprImpl(std::list &stmts // a = a + 1, selfVar attr need update UniqueFEIRExpr astUOPreIncExpr = FEIRBuilder::CreateExprMathBinary(OP_add, std::move(childFEIRExpr), std::move(incDecExpr)); - UniqueFEIRVar selfVar = FEIRBuilder::CreateVarNameForC(refName, *subType, false, false); + 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)); @@ -230,7 +230,7 @@ UniqueFEIRExpr ASTUOPreDecExpr::Emit2FEExprImpl(std::list &stmts // a = a - 1, selfVar attr need update UniqueFEIRExpr astUOPreIncExpr = FEIRBuilder::CreateExprMathBinary(OP_sub, std::move(childFEIRExpr), std::move(incDecExpr)); - UniqueFEIRVar selfVar = FEIRBuilder::CreateVarNameForC(refName, *subType, false, false); + 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)); @@ -248,7 +248,7 @@ UniqueFEIRExpr ASTUOAddrOfExpr::Emit2FEExprImpl(std::list &stmts ASTDecl *var = static_cast(childExpr)->GetASTDecl(); // var attr should update UniqueFEIRVar addrOfVar = FEIRBuilder::CreateVarNameForC(var->GetName(), *(var->GetTypeDesc().front()), - false, false); + var->IsGlobal(), false); addrOfExpr = FEIRBuilder::CreateExprAddrofVar(std::move(addrOfVar)); } else { // other potential expr should concern UniqueFEIRExpr childFEIRExpr; @@ -380,13 +380,6 @@ void ASTInitListExpr::SetInitListType(MIRType *type) { initListType = type; } -// ---------- ASTBinaryOperator ---------- -std::list ASTBinaryOperatorStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); - std::list stmts; - return stmts; -} - UniqueFEIRExpr ASTImplicitValueInitExpr::Emit2FEExprImpl(std::list &stmts) const { CHECK_FATAL(false, "NIY"); return nullptr; @@ -409,8 +402,31 @@ UniqueFEIRExpr ASTExprUnaryExprOrTypeTraitExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NIY"); - return nullptr; + 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, + std::move(baseFEExpr)); + iread->SetFieldName(memberName); + return iread; + } else { + UniqueFEIRVar tmpVar; + if (baseFEExpr->GetKind() == kExprDRead) { + auto dreadFEExpr = static_cast(baseFEExpr.get()); + tmpVar = dreadFEExpr->GetVar()->Clone(); + } else { + tmpVar = FEIRBuilder::CreateVarNameForC(FEUtils::GetSequentialName("struct_tmpvar_"), *baseType); + UniqueFEIRStmt readStmt = FEIRBuilder::CreateStmtDAssign(tmpVar->Clone(), baseFEExpr->Clone()); + stmts.emplace_back(std::move(readStmt)); + } + auto dread = std::make_unique(std::move(tmpVar)); + dread->SetFieldName(memberName); + return dread; + } } UniqueFEIRExpr ASTDesignatedInitUpdateExpr::Emit2FEExprImpl(std::list &stmts) const { @@ -418,104 +434,42 @@ UniqueFEIRExpr ASTDesignatedInitUpdateExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBOMulExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBODivExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBORemExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBOSubExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBOShlExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBOShrExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBOLTExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBOGTExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBOLEExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBOGEExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBOEQExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBONEExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBOAndExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBOXorExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBOOrExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBOLAndExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBOLOrExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBOEqExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); +UniqueFEIRExpr ASTBinaryOperatorExpr::Emit2FEExprImpl(std::list &stmts) const { + auto leftFEExpr = leftExpr->Emit2FEExpr(stmts); + auto rightFEExpr = rightExpr->Emit2FEExpr(stmts); + return FEIRBuilder::CreateExprBinary(opcode, std::move(leftFEExpr), std::move(rightFEExpr)); +} + +UniqueFEIRExpr ASTAssignExpr::ProcessAssign(std::list &stmts, UniqueFEIRExpr leftFEExpr, + UniqueFEIRExpr rightFEExpr) const { + // C89 does not support lvalue casting, but cxx support, needs to improve here + if (leftFEExpr->GetKind() == FEIRNodeKind::kExprDRead && !leftFEExpr->GetType()->IsArray()) { + auto dreadFEExpr = static_cast(leftFEExpr.get()); + FieldID fieldID = dreadFEExpr->GetFieldID(); + std::string fieldName = dreadFEExpr->GetFieldName(); + UniqueFEIRVarTrans varTrans = dreadFEExpr->CreateTransDirect(); + UniqueFEIRVar var = varTrans->GetVar()->Clone(); + auto preStmt = std::make_unique(std::move(var), std::move(rightFEExpr), fieldID); + preStmt->SetFieldName(fieldName); + stmts.emplace_back(std::move(preStmt)); + return leftFEExpr; + } 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); + preStmt->SetFieldName(ireadFEExpr->GetFieldName()); + stmts.emplace_back(std::move(preStmt)); + return leftFEExpr; + } return nullptr; } -UniqueFEIRExpr ASTBOAssign::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; +UniqueFEIRExpr ASTAssignExpr::Emit2FEExprImpl(std::list &stmts) const { + UniqueFEIRExpr leftFEExpr = leftExpr->Emit2FEExpr(stmts); + UniqueFEIRExpr rightFEExpr = rightExpr->Emit2FEExpr(stmts); + return ProcessAssign(stmts, std::move(leftFEExpr), std::move(rightFEExpr)); } UniqueFEIRExpr ASTBOComma::Emit2FEExprImpl(std::list &stmts) const { @@ -523,12 +477,7 @@ UniqueFEIRExpr ASTBOComma::Emit2FEExprImpl(std::list &stmts) con return nullptr; } -UniqueFEIRExpr ASTBOPtrMemD::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; -} - -UniqueFEIRExpr ASTBOPtrMemI::Emit2FEExprImpl(std::list &stmts) const { +UniqueFEIRExpr ASTBOPtrMemExpr::Emit2FEExprImpl(std::list &stmts) const { CHECK_FATAL(false, "NYI"); return nullptr; } @@ -600,8 +549,10 @@ UniqueFEIRExpr ASTImaginaryLiteral::Emit2FEExprImpl(std::list &s // ---------- ASTCompoundAssignOperatorExpr ---------- UniqueFEIRExpr ASTCompoundAssignOperatorExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NIY"); - return nullptr; + UniqueFEIRExpr leftFEExpr = leftExpr->Emit2FEExpr(stmts); + UniqueFEIRExpr rightFEExpr = rightExpr->Emit2FEExpr(stmts); + rightFEExpr = FEIRBuilder::CreateExprBinary(opForCompoundAssign, leftFEExpr->Clone(), std::move(rightFEExpr)); + return ProcessAssign(stmts, std::move(leftFEExpr), std::move(rightFEExpr)); } // ---------- ASTVAArgExpr ---------- @@ -612,8 +563,14 @@ UniqueFEIRExpr ASTVAArgExpr::Emit2FEExprImpl(std::list &stmts) c // ---------- ASTCStyleCastExpr ---------- UniqueFEIRExpr ASTCStyleCastExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NYI"); - return nullptr; + MIRType *src = canCastArray ? decl->GetTypeDesc().front() : srcType; + auto feirCStyleCastExpr = std::make_unique(src, destType, + child->Emit2FEExpr(stmts), + canCastArray); + if (decl != nullptr) { + feirCStyleCastExpr->SetRefName(decl->GetName()); + } + return feirCStyleCastExpr; } // ---------- ASTArrayInitLoopExpr ---------- @@ -654,8 +611,12 @@ UniqueFEIRExpr ASTDependentScopeDeclRefExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NIY"); - return nullptr; -} -} - + UniqueFEIRExpr atomicExpr = std::make_unique(type, refType, objExpr->Emit2FEExpr(stmts), + valExpr1->Emit2FEExpr(stmts), + valExpr2->Emit2FEExpr(stmts), + atomicOp); + static_cast(atomicExpr.get())->SetVal1Type(val1Type); + static_cast(atomicExpr.get())->SetVal2Type(val2Type); + return atomicExpr; +} +} \ No newline at end of file diff --git a/src/mplfe/ast_input/src/ast_parser.cpp b/src/mplfe/ast_input/src/ast_parser.cpp index 5ffc1ea262a81b3d9f7bb541dbe8d46562f2b721..82220d2d9fd18d8ca9ce5d98b2c572202b447b82 100644 --- a/src/mplfe/ast_input/src/ast_parser.cpp +++ b/src/mplfe/ast_input/src/ast_parser.cpp @@ -39,43 +39,26 @@ bool ASTParser::Verify() { return true; } -#define BO_CASE(CLASS) \ - case clang::BO_##CLASS: \ - return ASTExprBuilder(allocator); - -#define BO_CASE_EXPR(CLASS) \ - case clang::BO_##CLASS: \ - return ASTExprBuilder(allocator); - ASTBinaryOperatorExpr *ASTParser::AllocBinaryOperatorExpr(MapleAllocator &allocator, const clang::BinaryOperator bo) { - clang::BinaryOperator::Opcode opcode = bo.getOpcode(); - switch (opcode) { - BO_CASE(PtrMemD) // ".*" - BO_CASE(PtrMemI) // "->" - BO_CASE_EXPR(Mul) // "*" - BO_CASE_EXPR(Div) // "/" - BO_CASE_EXPR(Rem) // "%" - BO_CASE_EXPR(Add) // "+" - BO_CASE_EXPR(Sub) // "-" - BO_CASE_EXPR(Shl) // "<<" - BO_CASE_EXPR(Shr) // ">>" - BO_CASE_EXPR(LT) // "<" - BO_CASE_EXPR(GT) // ">" - BO_CASE_EXPR(LE) // "<=" - BO_CASE_EXPR(GE) // ">=" - BO_CASE_EXPR(EQ) // "==" - BO_CASE_EXPR(NE) // "!=" - BO_CASE_EXPR(And) // "&" - BO_CASE_EXPR(Xor) // "^" - BO_CASE_EXPR(Or) // "|" - BO_CASE_EXPR(LAnd) // "&&" - BO_CASE_EXPR(LOr) // "||" - BO_CASE(Assign) // "=" - BO_CASE(Comma) // "," - default: - CHECK_FATAL(false, "NIY"); - return nullptr; + if (bo.isAssignmentOp() && !bo.isCompoundAssignmentOp()) { + if (bo.isCompoundAssignmentOp()) { + auto *expr = ASTDeclsBuilder::ASTExprBuilder(allocator); + clang::BinaryOperator::Opcode opcode = clang::BinaryOperator::getOpForCompoundAssignment(bo.getOpcode()); + Opcode mirOpcode = ASTUtil::CvtBinaryOpcode(opcode); + expr->SetOpForCompoundAssign(mirOpcode); + } else { + return ASTDeclsBuilder::ASTExprBuilder(allocator); + } + } + // [C++ 5.5] Pointer-to-member operators. + if (bo.isPtrMemOp()) { + return ASTDeclsBuilder::ASTExprBuilder(allocator); } + Opcode mirOpcode = ASTUtil::CvtBinaryOpcode(bo.getOpcode()); + CHECK_FATAL(mirOpcode != OP_undef, "Opcode not support!"); + auto *expr = ASTDeclsBuilder::ASTExprBuilder(allocator); + expr->SetOpcode(mirOpcode); + return expr; } ASTStmt *ASTParser::ProcessFunctionBody(MapleAllocator &allocator, const clang::CompoundStmt &compoundStmt) { @@ -84,7 +67,7 @@ ASTStmt *ASTParser::ProcessFunctionBody(MapleAllocator &allocator, const clang:: } ASTStmt *ASTParser::ProcessStmtCompoundStmt(MapleAllocator &allocator, const clang::CompoundStmt &cpdStmt) { - ASTCompoundStmt *astCompoundStmt = ASTStmtBuilder(allocator); + ASTCompoundStmt *astCompoundStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astCompoundStmt != nullptr, "astCompoundStmt is nullptr"); clang::CompoundStmt::const_body_iterator it; ASTStmt *childStmt = nullptr; @@ -98,7 +81,7 @@ ASTStmt *ASTParser::ProcessStmtCompoundStmt(MapleAllocator &allocator, const cla if (childStmt != nullptr) { astCompoundStmt->SetASTStmt(childStmt); } else { - return nullptr; + continue; } } return astCompoundStmt; @@ -137,13 +120,12 @@ ASTStmt *ASTParser::ProcessStmt(MapleAllocator &allocator, const clang::Stmt &st STMT_CASE(DeclStmt); STMT_CASE(NullStmt); default: - CHECK_FATAL(false, "NIY"); return nullptr; } } ASTStmt *ASTParser::ProcessStmtUnaryOperator(MapleAllocator &allocator, const clang::UnaryOperator &unaryOp) { - ASTUnaryOperatorStmt *astUOStmt = ASTStmtBuilder(allocator); + ASTUnaryOperatorStmt *astUOStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astUOStmt != nullptr, "astUOStmt is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, &unaryOp); if (astExpr == nullptr) { @@ -154,7 +136,7 @@ ASTStmt *ASTParser::ProcessStmtUnaryOperator(MapleAllocator &allocator, const cl } ASTStmt *ASTParser::ProcessStmtBinaryOperator(MapleAllocator &allocator, const clang::BinaryOperator &binaryOp) { - ASTBinaryOperatorStmt *astBOStmt = ASTStmtBuilder(allocator); + ASTBinaryOperatorStmt *astBOStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astBOStmt != nullptr, "astBOStmt is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, &binaryOp); if (astExpr == nullptr) { @@ -165,7 +147,7 @@ ASTStmt *ASTParser::ProcessStmtBinaryOperator(MapleAllocator &allocator, const c } ASTStmt *ASTParser::ProcessStmtCallExpr(MapleAllocator &allocator, const clang::CallExpr &callExpr) { - ASTCallExprStmt *astCallExprStmt = ASTStmtBuilder(allocator); + ASTCallExprStmt *astCallExprStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astCallExprStmt != nullptr, "astCallExprStmt is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, &callExpr); if (astExpr == nullptr) { @@ -177,7 +159,8 @@ ASTStmt *ASTParser::ProcessStmtCallExpr(MapleAllocator &allocator, const clang:: ASTStmt *ASTParser::ProcessStmtImplicitCastExpr(MapleAllocator &allocator, const clang::ImplicitCastExpr &implicitCastExpr) { - ASTImplicitCastExprStmt *astImplicitCastExprStmt = ASTStmtBuilder(allocator); + ASTImplicitCastExprStmt *astImplicitCastExprStmt = + ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astImplicitCastExprStmt != nullptr, "astImplicitCastExprStmt is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, &implicitCastExpr); if (astExpr == nullptr) { @@ -188,7 +171,7 @@ ASTStmt *ASTParser::ProcessStmtImplicitCastExpr(MapleAllocator &allocator, } ASTStmt *ASTParser::ProcessStmtParenExpr(MapleAllocator &allocator, const clang::ParenExpr &parenExpr) { - ASTParenExprStmt *astParenExprStmt = ASTStmtBuilder(allocator); + ASTParenExprStmt *astParenExprStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astParenExprStmt != nullptr, "astCallExprStmt is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, &parenExpr); if (astExpr == nullptr) { @@ -199,7 +182,7 @@ ASTStmt *ASTParser::ProcessStmtParenExpr(MapleAllocator &allocator, const clang: } ASTStmt *ASTParser::ProcessStmtIntegerLiteral(MapleAllocator &allocator, const clang::IntegerLiteral &integerLiteral) { - ASTIntegerLiteralStmt *astIntegerLiteralStmt = ASTStmtBuilder(allocator); + ASTIntegerLiteralStmt *astIntegerLiteralStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astIntegerLiteralStmt != nullptr, "astIntegerLiteralStmt is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, &integerLiteral); if (astExpr == nullptr) { @@ -210,7 +193,7 @@ ASTStmt *ASTParser::ProcessStmtIntegerLiteral(MapleAllocator &allocator, const c } ASTStmt *ASTParser::ProcessStmtVAArgExpr(MapleAllocator &allocator, const clang::VAArgExpr &vAArgExpr) { - ASTVAArgExprStmt *astVAArgExprStmt = ASTStmtBuilder(allocator); + ASTVAArgExprStmt *astVAArgExprStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astVAArgExprStmt != nullptr, "astVAArgExprStmt is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, &vAArgExpr); if (astExpr == nullptr) { @@ -222,7 +205,8 @@ ASTStmt *ASTParser::ProcessStmtVAArgExpr(MapleAllocator &allocator, const clang: ASTStmt *ASTParser::ProcessStmtConditionalOperator(MapleAllocator &allocator, const clang::ConditionalOperator &conditionalOperator) { - ASTConditionalOperatorStmt *astConditionalOperatorStmt = ASTStmtBuilder(allocator); + ASTConditionalOperatorStmt *astConditionalOperatorStmt = + ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astConditionalOperatorStmt != nullptr, "astConditionalOperatorStmt is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, &conditionalOperator); if (astExpr == nullptr) { @@ -234,7 +218,8 @@ ASTStmt *ASTParser::ProcessStmtConditionalOperator(MapleAllocator &allocator, ASTStmt *ASTParser::ProcessStmtCharacterLiteral(MapleAllocator &allocator, const clang::CharacterLiteral &characterLiteral) { - ASTCharacterLiteralStmt *astCharacterLiteralStmt = ASTStmtBuilder(allocator); + ASTCharacterLiteralStmt *astCharacterLiteralStmt = + ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astCharacterLiteralStmt != nullptr, "astCharacterLiteralStmt is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, &characterLiteral); if (astExpr == nullptr) { @@ -245,7 +230,7 @@ ASTStmt *ASTParser::ProcessStmtCharacterLiteral(MapleAllocator &allocator, } ASTStmt *ASTParser::ProcessStmtCStyleCastExpr(MapleAllocator &allocator, const clang::CStyleCastExpr &cStyleCastExpr) { - ASTCStyleCastExprStmt *astCStyleCastExprStmt = ASTStmtBuilder(allocator); + ASTCStyleCastExprStmt *astCStyleCastExprStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astCStyleCastExprStmt != nullptr, "astCStyleCastExprStmt is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, &cStyleCastExpr); if (astExpr == nullptr) { @@ -256,7 +241,7 @@ ASTStmt *ASTParser::ProcessStmtCStyleCastExpr(MapleAllocator &allocator, const c } ASTStmt *ASTParser::ProcessStmtStmtExpr(MapleAllocator &allocator, const clang::StmtExpr &stmtExpr) { - ASTStmtExprStmt *astStmtExprStmt = ASTStmtBuilder(allocator); + ASTStmtExprStmt *astStmtExprStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astStmtExprStmt != nullptr, "astStmtExprStmt is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, &stmtExpr); if (astExpr == nullptr) { @@ -268,7 +253,7 @@ ASTStmt *ASTParser::ProcessStmtStmtExpr(MapleAllocator &allocator, const clang:: ASTStmt *ASTParser::ProcessStmtCompoundAssignOperator(MapleAllocator &allocator, const clang::CompoundAssignOperator &cpdAssignOp) { - ASTCompoundAssignOperatorStmt *astCAOStmt = ASTStmtBuilder(allocator); + ASTCompoundAssignOperatorStmt *astCAOStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astCAOStmt != nullptr, "astCAOStmt is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, &cpdAssignOp); if (astExpr == nullptr) { @@ -279,7 +264,7 @@ ASTStmt *ASTParser::ProcessStmtCompoundAssignOperator(MapleAllocator &allocator, } ASTStmt *ASTParser::ProcessStmtReturnStmt(MapleAllocator &allocator, const clang::ReturnStmt &retStmt) { - ASTReturnStmt *astStmt = ASTStmtBuilder(allocator); + ASTReturnStmt *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, retStmt.getRetValue()); if (astExpr == nullptr) { @@ -290,7 +275,7 @@ ASTStmt *ASTParser::ProcessStmtReturnStmt(MapleAllocator &allocator, const clang } ASTStmt *ASTParser::ProcessStmtIfStmt(MapleAllocator &allocator, const clang::IfStmt &ifStmt) { - auto *astStmt = ASTStmtBuilder(allocator); + auto *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, ifStmt.getCond()); if (astExpr == nullptr) { @@ -313,10 +298,10 @@ ASTStmt *ASTParser::ProcessStmtIfStmt(MapleAllocator &allocator, const clang::If } ASTStmt *ASTParser::ProcessStmtForStmt(MapleAllocator &allocator, const clang::ForStmt &forStmt) { - auto *astStmt = ASTStmtBuilder(allocator); + auto *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); if (forStmt.getInit() != nullptr) { - ASTStmt *initStmt = ProcessStmtCompoundStmt(allocator, *llvm::cast(forStmt.getInit())); + ASTStmt *initStmt = ProcessStmt(allocator, *forStmt.getInit()); if (initStmt == nullptr) { return nullptr; } @@ -345,7 +330,7 @@ ASTStmt *ASTParser::ProcessStmtForStmt(MapleAllocator &allocator, const clang::F } ASTStmt *ASTParser::ProcessStmtWhileStmt(MapleAllocator &allocator, const clang::WhileStmt &whileStmt) { - ASTWhileStmt *astStmt = ASTStmtBuilder(allocator); + ASTWhileStmt *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); ASTExpr *condExpr = ProcessExpr(allocator, whileStmt.getCond()); if (condExpr == nullptr) { @@ -361,9 +346,9 @@ ASTStmt *ASTParser::ProcessStmtWhileStmt(MapleAllocator &allocator, const clang: } ASTStmt *ASTParser::ProcessStmtGotoStmt(MapleAllocator &allocator, const clang::GotoStmt &gotoStmt) { - ASTGotoStmt *astStmt = ASTStmtBuilder(allocator); + ASTGotoStmt *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); - astStmt->SetLabelName(gotoStmt.getLabel()->getNameAsString()); + astStmt->SetLabelName(gotoStmt.getLabel()->getStmt()->getName()); return astStmt; } @@ -394,7 +379,7 @@ bool ASTParser::HasDefault(const clang::Stmt &stmt) { ASTStmt *ASTParser::ProcessStmtSwitchStmt(MapleAllocator &allocator, const clang::SwitchStmt &switchStmt) { // if switch cond expr has var decl, we need to handle it. - ASTSwitchStmt *astStmt = ASTStmtBuilder(allocator); + ASTSwitchStmt *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); ASTStmt *condStmt = switchStmt.getConditionVariableDeclStmt() == nullptr ? nullptr : ProcessStmt(allocator, *switchStmt.getConditionVariableDeclStmt()); @@ -406,11 +391,12 @@ ASTStmt *ASTParser::ProcessStmtSwitchStmt(MapleAllocator &allocator, const clang ASTStmt *bodyStmt = switchStmt.getBody() == nullptr ? nullptr : ProcessStmt(allocator, *switchStmt.getBody()); astStmt->SetBodyStmt(bodyStmt); + astStmt->SetHasDefault(HasDefault(*switchStmt.getBody())); return astStmt; } ASTStmt *ASTParser::ProcessStmtDoStmt(MapleAllocator &allocator, const clang::DoStmt &doStmt) { - ASTDoStmt *astStmt = ASTStmtBuilder(allocator); + ASTDoStmt *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); ASTExpr *condExpr = ProcessExpr(allocator, doStmt.getCond()); if (condExpr == nullptr) { @@ -426,23 +412,33 @@ ASTStmt *ASTParser::ProcessStmtDoStmt(MapleAllocator &allocator, const clang::Do } ASTStmt *ASTParser::ProcessStmtBreakStmt(MapleAllocator &allocator, const clang::BreakStmt &breakStmt) { - auto *astStmt = ASTStmtBuilder(allocator); + auto *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); return astStmt; } ASTStmt *ASTParser::ProcessStmtCaseStmt(MapleAllocator &allocator, const clang::CaseStmt &caseStmt) { - ASTCaseStmt *astStmt = ASTStmtBuilder(allocator); + ASTCaseStmt *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); astStmt->SetLHS(ProcessExpr(allocator, caseStmt.getLHS())); astStmt->SetRHS(ProcessExpr(allocator, caseStmt.getRHS())); + clang::Expr::EvalResult resL; + (void)caseStmt.getLHS()->EvaluateAsInt(resL, *astFile->GetAstContext()); + astStmt->SetLCaseTag(resL.Val.getInt().getExtValue()); + if (caseStmt.getRHS() != nullptr) { + clang::Expr::EvalResult resR; + (void)caseStmt.getLHS()->EvaluateAsInt(resR, *astFile->GetAstContext()); + astStmt->SetRCaseTag(resR.Val.getInt().getExtValue()); + } else { + astStmt->SetRCaseTag(resL.Val.getInt().getExtValue()); + } ASTStmt* subStmt = caseStmt.getSubStmt() == nullptr ? nullptr : ProcessStmt(allocator, *caseStmt.getSubStmt()); astStmt->SetSubStmt(subStmt); return astStmt; } ASTStmt *ASTParser::ProcessStmtDefaultStmt(MapleAllocator &allocator, const clang::DefaultStmt &defaultStmt) { - ASTDefaultStmt *astStmt = ASTStmtBuilder(allocator); + ASTDefaultStmt *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); auto *subStmt = defaultStmt.getSubStmt() == nullptr ? nullptr : ProcessStmt(allocator, *defaultStmt.getSubStmt()); astStmt->SetChildStmt(subStmt); @@ -450,19 +446,19 @@ ASTStmt *ASTParser::ProcessStmtDefaultStmt(MapleAllocator &allocator, const clan } ASTStmt *ASTParser::ProcessStmtNullStmt(MapleAllocator &allocator, const clang::NullStmt &nullStmt) { - ASTNullStmt *astStmt = ASTStmtBuilder(allocator); + ASTNullStmt *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); return astStmt; } ASTStmt *ASTParser::ProcessStmtContinueStmt(MapleAllocator &allocator, const clang::ContinueStmt &continueStmt) { - auto *astStmt = ASTStmtBuilder(allocator); + auto *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); return astStmt; } ASTStmt *ASTParser::ProcessStmtDeclStmt(MapleAllocator &allocator, const clang::DeclStmt &declStmt) { - ASTDeclStmt *astStmt = ASTStmtBuilder(allocator); + ASTDeclStmt *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); if (declStmt.isSingleDecl()) { const clang::Decl *decl = declStmt.getSingleDecl(); @@ -545,33 +541,33 @@ ASTUnaryOperatorExpr *ASTParser::AllocUnaryOperatorExpr(MapleAllocator &allocato clang::UnaryOperator::Opcode clangOpCode = expr.getOpcode(); switch (clangOpCode) { case clang::UO_Minus: // "-" - return ASTExprBuilder(allocator); + return ASTDeclsBuilder::ASTExprBuilder(allocator); case clang::UO_Not: // "~" - return ASTExprBuilder(allocator); + return ASTDeclsBuilder::ASTExprBuilder(allocator); case clang::UO_LNot: // "!" - return ASTExprBuilder(allocator); + return ASTDeclsBuilder::ASTExprBuilder(allocator); case clang::UO_PostInc: // "++" - return ASTExprBuilder(allocator); + return ASTDeclsBuilder::ASTExprBuilder(allocator); case clang::UO_PostDec: // "--" - return ASTExprBuilder(allocator); + return ASTDeclsBuilder::ASTExprBuilder(allocator); case clang::UO_PreInc: // "++" - return ASTExprBuilder(allocator); + return ASTDeclsBuilder::ASTExprBuilder(allocator); case clang::UO_PreDec: // "--" - return ASTExprBuilder(allocator); + return ASTDeclsBuilder::ASTExprBuilder(allocator); case clang::UO_AddrOf: // "&" - return ASTExprBuilder(allocator); + return ASTDeclsBuilder::ASTExprBuilder(allocator); case clang::UO_Deref: // "*" - return ASTExprBuilder(allocator); + return ASTDeclsBuilder::ASTExprBuilder(allocator); case clang::UO_Plus: // "+" - return ASTExprBuilder(allocator); + return ASTDeclsBuilder::ASTExprBuilder(allocator); case clang::UO_Real: // "__real" - return ASTExprBuilder(allocator); + return ASTDeclsBuilder::ASTExprBuilder(allocator); case clang::UO_Imag: // "__imag" - return ASTExprBuilder(allocator); + return ASTDeclsBuilder::ASTExprBuilder(allocator); case clang::UO_Extension: // "__extension__" - return ASTExprBuilder(allocator); + return ASTDeclsBuilder::ASTExprBuilder(allocator); case clang::UO_Coawait: // "co_await" - return ASTExprBuilder(allocator); + return ASTDeclsBuilder::ASTExprBuilder(allocator); default: CHECK_FATAL(false, "NYI"); } @@ -604,6 +600,10 @@ ASTExpr *ASTParser::ProcessExprUnaryOperator(MapleAllocator &allocator, const cl const auto *namedDecl = llvm::dyn_cast(declRefExpr->getDecl()->getCanonicalDecl()); std::string refName = astFile->GetMangledName(*namedDecl); astUOExpr->SetRefName(refName); + if (declRefExpr->getDecl()->getKind() == clang::Decl::Var) { + const auto *varDecl = llvm::cast(declRefExpr->getDecl()->getCanonicalDecl()); + astUOExpr->SetGlobal(!varDecl->isLocalVarDeclOrParm()); + } if (subType->GetPrimType() == PTY_ptr) { int64 len; const clang::QualType qualType = subExpr->getType()->getPointeeType(); @@ -630,7 +630,7 @@ ASTExpr *ASTParser::ProcessExprUnaryOperator(MapleAllocator &allocator, const cl } ASTExpr *ASTParser::ProcessExprNoInitExpr(MapleAllocator &allocator, const clang::NoInitExpr &expr) { - ASTNoInitExpr *astNoInitExpr = ASTExprBuilder(allocator); + ASTNoInitExpr *astNoInitExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astNoInitExpr != nullptr, "astNoInitExpr is nullptr"); clang::QualType qualType = expr.getType(); MIRType *noInitType = astFile->CvtType(qualType); @@ -639,7 +639,7 @@ ASTExpr *ASTParser::ProcessExprNoInitExpr(MapleAllocator &allocator, const clang } ASTExpr *ASTParser::ProcessExprPredefinedExpr(MapleAllocator &allocator, const clang::PredefinedExpr &expr) { - ASTPredefinedExpr *astPredefinedExpr = ASTExprBuilder(allocator); + ASTPredefinedExpr *astPredefinedExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astPredefinedExpr != nullptr, "astPredefinedExpr is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, expr.getFunctionName()); if (astExpr == nullptr) { @@ -650,7 +650,7 @@ ASTExpr *ASTParser::ProcessExprPredefinedExpr(MapleAllocator &allocator, const c } ASTExpr *ASTParser::ProcessExprOpaqueValueExpr(MapleAllocator &allocator, const clang::OpaqueValueExpr &expr) { - ASTOpaqueValueExpr *astOpaqueValueExpr = ASTExprBuilder(allocator); + ASTOpaqueValueExpr *astOpaqueValueExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astOpaqueValueExpr != nullptr, "astOpaqueValueExpr is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, expr.getSourceExpr()); if (astExpr == nullptr) { @@ -662,7 +662,8 @@ ASTExpr *ASTParser::ProcessExprOpaqueValueExpr(MapleAllocator &allocator, const ASTExpr *ASTParser::ProcessExprBinaryConditionalOperator(MapleAllocator &allocator, const clang::BinaryConditionalOperator &expr) { - ASTBinaryConditionalOperator *astBinaryConditionalOperator = ASTExprBuilder(allocator); + ASTBinaryConditionalOperator *astBinaryConditionalOperator = + ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astBinaryConditionalOperator != nullptr, "astBinaryConditionalOperator is nullptr"); ASTExpr *condExpr = ProcessExpr(allocator, expr.getCond()); if (condExpr == nullptr) { @@ -680,7 +681,7 @@ ASTExpr *ASTParser::ProcessExprBinaryConditionalOperator(MapleAllocator &allocat ASTExpr *ASTParser::ProcessExprCompoundLiteralExpr(MapleAllocator &allocator, const clang::CompoundLiteralExpr &expr) { - ASTCompoundLiteralExpr *astCompoundLiteralExpr = ASTExprBuilder(allocator); + ASTCompoundLiteralExpr *astCompoundLiteralExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astCompoundLiteralExpr != nullptr, "astCompoundLiteralExpr is nullptr"); const clang::Expr *initExpr = expr.getInitializer(); CHECK_FATAL(initExpr != nullptr, "initExpr is nullptr"); @@ -702,7 +703,7 @@ ASTExpr *ASTParser::ProcessExprCompoundLiteralExpr(MapleAllocator &allocator, } ASTExpr *ASTParser::ProcessExprInitListExpr(MapleAllocator &allocator, const clang::InitListExpr &expr) { - ASTInitListExpr *astInitListExpr = ASTExprBuilder(allocator); + ASTInitListExpr *astInitListExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astInitListExpr != nullptr, "ASTInitListExpr is nullptr"); MIRType *initListType = astFile->CvtType(expr.getType()); astInitListExpr->SetInitListType(initListType); @@ -720,7 +721,7 @@ ASTExpr *ASTParser::ProcessExprInitListExpr(MapleAllocator &allocator, const cla } ASTExpr *ASTParser::ProcessExprOffsetOfExpr(MapleAllocator &allocator, const clang::OffsetOfExpr &expr) {\ - ASTOffsetOfExpr *astOffsetOfExpr = ASTExprBuilder(allocator); + 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 @@ -732,7 +733,7 @@ ASTExpr *ASTParser::ProcessExprOffsetOfExpr(MapleAllocator &allocator, const cla } ASTExpr *ASTParser::ProcessExprVAArgExpr(MapleAllocator &allocator, const clang::VAArgExpr &expr) { - ASTVAArgExpr *astVAArgExpr = ASTExprBuilder(allocator); + ASTVAArgExpr *astVAArgExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); ASSERT(astVAArgExpr != nullptr, "astVAArgExpr is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, expr.getSubExpr()); if (astExpr == nullptr) { @@ -744,14 +745,14 @@ ASTExpr *ASTParser::ProcessExprVAArgExpr(MapleAllocator &allocator, const clang: ASTExpr *ASTParser::ProcessExprImplicitValueInitExpr(MapleAllocator &allocator, const clang::ImplicitValueInitExpr &expr) { - auto *astImplicitValueInitExpr = ASTExprBuilder(allocator); + auto *astImplicitValueInitExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astImplicitValueInitExpr != nullptr, "astImplicitValueInitExpr is nullptr"); astImplicitValueInitExpr->SetType(astFile->CvtType(expr.getType())); return astImplicitValueInitExpr; } ASTExpr *ASTParser::ProcessExprStringLiteral(MapleAllocator &allocator, const clang::StringLiteral &expr) { - auto *astStringLiteral = ASTExprBuilder(allocator); + auto *astStringLiteral = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astStringLiteral != nullptr, "astStringLiteral is nullptr"); astStringLiteral->SetType(astFile->CvtType(expr.getType())); astStringLiteral->SetLength(expr.getLength()); @@ -765,7 +766,7 @@ ASTExpr *ASTParser::ProcessExprStringLiteral(MapleAllocator &allocator, const cl } ASTExpr *ASTParser::ProcessExprArraySubscriptExpr(MapleAllocator &allocator, const clang::ArraySubscriptExpr &expr) { - auto *astArraySubscriptExpr = ASTExprBuilder(allocator); + auto *astArraySubscriptExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astArraySubscriptExpr != nullptr, "astArraySubscriptExpr is nullptr"); ASTExpr *baseExpr = ProcessExpr(allocator, expr.getBase()); if (baseExpr == nullptr) { @@ -782,7 +783,7 @@ ASTExpr *ASTParser::ProcessExprArraySubscriptExpr(MapleAllocator &allocator, con ASTExpr *ASTParser::ProcessExprUnaryExprOrTypeTraitExpr(MapleAllocator &allocator, const clang::UnaryExprOrTypeTraitExpr &expr) { - auto *astExprUnaryExprOrTypeTraitExpr = ASTExprBuilder(allocator); + auto *astExprUnaryExprOrTypeTraitExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astExprUnaryExprOrTypeTraitExpr != nullptr, "astExprUnaryExprOrTypeTraitExpr is nullptr"); if (expr.isArgumentType()) { astExprUnaryExprOrTypeTraitExpr->SetIsType(true); @@ -798,23 +799,23 @@ ASTExpr *ASTParser::ProcessExprUnaryExprOrTypeTraitExpr(MapleAllocator &allocato } ASTExpr *ASTParser::ProcessExprMemberExpr(MapleAllocator &allocator, const clang::MemberExpr &expr) { - auto *astMemberExpr = ASTExprBuilder(allocator); + auto *astMemberExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astMemberExpr != nullptr, "astMemberExpr is nullptr"); ASTExpr *baseExpr = ProcessExpr(allocator, expr.getBase()); if (baseExpr == nullptr) { return nullptr; } astMemberExpr->SetBaseExpr(baseExpr); - clang::ValueDecl *memberDecl = expr.getMemberDecl(); - std::string memberName = astFile->GetMangledName(*memberDecl); - astMemberExpr->SetMemberName(memberName); + astMemberExpr->SetBaseType(astFile->CvtType(expr.getBase()->getType())); + astMemberExpr->SetMemberName(expr.getMemberDecl()->getNameAsString()); + astMemberExpr->SetMemberType(astFile->CvtType(expr.getMemberDecl()->getType())); astMemberExpr->SetIsArrow(expr.isArrow()); return astMemberExpr; } ASTExpr *ASTParser::ProcessExprDesignatedInitUpdateExpr(MapleAllocator &allocator, const clang::DesignatedInitUpdateExpr &expr) { - auto *astDesignatedInitUpdateExpr = ASTExprBuilder(allocator); + auto *astDesignatedInitUpdateExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astDesignatedInitUpdateExpr != nullptr, "astDesignatedInitUpdateExpr is nullptr"); ASTExpr *baseExpr = ProcessExpr(allocator, expr.getBase()); if (baseExpr == nullptr) { @@ -835,7 +836,7 @@ ASTExpr *ASTParser::ProcessExprStmtExpr(MapleAllocator &allocator, const clang:: } ASTExpr *ASTParser::ProcessExprConditionalOperator(MapleAllocator &allocator, const clang::ConditionalOperator &expr) { - ASTConditionalOperator *astConditionalOperator = ASTExprBuilder(allocator); + ASTConditionalOperator *astConditionalOperator = ASTDeclsBuilder::ASTExprBuilder(allocator); ASSERT(astConditionalOperator != nullptr, "astConditionalOperator is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, expr.getCond()); if (astExpr == nullptr) { @@ -857,8 +858,7 @@ ASTExpr *ASTParser::ProcessExprConditionalOperator(MapleAllocator &allocator, co ASTExpr *ASTParser::ProcessExprCompoundAssignOperator(MapleAllocator &allocator, const clang::CompoundAssignOperator &expr) { - ASTCompoundAssignOperatorExpr *astCompoundAssignOperatorExpr = - ASTExprBuilder(allocator); + auto *astCompoundAssignOperatorExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); ASSERT(astCompoundAssignOperatorExpr != nullptr, "astCompoundAssignOperatorExpr is nullptr"); clang::Expr *lExpr = expr.getLHS(); if (lExpr != nullptr) { @@ -878,6 +878,9 @@ ASTExpr *ASTParser::ProcessExprCompoundAssignOperator(MapleAllocator &allocator, return nullptr; } } + clang::BinaryOperator::Opcode op = clang::BinaryOperator::getOpForCompoundAssignment(expr.getOpcode()); + astCompoundAssignOperatorExpr->SetOpForCompoundAssign(ASTUtil::CvtBinaryOpcode(op)); + astCompoundAssignOperatorExpr->SetRetType(astFile->CvtType(expr.getComputationResultType())); return astCompoundAssignOperatorExpr; } @@ -913,7 +916,7 @@ ASTExpr *ASTParser::ProcessExprGNUNullExpr(MapleAllocator &allocator, const clan } ASTExpr *ASTParser::ProcessExprConstantExpr(MapleAllocator &allocator, const clang::ConstantExpr &expr) { - ASTConstantExpr *astConstantExpr = ASTExprBuilder(allocator); + ASTConstantExpr *astConstantExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); ASSERT(astConstantExpr != nullptr, "astConstantExpr is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, expr.getSubExpr()); if (astExpr == nullptr) { @@ -930,7 +933,7 @@ ASTExpr *ASTParser::ProcessExprImaginaryLiteral(MapleAllocator &allocator, const clang::QualType elemQualType = llvm::cast(complexQualType)->getElementType(); MIRType *elemType = astFile->CvtType(elemQualType); CHECK_NULL_FATAL(elemType); - ASTImaginaryLiteral *astImaginaryLiteral = ASTExprBuilder(allocator); + ASTImaginaryLiteral *astImaginaryLiteral = ASTDeclsBuilder::ASTExprBuilder(allocator); astImaginaryLiteral->SetComplexType(complexType); astImaginaryLiteral->SetElemType(elemType); ASTExpr *astExpr = ProcessExpr(allocator, expr.getSubExpr()); @@ -942,7 +945,7 @@ ASTExpr *ASTParser::ProcessExprImaginaryLiteral(MapleAllocator &allocator, const } ASTExpr *ASTParser::ProcessExprCallExpr(MapleAllocator &allocator, const clang::CallExpr &expr) { - ASTCallExpr *astCallExpr = ASTExprBuilder(allocator); + ASTCallExpr *astCallExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); ASSERT(astCallExpr != nullptr, "astCallExpr is nullptr"); // callee ASTExpr *astCallee = ProcessExpr(allocator, expr.getCallee()); @@ -976,7 +979,7 @@ ASTExpr *ASTParser::ProcessExprCallExpr(MapleAllocator &allocator, const clang:: } ASTExpr *ASTParser::ProcessExprParenExpr(MapleAllocator &allocator, const clang::ParenExpr &expr) { - ASTParenExpr *astParenExpr = ASTExprBuilder(allocator); + ASTParenExpr *astParenExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); ASSERT(astParenExpr != nullptr, "astParenExpr is nullptr"); ASTExpr *astExpr = ProcessExpr(allocator, expr.getSubExpr()); if (astExpr == nullptr) { @@ -987,7 +990,7 @@ ASTExpr *ASTParser::ProcessExprParenExpr(MapleAllocator &allocator, const clang: } ASTExpr *ASTParser::ProcessExprCharacterLiteral(MapleAllocator &allocator, const clang::CharacterLiteral &expr) { - ASTCharacterLiteral *astCharacterLiteral = ASTExprBuilder(allocator); + ASTCharacterLiteral *astCharacterLiteral = ASTDeclsBuilder::ASTExprBuilder(allocator); ASSERT(astCharacterLiteral != nullptr, "astCharacterLiteral is nullptr"); const clang::QualType qualType = expr.getType(); const auto *type = llvm::cast(qualType.getTypePtr()); @@ -1000,7 +1003,7 @@ ASTExpr *ASTParser::ProcessExprCharacterLiteral(MapleAllocator &allocator, const } ASTExpr *ASTParser::ProcessExprIntegerLiteral(MapleAllocator &allocator, const clang::IntegerLiteral &expr) { - ASTIntegerLiteral *astIntegerLiteral = ASTExprBuilder(allocator); + ASTIntegerLiteral *astIntegerLiteral = ASTDeclsBuilder::ASTExprBuilder(allocator); ASSERT(astIntegerLiteral != nullptr, "astIntegerLiteral is nullptr"); uint64 val = 0; MIRType *type; @@ -1020,7 +1023,7 @@ ASTExpr *ASTParser::ProcessExprIntegerLiteral(MapleAllocator &allocator, const c } ASTExpr *ASTParser::ProcessExprFloatingLiteral(MapleAllocator &allocator, const clang::FloatingLiteral &expr) { - ASTFloatingLiteral *astFloatingLiteral = ASTExprBuilder(allocator); + ASTFloatingLiteral *astFloatingLiteral = ASTDeclsBuilder::ASTExprBuilder(allocator); ASSERT(astFloatingLiteral != nullptr, "astFloatingLiteral is nullptr"); llvm::APFloat apf = expr.getValue(); const llvm::fltSemantics &fltSem = expr.getSemantics(); @@ -1040,7 +1043,7 @@ ASTExpr *ASTParser::ProcessExprFloatingLiteral(MapleAllocator &allocator, const } ASTExpr *ASTParser::ProcessExprImplicitCastExpr(MapleAllocator &allocator, const clang::ImplicitCastExpr &expr) { - ASTImplicitCastExpr *astImplicitCastExpr = ASTExprBuilder(allocator); + ASTImplicitCastExpr *astImplicitCastExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astImplicitCastExpr != nullptr, "astImplicitCastExpr is nullptr"); switch (expr.getCastKind()) { case clang::CK_NoOp: @@ -1064,7 +1067,7 @@ ASTExpr *ASTParser::ProcessExprImplicitCastExpr(MapleAllocator &allocator, const } ASTExpr *ASTParser::ProcessExprDeclRefExpr(MapleAllocator &allocator, const clang::DeclRefExpr &expr) { - ASTDeclRefExpr *astRefExpr = ASTExprBuilder(allocator); + ASTDeclRefExpr *astRefExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astRefExpr != nullptr, "astRefExpr is nullptr"); switch (expr.getStmtClass()) { case clang::Stmt::DeclRefExprClass: { @@ -1072,8 +1075,13 @@ ASTExpr *ASTParser::ProcessExprDeclRefExpr(MapleAllocator &allocator, const clan std::string refName = astFile->GetMangledName(*namedDecl); clang::QualType qualType = expr.getDecl()->getType(); MIRType *refType = astFile->CvtType(qualType); - ASTDecl *astDecl = ASTDeclBuilder(allocator, fileName, refName, std::vector{refType}); + ASTDecl *astDecl = ASTDeclsBuilder::ASTDeclBuilder(allocator, fileName, refName, std::vector{refType}); + if (expr.getDecl()->getKind() == clang::Decl::Var) { + const auto *varDecl = llvm::cast(expr.getDecl()->getCanonicalDecl()); + astDecl->SetGlobal(!varDecl->isLocalVarDeclOrParm()); + } astRefExpr->SetASTDecl(astDecl); + astRefExpr->SetType(refType); return astRefExpr; } default: @@ -1119,18 +1127,54 @@ ASTExpr *ASTParser::ProcessExprBinaryOperator(MapleAllocator &allocator, const c return astBinOpExpr; } +ASTDecl *ASTParser::GetAstDeclOfDeclRefExpr(MapleAllocator &allocator, const clang::Expr &expr) { + switch (expr.getStmtClass()) { + case clang::Stmt::DeclRefExprClass: + return static_cast(ProcessExpr(allocator, &expr))->GetASTDecl(); + case clang::Stmt::ImplicitCastExprClass: + case clang::Stmt::CXXStaticCastExprClass: + case clang::Stmt::CXXReinterpretCastExprClass: + case clang::Stmt::CStyleCastExprClass: + return GetAstDeclOfDeclRefExpr(allocator, *llvm::cast(expr).getSubExpr()); + case clang::Stmt::ParenExprClass: + return GetAstDeclOfDeclRefExpr(allocator, *llvm::cast(expr).getSubExpr()); + case clang::Stmt::UnaryOperatorClass: + return GetAstDeclOfDeclRefExpr(allocator, *llvm::cast(expr).getSubExpr()); + case clang::Stmt::ConstantExprClass: + return GetAstDeclOfDeclRefExpr(allocator, *llvm::cast(expr).getSubExpr()); + default: + break; + } + return nullptr; +} + ASTExpr *ASTParser::ProcessExprCStyleCastExpr(MapleAllocator &allocator, const clang::CStyleCastExpr &castExpr) { - ASTCStyleCastExpr *astCastExpr = ASTExprBuilder(allocator); - CHECK_FATAL(astCastExpr != nullptr, "astCastExpr is nullptr"); - astCastExpr->SetSrcType(astFile->CvtType(castExpr.getSubExpr()->getType())); - astCastExpr->SetDestType(astFile->CvtType(castExpr.getType())); + ASTCStyleCastExpr *astCastExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + clang::QualType fType = castExpr.getSubExpr()->getType(); + clang::QualType tType = castExpr.getType(); + bool shouldCastArr = false; + if (fType->isPointerType() && tType->isPointerType()) { + const clang::Type *fromType = fType->getPointeeType().getTypePtrOrNull(); + const clang::Type *toType = tType->getPointeeType().getTypePtrOrNull(); + bool asFlag = fromType != nullptr && toType != nullptr; + CHECK_FATAL(asFlag, "ERROR:null pointer!"); + auto *implicit = llvm::dyn_cast(castExpr.getSubExpr()); + if ((fromType->getTypeClass() == clang::Type::ConstantArray && toType->getTypeClass() == clang::Type::Builtin) || + (implicit != nullptr && implicit->getCastKind() == clang::CK_ArrayToPointerDecay)) { + astCastExpr->SetDecl(GetAstDeclOfDeclRefExpr(allocator, *implicit)); + shouldCastArr = true; + } + } + astCastExpr->SetSrcType(astFile->CvtType(fType)); + astCastExpr->SetDestType(astFile->CvtType(tType)); astCastExpr->SetSubExpr(ProcessExpr(allocator, castExpr.getSubExpr())); + astCastExpr->SetCanCastArray(shouldCastArr); return astCastExpr; } ASTExpr *ASTParser::ProcessExprArrayInitLoopExpr(MapleAllocator &allocator, const clang::ArrayInitLoopExpr &arrInitLoopExpr) { - ASTArrayInitLoopExpr *astExpr = ASTExprBuilder(allocator); + ASTArrayInitLoopExpr *astExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astExpr != nullptr, "astCastExpr is nullptr"); ASTExpr *common = arrInitLoopExpr.getCommonExpr() == nullptr ? nullptr : ProcessExpr(allocator, arrInitLoopExpr.getCommonExpr()); @@ -1140,7 +1184,7 @@ ASTExpr *ASTParser::ProcessExprArrayInitLoopExpr(MapleAllocator &allocator, ASTExpr *ASTParser::ProcessExprArrayInitIndexExpr(MapleAllocator &allocator, const clang::ArrayInitIndexExpr &arrInitIndexExpr) { - ASTArrayInitIndexExpr *astExpr = ASTExprBuilder(allocator); + ASTArrayInitIndexExpr *astExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astExpr != nullptr, "astCastExpr is nullptr"); astExpr->SetPrimType(astFile->CvtType(arrInitIndexExpr.getType())); astExpr->SetValue("0"); @@ -1149,10 +1193,15 @@ ASTExpr *ASTParser::ProcessExprArrayInitIndexExpr(MapleAllocator &allocator, ASTExpr *ASTParser::ProcessExprAtomicExpr(MapleAllocator &allocator, const clang::AtomicExpr &atomicExpr) { - ASTAtomicExpr *astExpr = ASTExprBuilder(allocator); + ASTAtomicExpr *astExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astExpr != nullptr, "astCastExpr is nullptr"); + astExpr->SetObjExpr(ProcessExpr(allocator, atomicExpr.getPtr())); astExpr->SetType(astFile->CvtType(atomicExpr.getPtr()->getType())); astExpr->SetRefType(astFile->CvtType(atomicExpr.getPtr()->getType()->getPointeeType())); + astExpr->SetValExpr1(ProcessExpr(allocator, atomicExpr.getVal1())); + astExpr->SetValExpr2(ProcessExpr(allocator, atomicExpr.getVal2())); + astExpr->SetVal1Type(astFile->CvtType(atomicExpr.getVal1()->getType())); + astExpr->SetVal2Type(astFile->CvtType(atomicExpr.getVal2()->getType())); switch (atomicExpr.getOp()) { case clang::AtomicExpr::AO__atomic_add_fetch: case clang::AtomicExpr::AO__atomic_fetch_add: @@ -1203,7 +1252,7 @@ ASTExpr *ASTParser::ProcessExprAtomicExpr(MapleAllocator &allocator, ASTExpr *ASTParser::ProcessExprExprWithCleanups(MapleAllocator &allocator, const clang::ExprWithCleanups &cleanupsExpr) { - ASTExprWithCleanups *astExpr = ASTExprBuilder(allocator); + ASTExprWithCleanups *astExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astExpr != nullptr, "astCastExpr is nullptr"); ASTExpr *sub = cleanupsExpr.getSubExpr() == nullptr ? nullptr : ProcessExpr(allocator, cleanupsExpr.getSubExpr()); astExpr->SetSubExpr(sub); @@ -1293,7 +1342,7 @@ ASTDecl *ASTParser::ProcessDeclRecordDecl(MapleAllocator &allocator, const clang structName = astFile->GetOrCreateMappedUnnamedName(id); } ASTStruct *curStructOrUnion = - ASTStructBuilder(allocator, fileName, structName, std::vector{recType}, attrs); + ASTDeclsBuilder::ASTStructBuilder(allocator, fileName, structName, std::vector{recType}, attrs); if (recDecl.isUnion()) { curStructOrUnion->SetIsUnion(); } @@ -1359,7 +1408,7 @@ ASTDecl *ASTParser::ProcessDeclFunctionDecl(MapleAllocator &allocator, const cla } GenericAttrs attrs; astFile->CollectFuncAttrs(funcDecl, attrs, kPublic); - ASTFunc *astFunc = ASTFuncBuilder(allocator, fileName, funcName, typeDescIn, attrs, parmNamesIn); + ASTFunc *astFunc = ASTDeclsBuilder::ASTFuncBuilder(allocator, fileName, funcName, typeDescIn, attrs, parmNamesIn); CHECK_FATAL(astFunc != nullptr, "astFunc is nullptr"); if (funcDecl.hasBody()) { ASTStmt *astCompoundStmt = ProcessStmtCompoundStmt(allocator, @@ -1385,7 +1434,7 @@ ASTDecl *ASTParser::ProcessDeclFieldDecl(MapleAllocator &allocator, const clang: } GenericAttrs attrs; astFile->CollectAttrs(decl, attrs, kPublic); - return ASTFieldBuilder(allocator, fileName, fieldName, std::vector{fieldType}, attrs); + return ASTDeclsBuilder::ASTFieldBuilder(allocator, fileName, fieldName, std::vector{fieldType}, attrs); } ASTDecl *ASTParser::ProcessDeclVarDecl(MapleAllocator &allocator, const clang::VarDecl &varDecl) { @@ -1400,7 +1449,7 @@ ASTDecl *ASTParser::ProcessDeclVarDecl(MapleAllocator &allocator, const clang::V } GenericAttrs attrs; astFile->CollectAttrs(varDecl, attrs, kPublic); - ASTVar *astVar = ASTVarBuilder(allocator, fileName, varName, std::vector{varType}, attrs); + ASTVar *astVar = ASTDeclsBuilder::ASTVarBuilder(allocator, fileName, varName, std::vector{varType}, attrs); if (varDecl.hasInit()) { astVar->SetInitExpr(ProcessExpr(allocator, varDecl.getInit())); } @@ -1417,6 +1466,7 @@ bool ASTParser::RetrieveStructs(MapleAllocator &allocator, MapleList if (curStructOrUnion == nullptr) { return false; } + curStructOrUnion->SetGlobal(true); structs.emplace_back(curStructOrUnion); } return true; @@ -1429,6 +1479,7 @@ bool ASTParser::RetrieveFuncs(MapleAllocator &allocator, MapleList &fu if (af == nullptr) { return false; } + af->SetGlobal(true); funcs.emplace_back(af); } return true; diff --git a/src/mplfe/ast_input/src/ast_stmt.cpp b/src/mplfe/ast_input/src/ast_stmt.cpp index 68623eb449d277a347f3029f03500ea184e2bae4..30f924dcff0f10a93be368a53f96454c90ed9717 100644 --- a/src/mplfe/ast_input/src/ast_stmt.cpp +++ b/src/mplfe/ast_input/src/ast_stmt.cpp @@ -14,6 +14,7 @@ */ #include "ast_stmt.h" #include "ast_decl.h" +#include "ast_util.h" #include "mpl_logging.h" #include "feir_stmt.h" #include "feir_builder.h" @@ -36,8 +37,10 @@ const std::list &ASTCompoundStmt::GetASTStmtList() const { } std::list ASTCompoundStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); std::list stmts; + for (auto it : astStmts) { + stmts.splice(stmts.end(), it->Emit2FEStmt()); + } return stmts; } @@ -55,38 +58,76 @@ void ASTDeclRefExpr::SetASTDecl(ASTDecl *astDecl) { } std::list ASTIfStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); std::list stmts; + std::list thenStmts = thenStmt->Emit2FEStmt(); + UniqueFEIRExpr condFEExpr = condExpr->Emit2FEExpr(stmts); + std::unique_ptr ifStmt = std::make_unique(std::move(condFEExpr), std::move(thenStmts)); + if (elseStmt != nullptr) { + std::list elseStmts = elseStmt->Emit2FEStmt(); + ifStmt->SetHasElse(true); + ifStmt->SetElseStmts(std::move(elseStmts)); + } + stmts.emplace_back(std::move(ifStmt)); return stmts; } std::list ASTForStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); std::list stmts; + if (initStmt != nullptr) { + std::list feStmts = initStmt->Emit2FEStmt(); + stmts.splice(stmts.cend(), feStmts); + } + UniqueFEIRExpr condFEExpr; + if (condExpr != nullptr) { + condFEExpr = condExpr->Emit2FEExpr(stmts); + } else { + condFEExpr = std::make_unique(static_cast(1), PTY_i32); + } + std::list bodyFEStmts = bodyStmt->Emit2FEStmt(); + if (incExpr != nullptr) { + std::list exprs; + std::list incStmts; + UniqueFEIRExpr incFEExpr = incExpr->Emit2FEExpr(incStmts); + exprs.emplace_back(std::move(incFEExpr)); + auto incStmt = std::make_unique(OP_eval, std::move(exprs)); + incStmts.emplace_back(std::move(incStmt)); + bodyFEStmts.splice(bodyFEStmts.cend(), incStmts); + } + UniqueFEIRStmt whileStmt = std::make_unique(OP_while, std::move(condFEExpr), std::move(bodyFEStmts)); + stmts.emplace_back(std::move(whileStmt)); return stmts; } std::list ASTWhileStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); std::list stmts; + UniqueFEIRExpr condFEExpr = condExpr->Emit2FEExpr(stmts); + std::list bodyFEStmts = bodyStmt->Emit2FEStmt(); + UniqueFEIRStmt whileStmt = std::make_unique(OP_while, std::move(condFEExpr), std::move(bodyFEStmts)); + stmts.emplace_back(std::move(whileStmt)); return stmts; } std::list ASTDoStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); std::list stmts; + UniqueFEIRExpr condFEExpr = condExpr->Emit2FEExpr(stmts); + std::list bodyFEStmts = bodyStmt->Emit2FEStmt(); + UniqueFEIRStmt whileStmt = std::make_unique(OP_dowhile, std::move(condFEExpr), + std::move(bodyFEStmts)); + stmts.emplace_back(std::move(whileStmt)); return stmts; } std::list ASTBreakStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); std::list stmts; + UniqueFEIRStmt stmt = std::make_unique(); + stmts.emplace_back(std::move(stmt)); return stmts; } std::list ASTContinueStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); std::list stmts; + UniqueFEIRStmt stmt = std::make_unique(); + stmts.emplace_back(std::move(stmt)); return stmts; } @@ -100,35 +141,50 @@ std::list ASTUnaryOperatorStmt::Emit2FEStmtImpl() const { // ---------- ASTGotoStmt ---------- std::list ASTGotoStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); std::list stmts; + UniqueFEIRStmt stmt = FEIRBuilder::CreateStmtGoto(labelName); + stmts.emplace_back(std::move(stmt)); return stmts; } // ---------- ASTSwitchStmt ---------- std::list ASTSwitchStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); std::list stmts; + UniqueFEIRExpr expr = condExpr->Emit2FEExpr(stmts); + auto switchStmt = std::make_unique(std::move(expr), hasDefualt); + for (auto &s : bodyStmt->Emit2FEStmt()) { + switchStmt.get()->AddFeirStmt(std::move(s)); + } + stmts.emplace_back(std::move(switchStmt)); return stmts; } // ---------- ASTCaseStmt ---------- std::list ASTCaseStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); std::list stmts; + auto caseStmt = std::make_unique(lCaseTag); + caseStmt.get()->AddCaseTag2CaseVec(lCaseTag, rCaseTag); + for (auto &s : subStmt->Emit2FEStmt()) { + caseStmt.get()->AddFeirStmt(std::move(s)); + } + stmts.emplace_back(std::move(caseStmt)); return stmts; } // ---------- ASTDefaultStmt ---------- std::list ASTDefaultStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); std::list stmts; + auto defalutStmt = std::make_unique(); + for (auto &s : child->Emit2FEStmt()) { + defalutStmt.get()->AddFeirStmt(std::move(s)); + } + stmts.emplace_back(std::move(defalutStmt)); return stmts; } // ---------- ASTNullStmt ---------- std::list ASTNullStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); + // there is no need to process this stmt std::list stmts; return stmts; } @@ -179,8 +235,13 @@ std::list ASTCallExprStmt::Emit2FEStmtImpl() const { // ---------- ASTImplicitCastExprStmt ---------- std::list ASTImplicitCastExprStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); + CHECK_FATAL(exprs.size() == 1, "Only one sub expr supported!"); std::list stmts; + UniqueFEIRExpr feirExpr = exprs.front()->Emit2FEExpr(stmts); + std::list feirExprs; + feirExprs.emplace_back(std::move(feirExpr)); + auto stmt = std::make_unique(OP_eval, std::move(feirExprs)); + stmts.emplace_back(std::move(stmt)); return stmts; } @@ -235,8 +296,28 @@ std::list ASTCStyleCastExprStmt::Emit2FEStmtImpl() const { // ---------- ASTCompoundAssignOperatorStmt ---------- std::list ASTCompoundAssignOperatorStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); + CHECK_FATAL(exprs.size() == 1, "ASTCompoundAssignOperatorStmt must contain only one bo expr!"); + std::list stmts; + CHECK_FATAL(static_cast(exprs.front()) != nullptr, "Child expr must be ASTCompoundAssignOperator!"); + exprs.front()->Emit2FEExpr(stmts); + return stmts; +} + +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 { + 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)); + } return stmts; } } // namespace maple diff --git a/src/mplfe/bc_input/include/bc_instruction.h b/src/mplfe/bc_input/include/bc_instruction.h index 6fad4dc71c7c2b462c877e963fd099c09a585b98..a5f62446352a7a53486ed47b59d9fb9360b98d2d 100644 --- a/src/mplfe/bc_input/include/bc_instruction.h +++ b/src/mplfe/bc_input/include/bc_instruction.h @@ -154,11 +154,21 @@ struct BCRegTypeItem { pos = pc; } + void SetDom(bool flag) { + isDom = flag; + } + + bool IsDom() const { + return isDom; + } + GStrIdx typeNameIdx; bool isIndeterminate = false; // means `is def ` or `come from def` bool isFromDef = false; uint32 pos = UINT32_MAX; + + bool isDom = false; }; class BCRegType { @@ -239,6 +249,10 @@ class BCRegType { pos = pc; } + uint32 GetPos() const { + return pos; + } + void RegisterRelatedBCRegType(BCRegType *ty) { relatedBCRegTypes.emplace_back(ty); } diff --git a/src/mplfe/bc_input/src/bc_class.cpp b/src/mplfe/bc_input/src/bc_class.cpp index e1f102eeb88910017e5fe4afbb3bd45237f43809..10f8aa18a0b1810d7b6bbc3aecc5755b68186bb8 100644 --- a/src/mplfe/bc_input/src/bc_class.cpp +++ b/src/mplfe/bc_input/src/bc_class.cpp @@ -366,6 +366,7 @@ void BCClassMethod::InsertPhi(const std::vector &dom, std::vecto } CHECK_FATAL(srcItem != nullptr, "ByteCode RA error."); for (auto ty : *(d->aliveUsedTypes)) { + ty->SetDom(true); srcItem->InsertUniqueAliveType(d, ty); } } diff --git a/src/mplfe/bc_input/src/bc_instruction.cpp b/src/mplfe/bc_input/src/bc_instruction.cpp index 4f9d5d6c01943d934edcf15569bcc880328e8e87..8a255561bfbfa767c55cbdb43151a30f84efeb04 100644 --- a/src/mplfe/bc_input/src/bc_instruction.cpp +++ b/src/mplfe/bc_input/src/bc_instruction.cpp @@ -486,8 +486,11 @@ std::list BCReg::GenRetypeStmtsAfterDef() const { if (regType->GetUsedTypes() != nullptr) { for (const auto &usedType : *(regType->GetUsedTypes())) { bool exist = false; - for (const auto &elem : unqTypeItems) { + for (auto &elem : unqTypeItems) { if ((*usedType) == (*elem)) { + if (usedType->IsDom()) { + elem->SetDom(true); + } exist = true; break; } @@ -510,6 +513,9 @@ std::list BCReg::GenRetypeStmtsAfterDef() const { UniqueFEIRStmt retypeStmt = FEIRBuilder::CreateStmtRetype(dstReg->GenFEIRVarReg(), this->GenFEIRVarReg()); if (retypeStmt != nullptr) { + if (FEOptions::GetInstance().IsAOT() && usedType->IsDom()) { + retypeStmt->SetHexPC(regType->GetPos()); + } retypeStmts.emplace_back(std::move(retypeStmt)); } } diff --git a/src/mplfe/common/include/fe_utils.h b/src/mplfe/common/include/fe_utils.h index e46df1cba7a03fc2d1024f76fa115c0ae6732eca..77e8207b5d6183bd81a76c4b0c71444b917cfad3 100644 --- a/src/mplfe/common/include/fe_utils.h +++ b/src/mplfe/common/include/fe_utils.h @@ -21,6 +21,7 @@ #include "prim_types.h" #include "global_tables.h" #include "mempool.h" +#include "mir_nodes.h" namespace maple { class FEUtils { @@ -290,5 +291,41 @@ class FELinkListNode { FELinkListNode *prev; FELinkListNode *next; }; + +class AstSwitchUtil { + public: + static AstSwitchUtil &Instance() { + 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); + void PopNestedBreakLabels(); + void PushNestedCaseVectors(std::pair); + void PopNestedCaseVectors(); + bool CheckLabelUsed(LabelIdx label); + const std::pair &GetTopOfNestedCaseVectors() const; + std::map &GetLabelUseMap() { + return labelUsed; + } + static uint32_t tempVarNo; + static const char *cleanLabel; + static const char *exitLabel; + static const char *blockLabel; + static const char *caseLabel; + static const char *catchLabel; + static const char *endehLabel; + + private: + AstSwitchUtil() = default; + 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 } // namespace maple #endif // MPLFE_INCLUDE_FE_UTILS_H \ No newline at end of file diff --git a/src/mplfe/common/include/feir_builder.h b/src/mplfe/common/include/feir_builder.h index 1be7defc1a70b61e58e791e89cd7719716169165..b78327b093f0803c25b7e5184ed810cfa7804b5e 100644 --- a/src/mplfe/common/include/feir_builder.h +++ b/src/mplfe/common/include/feir_builder.h @@ -61,6 +61,7 @@ class FEIRBuilder { static UniqueFEIRExpr CreateExprMathUnary(Opcode op, UniqueFEIRExpr expr); static UniqueFEIRExpr CreateExprMathBinary(Opcode op, UniqueFEIRVar var0, UniqueFEIRVar var1); static UniqueFEIRExpr CreateExprMathBinary(Opcode op, UniqueFEIRExpr expr0, UniqueFEIRExpr expr1); + static UniqueFEIRExpr CreateExprBinary(Opcode op, UniqueFEIRExpr expr0, UniqueFEIRExpr expr1); static UniqueFEIRExpr CreateExprSExt(UniqueFEIRVar srcVar); static UniqueFEIRExpr CreateExprSExt(UniqueFEIRExpr srcExpr, PrimType dstType); static UniqueFEIRExpr CreateExprZExt(UniqueFEIRVar srcVar); @@ -78,6 +79,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 CreateStmtCondGoto(uint32 targetLabelIdx, Opcode op, UniqueFEIRExpr expr); static UniqueFEIRStmt CreateStmtSwitch(UniqueFEIRExpr expr); static UniqueFEIRStmt CreateStmtJavaConstClass(UniqueFEIRVar dstVar, UniqueFEIRType type); diff --git a/src/mplfe/common/include/feir_node_kind.def b/src/mplfe/common/include/feir_node_kind.def index 8e8108c7658e53c0e3136e6e93ff064851c42e56..78a7169cd8601f0d1ddead6114385d3cdf0174ab 100644 --- a/src/mplfe/common/include/feir_node_kind.def +++ b/src/mplfe/common/include/feir_node_kind.def @@ -48,6 +48,8 @@ FEIR_NODE_KIND(ExprJavaNewArray, "ExprJavaNewArray") FEIR_NODE_KIND(ExprJavaArrayLength, "ExprJavaArrayLength") FEIR_NODE_KIND(ExprJavaInstanceOf, "ExprJavaInstanceOf") FEIR_NODE_KIND(ExprArrayLoad, "ExprArrayLoad") +FEIR_NODE_KIND(ExprCStyleCast, "ExprCStyleCast") +FEIR_NODE_KIND(ExprAtomic, "ExprAtomic") FEIR_NODE_KIND(StmtJavaFillArrayData, "StmtJavaFillArrayData") FEIR_NODE_KIND(StmtPesudoFuncStart, "StmtPesudoFuncStart") FEIR_NODE_KIND(StmtPesudoFuncEnd, "StmtPesudoFuncEnd") @@ -59,3 +61,9 @@ FEIR_NODE_KIND(StmtPesudoEndTry, "StmtPesudoEndTry") FEIR_NODE_KIND(StmtPesudoJavaCatch, "StmtPesudoJavaCatch") FEIR_NODE_KIND(StmtPesudoComment, "StmtPesudoComment") FEIR_NODE_KIND(StmtPesudoCommentForInst, "StmtPesudoCommentForInst") +FEIR_NODE_KIND(StmtCaseForC, "StmtCaseForC") +FEIR_NODE_KIND(StmtDefaultForC, "StmtDefaultForC") +FEIR_NODE_KIND(StmtIf, "StmtIf") +FEIR_NODE_KIND(StmtDoWhile, "StmtDoWhile") +FEIR_NODE_KIND(StmtBreak, "StmtBreak") +FEIR_NODE_KIND(StmtContinue, "StmtContinue") diff --git a/src/mplfe/common/include/feir_stmt.h b/src/mplfe/common/include/feir_stmt.h index 589f1a7456224130ed2824f94b8ff380c4e0d7e3..34bc4e6490ee8b7deb07ee2c583dc2d980d09492 100644 --- a/src/mplfe/common/include/feir_stmt.h +++ b/src/mplfe/common/include/feir_stmt.h @@ -403,6 +403,26 @@ class FEIRExprDRead : public FEIRExpr { return trans; } + FieldID GetFieldID() { + return fieldID; + } + + UniqueFEIRVar &GetVar() { + return varSrc; + } + + void SetFieldName(std::string argFieldName){ + fieldName = argFieldName; + } + + std::string GetFieldName(){ + return fieldName; + } + + void SetFieldID(FieldID argFieldID){ + fieldID = argFieldID; + } + protected: std::unique_ptr CloneImpl() const override; void RegisterDFGNodes2CheckPointImpl(FEIRStmtCheckPoint &checkPoint) override; @@ -412,6 +432,8 @@ class FEIRExprDRead : public FEIRExpr { private: std::unique_ptr varSrc; + FieldID fieldID = 0; + std::string fieldName; }; // ---------- FEIRExprRegRead ---------- @@ -558,7 +580,31 @@ class FEIRExprIRead : public FEIRExpr { FEIRExprIRead(UniqueFEIRType returnType, UniqueFEIRType pointeeType, FieldID id, UniqueFEIRExpr expr) : FEIRExpr(FEIRNodeKind::kExprIRead), retType(std::move(returnType)), ptrType(std::move(pointeeType)), fieldID(id), subExpr(std::move(expr)) {} - ~FEIRExprIRead() = default; + ~FEIRExprIRead() override = default; + + void SetFieldID(FieldID argFieldID){ + fieldID = argFieldID; + } + + FieldID GetFieldID(){ + return fieldID; + } + + void SetFieldName(std::string argFieldName){ + fieldName = argFieldName; + } + + std::string GetFieldName(){ + return fieldName; + } + + UniqueFEIRExpr &GetOpnd(){ + return opnd; + } + + UniqueFEIRType &GetType(){ + return type; + } protected: std::unique_ptr CloneImpl() const override; @@ -569,6 +615,9 @@ class FEIRExprIRead : public FEIRExpr { UniqueFEIRType ptrType; FieldID fieldID; UniqueFEIRExpr subExpr; + UniqueFEIRExpr opnd; + UniqueFEIRType type; + std::string fieldName; }; // ---------- FEIRExprBinary ---------- @@ -815,6 +864,80 @@ class FEIRExprArrayLoad : public FEIRExpr { UniqueFEIRType typeArray; }; +class FEIRExprCStyleCast : public FEIRExpr { + public: + FEIRExprCStyleCast(MIRType *src, MIRType *dest, UniqueFEIRExpr sub, bool isArr2Pty); + ~FEIRExprCStyleCast() = default; + void SetArray2Pointer(bool isArr2Ptr) { + isArray2Pointer = isArr2Ptr; + } + void SetRefName(std::string name) { + refName = name; + } + + protected: + std::unique_ptr CloneImpl() const override; + BaseNode *GenMIRNodeImpl(MIRBuilder &mirBuilder) const override; + + private: + MIRType *srcType = nullptr; + MIRType *destType = nullptr; + UniqueFEIRExpr subExpr; + bool isArray2Pointer; + std::string refName; +}; + +enum ASTAtomicOp { + kAtomicBinaryOpAdd, + kAtomicBinaryOpSub, + kAtomicBinaryOpAnd, + kAtomicBinaryOpOr, + kAtomicBinaryOpXor, + kAtomicOpLoad, + kAtomicOpStore, + kAtomicOpExchange, + kAtomicOpCompareExchange, + kAtomicOpLast, +}; + +class FEIRExprAtomic : public FEIRExpr { + public: + FEIRExprAtomic(MIRType *ty, MIRType *ref, UniqueFEIRExpr obj, UniqueFEIRExpr val1, + UniqueFEIRExpr val2, + ASTAtomicOp atomOp); + ~FEIRExprAtomic() = default; + void SetVal1Type(MIRType *ty) { + val1Type = ty; + } + void SetVal2Type(MIRType *ty) { + val2Type = ty; + } + + protected: + std::unique_ptr CloneImpl() const override; + BaseNode *GenMIRNodeImpl(MIRBuilder &mirBuilder) const override; + + private: + void ProcessAtomicBinary(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, + MIRSymbol &valueVar, ASTAtomicOp opcode) const; + void ProcessAtomicLoad(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, + MIRSymbol &valueVar) const; + void ProcessAtomicStore(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, + MIRSymbol &valueVar) const; + void ProcessAtomicExchange(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, + MIRSymbol &valueVar) const; + void ProcessAtomicCompareExchange(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, + MIRSymbol *valueVar) const; + MIRType *type = nullptr; + MIRType *refType = nullptr; + MIRType *val1Type = nullptr; + MIRType *val2Type = nullptr; + UniqueFEIRExpr objExpr; + UniqueFEIRExpr valExpr1; + UniqueFEIRExpr valExpr2; + ASTAtomicOp atomicOp; +}; + // ---------- FEIRStmtNary ---------- class FEIRStmtNary : public FEIRStmt { public: @@ -884,6 +1007,10 @@ class FEIRStmtDAssign : public FEIRStmtAssign { expr = std::move(argExpr); } + void SetFieldName(std::string argFieldName) { + fieldName = argFieldName; + } + protected: std::string DumpDotStringImpl() const override; void RegisterDFGNodes2CheckPointImpl(FEIRStmtCheckPoint &checkPoint) override; @@ -892,6 +1019,31 @@ class FEIRStmtDAssign : public FEIRStmtAssign { std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; std::unique_ptr expr; int32 fieldID; + std::string fieldName; +}; + +// ---------- FEIRStmtDAssign ---------- +class FEIRStmtIAssign : public FEIRStmt { + public: + FEIRStmtIAssign(UniqueFEIRType argAddrType, UniqueFEIRExpr argAddrExpr, UniqueFEIRExpr argBaseExpr, FieldID id) + : FEIRStmt(FEIRNodeKind::kStmtIAssign), + addrType(std::move(argAddrType)), + addrExpr(std::move(argAddrExpr)), + baseExpr(std::move(argBaseExpr)), + fieldID(id) {} + ~FEIRStmtIAssign() = default; + + void SetFieldName(std::string name){ + fieldName = std::move(name); + } + + protected: + std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + UniqueFEIRType addrType; + UniqueFEIRExpr addrExpr; + UniqueFEIRExpr baseExpr; + std::string fieldName; + FieldID fieldID; }; // ---------- FEIRStmtJavaTypeCheck ---------- @@ -1158,6 +1310,33 @@ class FEIRStmtGoto2 : public FEIRStmt { FEIRStmtPesudoLabel2 *stmtTarget = nullptr; }; +// ---------- FEIRStmtGoto ---------- +class FEIRStmtGotoForC : public FEIRStmt { + public: + explicit FEIRStmtGotoForC(std::string labelName); + virtual ~FEIRStmtGotoForC() = default; + void SetLabelName(std::string name) { + labelName = std::move(name); + } + + std::string GetLabelName() const { + return labelName; + } + + protected: + bool IsFallThroughImpl() const override { + return false; + } + + bool IsBranchImpl() const override { + return true; + } + + std::string DumpDotStringImpl() const override; + std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + std::string labelName; +}; + // ---------- FEIRStmtCondGoto ---------- class FEIRStmtCondGoto : public FEIRStmtGoto { public: @@ -1344,6 +1523,73 @@ class FEIRStmtSwitch2 : public FEIRStmt { UniqueFEIRExpr expr; }; +// ---------- FEIRStmtSwitchForC ---------- +class FEIRStmtSwitchForC : public FEIRStmt { + public: + FEIRStmtSwitchForC(UniqueFEIRExpr argCondExpr, bool argHasDefault); + ~FEIRStmtSwitchForC() = default; + void AddFeirStmt(UniqueFEIRStmt stmt) { + subStmts.emplace_back(std::move(stmt)); + } + + void SetExpr(UniqueFEIRExpr argExpr) { + CHECK_NULL_FATAL(argExpr); + expr = std::move(argExpr); + } + + void SetHasDefault(bool argHasDefault) { + hasDefault = argHasDefault; + } + + protected: + std::string DumpDotStringImpl() const override; + void RegisterDFGNodes2CheckPointImpl(FEIRStmtCheckPoint &checkPoint) override; + bool CalculateDefs4AllUsesImpl(FEIRStmtCheckPoint &checkPoint, FEIRUseDefChain &udChain) override; + std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + + private: + UniqueFEIRExpr expr; + bool hasDefault = true; + std::list subStmts; +}; + +// ---------- FEIRStmtCaseForC ---------- +class FEIRStmtCaseForC : public FEIRStmt { + public: + FEIRStmtCaseForC(int64 lCaseLabel); + void AddCaseTag2CaseVec(int64 lCaseTag, int64 rCaseTag); + ~FEIRStmtCaseForC() = default; + void AddFeirStmt(UniqueFEIRStmt stmt) { + subStmts.emplace_back(std::move(stmt)); + } + std::map &GetPesudoLabelMap() { + return pesudoLabelMap; + } + protected: + std::string DumpDotStringImpl() const override; + std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + + private: + int64 lCaseLabel; + std::map pesudoLabelMap = std::map(); + std::list subStmts; +}; + +// ---------- FEIRStmtDefaultForC ---------- +class FEIRStmtDefaultForC : public FEIRStmt { + public: + explicit FEIRStmtDefaultForC(); + ~FEIRStmtDefaultForC() = default; + void AddFeirStmt(UniqueFEIRStmt stmt) { + subStmts.emplace_back(std::move(stmt)); + } + + protected: + std::string DumpDotStringImpl() const override; + std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + std::list subStmts; +}; + // ---------- FEIRStmtArrayStore ---------- class FEIRStmtArrayStore : public FEIRStmt { public: @@ -1664,5 +1910,95 @@ class FEIRStmtPesudoCommentForInst : public FEIRStmtPesudoComment { uint32 lineNum = invalid; uint32 pc = invalid; }; + +class FEIRStmtIf : public FEIRStmt { + public: + FEIRStmtIf(UniqueFEIRExpr argCondExpr, std::list argThenStmts) + : FEIRStmt(FEIRNodeKind::kStmtIf), + condExpr(std::move(argCondExpr)), + thenStmts(std::move(argThenStmts)) {} + ~FEIRStmtIf() = default; + + void SetHasElse(bool argHasElse) { + hasElse = argHasElse; + } + + void SetElseStmts(std::list argElseStmts) { + elseStmts = std::move(argElseStmts); + } + + protected: + bool IsBranchImpl() const override { + return true; + } + + std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + + private: + UniqueFEIRExpr condExpr; + bool hasElse = false; + std::list thenStmts; + std::list elseStmts; +}; + +class FEIRStmtDoWhile : public FEIRStmt { + public: + FEIRStmtDoWhile(Opcode argOpcode, UniqueFEIRExpr argCondExpr, std::list argBodyStmts) + : FEIRStmt(FEIRNodeKind::kStmtDoWhile), + opcode(argOpcode), + condExpr(std::move(argCondExpr)), + bodyStmts(std::move(argBodyStmts)) {} + ~FEIRStmtDoWhile() = default; + + protected: + bool IsBranchImpl() const override { + return true; + } + + std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + + private: + Opcode opcode; + UniqueFEIRExpr condExpr; + std::list bodyStmts; +}; + +class FEIRStmtBreak : public FEIRStmt { + public: + FEIRStmtBreak(): FEIRStmt(FEIRNodeKind::kStmtBreak) {} + ~FEIRStmtBreak() = default; + + void SetLabelName(std::string name){ + labelName = std::move(name); + } + + protected: + bool IsBranchImpl() const override { + return true; + } + + std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + private: + std::string labelName; +}; + +class FEIRStmtContinue : public FEIRStmt { + public: + FEIRStmtContinue(): FEIRStmt(FEIRNodeKind::kStmtContinue) {} + ~FEIRStmtContinue() = default; + + void SetLabelName(std::string name){ + labelName = std::move(name); + } + + 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/include/feir_type.h b/src/mplfe/common/include/feir_type.h index 803ab0838c553c140beadbab732c091bad78e77f..d4156e296924a51ae51c80403b47a859cc692590 100644 --- a/src/mplfe/common/include/feir_type.h +++ b/src/mplfe/common/include/feir_type.h @@ -29,7 +29,7 @@ enum FEIRTypeKind { kFEIRTypeDefault, kFEIRTypeByName, kFEIRTypePointer, - kFEIRTypenNative + kFEIRTypeNative }; class FEIRType { @@ -40,7 +40,7 @@ class FEIRType { static std::map> InitLangConfig(); MIRType *GenerateMIRTypeAuto(MIRSrcLang argSrcLang) const; MIRType *GenerateMIRTypeAuto() const { - return GenerateMIRTypeAuto(srcLang); + return GenerateMIRTypeAutoImpl(); } bool IsSameKind(const FEIRType &type) const { @@ -142,6 +142,10 @@ class FEIRType { static std::map> langConfig; protected: + virtual MIRType *GenerateMIRTypeAutoImpl() const { + return GenerateMIRTypeAuto(srcLang); + } + virtual MIRType *GenerateMIRTypeAutoImpl(MIRSrcLang argSrcLang) const; virtual void CopyFromImpl(const FEIRType &type); virtual std::unique_ptr CloneImpl() const = 0; virtual MIRType *GenerateMIRTypeImpl(bool usePtr, PrimType ptyPtr) const = 0; @@ -284,19 +288,27 @@ class FEIRTypeByName : public FEIRTypeDefault { // MIRType is enclosed directly in FEIRTypeNative. // Right now, FEIRTypeNative is only used for c-language. // Because var type is translated as MIRType directly in stage of ast parse. -class FEIRTypeNative : public FEIRTypeDefault { +class FEIRTypeNative : public FEIRType { public: - FEIRTypeNative(MIRType &argMIRType, TypeDim argDim = 0); + explicit FEIRTypeNative(MIRType &argMIRType); ~FEIRTypeNative() = default; FEIRTypeNative(const FEIRTypeNative&) = delete; FEIRTypeNative &operator=(const FEIRTypeNative&) = delete; protected: + MIRType *GenerateMIRTypeAutoImpl() const override; + PrimType GetPrimTypeImpl() const override; + void SetPrimTypeImpl(PrimType pt) override; + void CopyFromImpl(const FEIRType &type) override; std::unique_ptr CloneImpl() const override; MIRType *GenerateMIRTypeImpl(bool usePtr, PrimType ptyPtr) const override; bool IsEqualToImpl(const FEIRType &argType) const override; size_t HashImpl() const override; + std::string GetTypeNameImpl() const override; bool IsScalarImpl() const override; + bool IsRefImpl() const override; + bool IsArrayImpl() const override; + bool IsPreciseImpl() const override { return true; } @@ -305,6 +317,9 @@ class FEIRTypeNative : public FEIRTypeDefault { return true; } + TypeDim ArrayIncrDimImpl(TypeDim delta) override; + TypeDim ArrayDecrDimImpl(TypeDim delta) override; + private: MIRType &mirType; }; diff --git a/src/mplfe/common/include/feir_var.h b/src/mplfe/common/include/feir_var.h index e009e60f44876cebb4a3e638601584851f61c5ce..cad4faf23cb3c94aab447cc63259a937b15a2145 100644 --- a/src/mplfe/common/include/feir_var.h +++ b/src/mplfe/common/include/feir_var.h @@ -60,11 +60,9 @@ using UniqueFEIRVarTrans = std::unique_ptr; enum FEIRVarKind : uint8 { kFEIRVarDefault = 0, - kFEIRVarSpecial, kFEIRVarReg, kFEIRVarAccumulator, kFEIRVarName, - kFEIRVarNameSpec, kFEIRVarTypeScatter, }; diff --git a/src/mplfe/common/include/feir_var_name.h b/src/mplfe/common/include/feir_var_name.h index 1284b9952a6b6f1b480eb713951e200b250cdff7..b03ec8757f76f3f38124bcf0f5cc636fd7853547 100644 --- a/src/mplfe/common/include/feir_var_name.h +++ b/src/mplfe/common/include/feir_var_name.h @@ -34,6 +34,9 @@ class FEIRVarName : public FEIRVar { nameIdx(argNameIdx), withType(argWithType) {} + FEIRVarName(const std::string &argName, std::unique_ptr argType, bool argWithType = false) + : FEIRVarName(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(argName), std::move(argType), argWithType) {} + virtual ~FEIRVarName() = default; protected: @@ -44,35 +47,8 @@ class FEIRVarName : public FEIRVar { size_t HashImpl() const override; GStrIdx nameIdx; + // means emit this symbol with type bool withType : 1; }; - -// ---------- FEIRVarNameSpec ---------- -class FEIRVarNameSpec : public FEIRVarName { - public: - FEIRVarNameSpec(const std::string &argName, bool argWithType = false) - : FEIRVarName(GStrIdx(0), argWithType), - name(argName) { - kind = FEIRVarKind::kFEIRVarNameSpec; - } - - FEIRVarNameSpec(const std::string &argName, std::unique_ptr argType, bool argWithType = false) - : FEIRVarName(GStrIdx(0), std::move(argType), argWithType), - name(argName) { - kind = FEIRVarKind::kFEIRVarNameSpec; - } - - ~FEIRVarNameSpec() = default; - - protected: - std::string GetNameImpl(const MIRType &mirType) const override; - std::string GetNameRawImpl() const override; - std::unique_ptr CloneImpl() const override; - bool EqualsToImpl(const std::unique_ptr &var) const override; - size_t HashImpl() const override; - - private: - std::string name; -}; } // namespace maple #endif // MPLFE_INCLUDE_FEIR_VAR_REG_H \ No newline at end of file diff --git a/src/mplfe/common/src/fe_utils.cpp b/src/mplfe/common/src/fe_utils.cpp index c889feab7655f1580443e89a2c07a517074fee8c..81154dad3a95c657a4383122aa3a8776a740795c 100644 --- a/src/mplfe/common/src/fe_utils.cpp +++ b/src/mplfe/common/src/fe_utils.cpp @@ -16,6 +16,7 @@ #include #include "mpl_logging.h" #include "mir_type.h" +#include "mir_builder.h" namespace maple { // ---------- FEUtils ---------- const std::string FEUtils::kBoolean = "Z"; @@ -233,4 +234,53 @@ void FELinkListNode::InsertAfter(FELinkListNode *ins, FELinkListNode *pos) { ins->prev = pos; ins->next = posNext; } + +uint32_t AstSwitchUtil::tempVarNo = 0; +const char *AstSwitchUtil::cleanLabel = "clean"; +const char *AstSwitchUtil::exitLabel = "exit"; +const char *AstSwitchUtil::blockLabel = "blklbl"; +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); + ++tempVarNo; + return BlockLabel(endLab, exitLab); +} + +void AstSwitchUtil::MarkLabelUsed(LabelIdx label) { + labelUsed[label] = true; +} + +void AstSwitchUtil::MarkLabelUnUsed(LabelIdx label) { + labelUsed[label] = false; +} + +void AstSwitchUtil::PushNestedBreakLabels(LabelIdx label) { + nestedBreakLabels.push(label); +} + +void AstSwitchUtil::PopNestedBreakLabels() { + nestedBreakLabels.pop(); +} + +void AstSwitchUtil::PushNestedCaseVectors(std::pair caseVec) { + nestedCaseVectors.push(caseVec); +} + +void AstSwitchUtil::PopNestedCaseVectors() { + nestedCaseVectors.pop(); +} + +bool AstSwitchUtil::CheckLabelUsed(LabelIdx label) { + return labelUsed[label]; +} + +const std::pair &AstSwitchUtil::GetTopOfNestedCaseVectors() const { + return nestedCaseVectors.top(); +} } // namespace maple \ No newline at end of file diff --git a/src/mplfe/common/src/feir_builder.cpp b/src/mplfe/common/src/feir_builder.cpp index 4022391f19d74dec9e589a4a6d406873d3484245..7b4daec3bd1b5a05db0e85672c36321bcd527b92 100644 --- a/src/mplfe/common/src/feir_builder.cpp +++ b/src/mplfe/common/src/feir_builder.cpp @@ -74,20 +74,13 @@ UniqueFEIRVar FEIRBuilder::CreateVarName(GStrIdx nameIdx, PrimType primType, boo UniqueFEIRVar FEIRBuilder::CreateVarName(const std::string &name, PrimType primType, bool isGlobal, bool withType) { - GStrIdx nameIdx = GlobalTables::GetStrTable().GetStrIdxFromName(name); - if (nameIdx == 0) { - UniqueFEIRVar var = std::make_unique(name, withType); - var->GetType()->SetPrimType(primType); - var->SetGlobal(isGlobal); - return var; - } else { - return CreateVarName(nameIdx, primType, isGlobal, withType); - } + GStrIdx nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name); + return CreateVarName(nameIdx, primType, isGlobal, withType); } UniqueFEIRVar FEIRBuilder::CreateVarNameForC(GStrIdx nameIdx, MIRType &mirType, bool isGlobal, bool withType, TypeDim dim) { - UniqueFEIRType type = std::make_unique(mirType, dim); + UniqueFEIRType type = std::make_unique(mirType); UniqueFEIRVar var = std::make_unique(nameIdx, std::move(type), withType); var->SetGlobal(isGlobal); return var; @@ -191,6 +184,10 @@ UniqueFEIRExpr FEIRBuilder::CreateExprMathBinary(Opcode op, UniqueFEIRExpr expr0 return std::make_unique(op, std::move(expr0), std::move(expr1)); } +UniqueFEIRExpr FEIRBuilder::CreateExprBinary(Opcode op, UniqueFEIRExpr expr0, UniqueFEIRExpr expr1) { + return std::make_unique(op, std::move(expr0), std::move(expr1)); +} + UniqueFEIRExpr FEIRBuilder::CreateExprSExt(UniqueFEIRVar srcVar) { return std::make_unique(OP_sext, PTY_i32, std::make_unique(std::move(srcVar))); @@ -278,6 +275,12 @@ UniqueFEIRStmt FEIRBuilder::CreateStmtGoto(uint32 targetLabelIdx) { return stmt; } +UniqueFEIRStmt FEIRBuilder::CreateStmtGoto(std::string labelName) { + UniqueFEIRStmt stmt = std::make_unique(std::move(labelName)); + CHECK_NULL_FATAL(stmt); + return stmt; +} + UniqueFEIRStmt FEIRBuilder::CreateStmtCondGoto(uint32 targetLabelIdx, Opcode op, UniqueFEIRExpr expr) { UniqueFEIRStmt stmt = std::make_unique(op, targetLabelIdx, std::move(expr)); CHECK_NULL_FATAL(stmt); diff --git a/src/mplfe/common/src/feir_stmt.cpp b/src/mplfe/common/src/feir_stmt.cpp index 02d4de0c233744351768b38f15728862432c0a68..5d91cecf19f9d743a25fe0d2ec44fee0d8ba2bf3 100644 --- a/src/mplfe/common/src/feir_stmt.cpp +++ b/src/mplfe/common/src/feir_stmt.cpp @@ -26,6 +26,7 @@ #include "feir_type_helper.h" #include "bc_util.h" #include "rc_setter.h" +#include "fe_utils.h" namespace maple { std::string GetFEIRNodeKindDescription(FEIRNodeKind kindArg) { @@ -287,8 +288,18 @@ std::list FEIRStmtDAssign::GenMIRStmtsImpl(MIRBuilder &mirBuilder) co ASSERT(expr != nullptr, "src expr is nullptr"); MIRSymbol *dstSym = var->GenerateMIRSymbol(mirBuilder); BaseNode *srcNode = expr->GenMIRNode(mirBuilder); - StmtNode *mirStmt = mirBuilder.CreateStmtDassign(*dstSym, fieldID, srcNode); - ans.push_back(mirStmt); + if (!fieldName.empty() && fieldID == 0) { + MIRType *mirType = var->GetType()->GenerateMIRTypeAuto(); + if (mirType->IsMIRStructType()) { + MIRStructType *mirStructType = static_cast(mirType); + FieldID fid = mirBuilder.GetStructFieldIDFromFieldName(*mirStructType, fieldName); + StmtNode *mirStmt = mirBuilder.CreateStmtDassign(*dstSym, fid, srcNode); + ans.push_back(mirStmt); + } + } else { + StmtNode *mirStmt = mirBuilder.CreateStmtDassign(*dstSym, fieldID, srcNode); + ans.push_back(mirStmt); + } return ans; } @@ -763,6 +774,24 @@ std::pair FEIRStmtGoto2::GetLabelIdx() const { return std::make_pair(labelIdxOuter, labelIdxInner); } +FEIRStmtGotoForC::FEIRStmtGotoForC(std::string name) + : FEIRStmt(FEIRNodeKind::kStmtGoto), + labelName(name) {} + +std::list FEIRStmtGotoForC::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { + std::list ans; + LabelIdx label = mirBuilder.GetOrCreateMIRLabel(labelName); + GotoNode *gotoNode = mirBuilder.CreateStmtGoto(OP_goto, label); + ans.push_back(gotoNode); + return ans; +} + +std::string FEIRStmtGotoForC::DumpDotStringImpl() const { + std::stringstream ss; + ss << " " << id << ": " << GetFEIRNodeKindDescription(kind); + return ss.str(); +} + // ---------- FEIRStmtCondGoto ---------- FEIRStmtCondGoto::FEIRStmtCondGoto(Opcode argOp, uint32 argLabelIdx, UniqueFEIRExpr argExpr) : FEIRStmtGoto(argLabelIdx), @@ -880,6 +909,119 @@ std::string FEIRStmtSwitch2::DumpDotStringImpl() const { return ss.str(); } +// ---------- FEIRStmtSwitchForC ---------- +FEIRStmtSwitchForC::FEIRStmtSwitchForC(UniqueFEIRExpr argCondExpr, bool argHasDefault) + : FEIRStmt(FEIRNodeKind::kStmtSwitch), + expr(std::move(argCondExpr)), + hasDefault(argHasDefault) {} + +void FEIRStmtSwitchForC::RegisterDFGNodes2CheckPointImpl(FEIRStmtCheckPoint &checkPoint) { + expr->RegisterDFGNodes2CheckPoint(checkPoint); +} + +bool FEIRStmtSwitchForC::CalculateDefs4AllUsesImpl(FEIRStmtCheckPoint &checkPoint, FEIRUseDefChain &udChain) { + return expr->CalculateDefs4AllUses(checkPoint, udChain); +} + +std::list FEIRStmtSwitchForC::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { + 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 + AstSwitchUtil::Instance().PushNestedCaseVectors(std::pair(caseVec, swDefaultLabel)); + BaseNode *exprNode = expr->GenMIRNode(mirBuilder); + CaseVector &switchTable = *AstSwitchUtil::Instance().GetTopOfNestedCaseVectors().first; + for (auto &sub : subStmts) { + if (sub.get()->GetKind() == kStmtCaseForC) { + auto caseStmt = static_cast(sub.get()); + for (auto targetPair : caseStmt->GetPesudoLabelMap()) { + targetPair.second->GenerateLabelIdx(mirBuilder); + switchTable.push_back(std::make_pair(targetPair.first, targetPair.second->GetMIRLabelIdx())); + } + } + } + SwitchNode *mirSwitchStmt = mirBuilder.CreateStmtSwitch(exprNode, swDefaultLabel, switchTable); + ans.push_back(mirSwitchStmt); + for (auto &sub : subStmts) { + ans.splice(ans.end(), sub.get()->GenMIRStmts(mirBuilder)); + } + if (!hasDefault) { + StmtNode *mirSwExitLabelStmt = mirBuilder.CreateStmtLabel(allocateLabel.first); + ans.push_back(mirSwExitLabelStmt); + } + + if (AstSwitchUtil::Instance().CheckLabelUsed(allocateLabel.second)) { + StmtNode *mirSwExitLabelStmt = mirBuilder.CreateStmtLabel(allocateLabel.second); + ans.push_back(mirSwExitLabelStmt); + } + AstSwitchUtil::Instance().PopNestedBreakLabels(); + AstSwitchUtil::Instance().PopNestedCaseVectors(); + return ans; +} + +std::string FEIRStmtSwitchForC::DumpDotStringImpl() const { + std::stringstream ss; + ss << " " << id << ": " << GetFEIRNodeKindDescription(kind); + return ss.str(); +} + +FEIRStmtCaseForC::FEIRStmtCaseForC(int64 label) + : FEIRStmt(FEIRNodeKind::kStmtCaseForC), + lCaseLabel(label) {} + +void FEIRStmtCaseForC::AddCaseTag2CaseVec(int64 lCaseTag, int64 rCaseTag) { + auto pLabel = std::make_unique(lCaseLabel); + for (int64 csTag = lCaseTag; csTag <= rCaseTag; ++csTag) { + pesudoLabelMap.insert(std::pair(csTag, pLabel.get())); + } +} + +std::list FEIRStmtCaseForC::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { + std::list ans; + CaseVector &caseVec = *AstSwitchUtil::Instance().GetTopOfNestedCaseVectors().first; + StmtNode *mirLabelStmt = nullptr; + for (auto it : caseVec) { + if (lCaseLabel == it.first) { + mirLabelStmt = mirBuilder.CreateStmtLabel(it.second); + ans.emplace_back(mirLabelStmt); + } + } + + for (auto &sub : subStmts) { + ans.splice(ans.end(), sub.get()->GenMIRStmts(mirBuilder)); + } + return ans; +} + +std::string FEIRStmtCaseForC::DumpDotStringImpl() const { + std::stringstream ss; + ss << " " << id << ": " << GetFEIRNodeKindDescription(kind); + return ss.str(); +} + +FEIRStmtDefaultForC::FEIRStmtDefaultForC() + : FEIRStmt(FEIRNodeKind::kStmtDefaultForC) {} + +std::list FEIRStmtDefaultForC::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { + std::list ans; + StmtNode *mirLabelStmt = mirBuilder.CreateStmtLabel(AstSwitchUtil::Instance().GetTopOfNestedCaseVectors().second); + ans.emplace_back(mirLabelStmt); + for (auto &sub : subStmts) { + ans.splice(ans.end(), sub.get()->GenMIRStmts(mirBuilder)); + } + return ans; +} + +std::string FEIRStmtDefaultForC::DumpDotStringImpl() const { + std::stringstream ss; + ss << " " << id << ": " << GetFEIRNodeKindDescription(kind); + return ss.str(); +} + // ---------- FEIRStmtArrayStore ---------- FEIRStmtArrayStore::FEIRStmtArrayStore(UniqueFEIRExpr argExprElem, UniqueFEIRExpr argExprArray, UniqueFEIRExpr argExprIndex, UniqueFEIRType argTypeArray) @@ -1759,6 +1901,13 @@ BaseNode *FEIRExprDRead::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { MIRSymbol *symbol = varSrc->GenerateMIRSymbol(mirBuilder); ASSERT(type != nullptr, "type is nullptr"); AddrofNode *node = mirBuilder.CreateExprDread(*type, *symbol); + if (type->IsMIRStructType() && (!fieldName.empty() || (fieldID != 0))) { + FieldID fieldIdVar = fieldID; + if (fieldIdVar == 0) { + fieldIdVar = mirBuilder.GetStructFieldIDFromFieldName(*type, fieldName); + } + node = mirBuilder.CreateExprDread(*type, fieldIdVar, *symbol); + } return node; } @@ -1781,9 +1930,24 @@ std::unique_ptr FEIRExprIRead::CloneImpl() const { BaseNode *FEIRExprIRead::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { MIRType *returnType = retType->GenerateMIRTypeAuto(kSrcLangC); - MIRType *pointeeType = ptrType->GenerateMIRTypeAuto(kSrcLangC); - BaseNode *subNode = subExpr->GenMIRNode(mirBuilder); - return mirBuilder.CreateExprIread(*returnType, *pointeeType, fieldID, subNode); + MIRType *pointerType = ptrType->GenerateMIRTypeAuto(kSrcLangC); + BaseNode *node = subExpr->GenMIRNode(mirBuilder); + CHECK_FATAL(pointerType->IsMIRPtrType(), "Must be ptr type!"); + MIRPtrType *mirPtrType = static_cast(pointerType); + MIRType *pointedMirType = mirPtrType->GetPointedType(); + FieldID fid = fieldID; + if (pointedMirType->IsMIRStructType()) { + CHECK_FATAL(!fieldName.empty() || fid != 0, "error"); + if (fid == 0) { + fid = mirBuilder.GetStructFieldIDFromFieldName(*pointedMirType, fieldName); + } + MIRStructType *structMirType = static_cast(pointedMirType); + FieldPair fieldPair = structMirType->TraverseToFieldRef(fid); + returnType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldPair.second.first); + } else { + CHECK_FATAL(fid == 0, "fieldid must be 0!"); + } + return mirBuilder.CreateExprIread(*returnType, *mirPtrType, fid, node); } // ---------- FEIRExprAddrof ---------- @@ -2726,6 +2890,236 @@ bool FEIRExprArrayLoad::CalculateDefs4AllUsesImpl(FEIRStmtCheckPoint &checkPoint return success; } +// ---------- FEIRExprCStyleCast ---------- +FEIRExprCStyleCast::FEIRExprCStyleCast(MIRType *src, + MIRType *dest, + UniqueFEIRExpr sub, + bool isArr2Pty) + : FEIRExpr(FEIRNodeKind::kExprCStyleCast), + srcType(std::move(src)), + destType(std::move(dest)), + subExpr(std::move(sub)), + isArray2Pointer(isArr2Pty) {} + +std::unique_ptr FEIRExprCStyleCast::CloneImpl() const { + auto expr = std::make_unique(srcType, destType, + subExpr->Clone(), isArray2Pointer); + expr->SetRefName(refName); + return expr; +} + +BaseNode *FEIRExprCStyleCast::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { + BaseNode *sub = subExpr.get()->GenMIRNode(mirBuilder); + BaseNode *cvt = nullptr; + if (isArray2Pointer) { + auto *arrayType = static_cast(srcType); + ASSERT(arrayType != nullptr, "ERROR:null pointer!"); + ArrayNode *arrayNode = mirBuilder.CreateExprArray(*arrayType); + GStrIdx strIdx = GlobalTables::GetStrTable().GetStrIdxFromName(refName); + MIRSymbol *var = nullptr; + if (strIdx != 0u) { + // try to find the decl in local scope first + MIRFunction *currentFunctionInner = mirBuilder.GetCurrentFunction(); +#ifndef USE_OPS + if (currentFunctionInner != nullptr) { + var = SymbolBuilder::Instance().GetSymbolFromStrIdx(strIdx, currentFunctionInner); + } + if (var == nullptr) { + var = SymbolBuilder::Instance().GetSymbolFromStrIdx(strIdx); + } +#else + if (currentFunctionInner != nullptr) { + var = mirBuilder.GetOrCreateLocalDecl(refName.c_str(), *arrayType); + } + if (var == nullptr) { + var = mirBuilder.GetOrCreateGlobalDecl(refName.c_str(), *arrayType); + } +#endif + } + arrayNode->GetNopnd().push_back(mirBuilder.CreateExprAddrof(0, *var)); + for (uint8 i = 0; i < arrayType->GetDim(); ++i) { + arrayNode->GetNopnd().push_back(mirBuilder.CreateIntConst(0, PTY_i32)); + } + arrayNode->SetNumOpnds(static_cast(arrayType->GetDim() + 1)); + return arrayNode; + } + auto isCvtNeeded = [&](const MIRType &fromNode, const MIRType &toNode, const BaseNode &baseNode) { + if (fromNode.EqualTo(toNode)) { + return false; + } + if (baseNode.GetOpCode() == OP_bnot && baseNode.Opnd(0)->GetOpCode() == OP_constval) { + return false; + } + return true; + }; + if (sub != nullptr && srcType != nullptr && destType != nullptr && isCvtNeeded(*srcType, *destType, *sub)) { + PrimType fromType = srcType->GetPrimType(); + PrimType toType = destType->GetPrimType(); + if (fromType == toType || toType == PTY_void) { + return sub; + } + if (IsPrimitiveFloat(fromType) && IsPrimitiveInteger(toType)) { + cvt = mirBuilder.CreateExprTypeCvt(OP_trunc, *destType, *srcType, sub); + } else { + cvt = mirBuilder.CreateExprTypeCvt(OP_cvt, *destType, *srcType, sub); + } + } + return cvt; +} + +// ---------- FEIRExprAtomic ---------- +FEIRExprAtomic::FEIRExprAtomic(MIRType *ty, MIRType *ref, UniqueFEIRExpr obj, UniqueFEIRExpr val1, + UniqueFEIRExpr val2, + ASTAtomicOp atomOp) + : FEIRExpr(FEIRNodeKind::kExprAtomic), + type(ty), + refType(ref), + objExpr(std::move(obj)), + valExpr1(std::move(val1)), + valExpr2(std::move(val2)), + atomicOp(atomOp) {} + +std::unique_ptr FEIRExprAtomic::CloneImpl() const { + std::unique_ptr expr = std::make_unique(type, refType, objExpr->Clone(), + valExpr1->Clone(), valExpr2->Clone(), atomicOp); + return expr; +} + +void FEIRExprAtomic::ProcessAtomicBinary(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, + MIRSymbol &valueVar, ASTAtomicOp atomicOp) const { + BaseNode *constNode = valExpr1.get()->GenMIRNode(mirBuilder); + BaseNode *ireadNode = mirBuilder.CreateExprIread(*refType, *type, 0, &lockNode); + BaseNode *valueNode = mirBuilder.CreateExprDread(valueVar); + StmtNode *storeStmt = mirBuilder.CreateStmtDassign(valueVar, 0, ireadNode); + block.AddStatement(storeStmt); + Opcode opcode = OP_add; + if (atomicOp == kAtomicBinaryOpAdd) { + opcode = OP_add; + } else if (atomicOp == kAtomicBinaryOpSub) { + opcode = OP_sub; + } else if (atomicOp == kAtomicBinaryOpAnd) { + opcode = OP_band; + } else if (atomicOp == kAtomicBinaryOpOr) { + opcode = OP_bior; + } else if (atomicOp == kAtomicBinaryOpOr) { + opcode = OP_bxor; + } else { + } + BinaryNode *binNode = mirBuilder.CreateExprBinary(opcode, *val1Type, ireadNode, constNode); + StmtNode *addStmt = mirBuilder.CreateStmtIassign(*type, 0, &lockNode, binNode); + block.AddStatement(addStmt); + if (kAtomicBinaryOpAdd <= atomicOp && atomicOp <= kAtomicBinaryOpXor) { + BinaryNode *vbinNode = mirBuilder.CreateExprBinary(opcode, *val1Type, valueNode, constNode); + addStmt = mirBuilder.CreateStmtDassign(valueVar, 0, vbinNode); + block.AddStatement(addStmt); + } +} + +void FEIRExprAtomic::ProcessAtomicLoad(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, + MIRSymbol &valueVar) const { + BaseNode *ireadNode = mirBuilder.CreateExprIread(*refType, *type, 0, &lockNode); + StmtNode *loadStmt = mirBuilder.CreateStmtDassign(valueVar, 0, ireadNode); + block.AddStatement(loadStmt); +} + +void FEIRExprAtomic::ProcessAtomicStore(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, + MIRSymbol &valueVar) const { + BaseNode *constNode = valExpr1.get()->GenMIRNode(mirBuilder); + StmtNode *storeStmt = mirBuilder.CreateStmtIassign(*type, 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); + StmtNode *storeStmt = mirBuilder.CreateStmtDassign(valueVar, 0, ireadNode); + block.AddStatement(storeStmt); + BaseNode *constNode = valExpr1.get()->GenMIRNode(mirBuilder); + StmtNode *setStmt = mirBuilder.CreateStmtIassign(*type, 0, &lockNode, constNode); + block.AddStatement(setStmt); +} +void FEIRExprAtomic::ProcessAtomicCompareExchange(MIRBuilder &mirBuilder, BlockNode &block, BaseNode &lockNode, + MIRSymbol *valueVar) const { +#ifndef USE_OPS + valueVar = SymbolBuilder::Instance().GetOrCreateLocalSymbol(*GlobalTables::GetTypeTable().GetUInt1(), + FEUtils::GetSequentialName("valueVar"), + *mirBuilder.GetCurrentFunction()); +#else + valueVar = mirBuilder.GetOrCreateLocalDecl(FEUtils::GetSequentialName("valueVar").c_str(), + *GlobalTables::GetTypeTable().GetUInt1()); +#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 *desiredNode = valExpr2.get()->GenMIRNode(mirBuilder); + BaseNode *ireadNode = mirBuilder.CreateExprIread(*refType, *type, 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); + ifStmt->GetThenPart()->AddStatement(setStmt); + StmtNode *storeStmt = mirBuilder.CreateStmtDassign(*valueVar, 0, mirBuilder.GetConstUInt1(true)); + ifStmt->GetThenPart()->AddStatement(storeStmt); +} + +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"), + *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 *valueVar = mirBuilder.GetOrCreateLocalDecl(FEUtils::GetSequentialName("valueVar").c_str(), *refType); +#endif + BaseNode *lockNode = mirBuilder.CreateExprDread(*lockVar); + StmtNode *fetchStmt = mirBuilder.CreateStmtIassign(*type, 0, lockNode, objNode); + ASSERT_NOT_NULL(fetchStmt); + MIRModule &module = FEManager::GetModule(); + block = module.CurFuncCodeMemPool()->New(); + block->AddStatement(fetchStmt); + NaryStmtNode *syncenter = mirBuilder.CreateStmtNary(OP_syncenter, lockNode); + block->AddStatement(syncenter); + switch (atomicOp) { + case kAtomicBinaryOpAdd: + case kAtomicBinaryOpSub: + case kAtomicBinaryOpAnd: + case kAtomicBinaryOpOr: + case kAtomicBinaryOpXor: { + ProcessAtomicBinary(mirBuilder, *block, *lockNode, *valueVar, atomicOp); + break; + } + case kAtomicOpLoad: { + ProcessAtomicLoad(mirBuilder, *block, *lockNode, *valueVar); + break; + } + case kAtomicOpStore: { + ProcessAtomicStore(mirBuilder, *block, *lockNode, *valueVar); + break; + } + case kAtomicOpExchange: { + ProcessAtomicExchange(mirBuilder, *block, *lockNode, *valueVar); + break; + } + case kAtomicOpCompareExchange: { + ProcessAtomicCompareExchange(mirBuilder, *block, *lockNode, valueVar); + break; + } + default: { + CHECK_FATAL(false, "atomic opcode not yet supported %u", static_cast(atomicOp)); + break; + } + } + NaryStmtNode *syncExit = mirBuilder.CreateStmtNary(OP_syncexit, lockNode); + block->AddStatement(syncExit); + BaseNode *valueNode = mirBuilder.CreateExprDread(*valueVar); + return valueNode; +} + // ---------- FEIRStmtPesudoLabel ---------- FEIRStmtPesudoLabel::FEIRStmtPesudoLabel(uint32 argLabelIdx) : FEIRStmt(kStmtPesudoLabel), @@ -2955,4 +3349,103 @@ std::string FEIRStmtPesudoCommentForInst::DumpDotStringImpl() const { ss << " " << id << ": " << GetFEIRNodeKindDescription(kind); return ss.str(); } + +std::list FEIRStmtIAssign::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { + std::list ans; + MIRType *mirType = addrType->GenerateMIRTypeAuto(kSrcLangC); + BaseNode *addrNode = addrExpr->GenMIRNode(mirBuilder); + BaseNode *baseNode = baseExpr->GenMIRNode(mirBuilder); + FieldID fid = fieldID; + if (!fieldName.empty() && fid == 0) { + if (mirType->IsMIRPtrType()) { + MIRPtrType *mirPtrType = static_cast(mirType); + if (mirPtrType->GetPointedType()->IsMIRStructType()) { + fid = mirBuilder.GetStructFieldIDFromFieldName(*mirPtrType->GetPointedType(), fieldName); + } + } + } + IassignNode *iAssignNode = mirBuilder.CreateStmtIassign(*mirType, fid, addrNode, baseNode); + ans.emplace_back(iAssignNode); + return ans; +} + +std::list FEIRStmtIf::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { + std::list stmts; + IfStmtNode *ifNode; + BaseNode *condNode = condExpr->GenMIRNode(mirBuilder); + if (hasElse) { + ifNode = mirBuilder.CreateStmtIfThenElse(condNode); + } else { + ifNode = mirBuilder.CreateStmtIf(condNode); + } + BlockNode *thenBlock = ifNode->GetThenPart(); + for (auto &stmt : thenStmts) { + std::list mirStmts = stmt->GenMIRStmts(mirBuilder); + for (auto stmtNode : mirStmts) { + thenBlock->AddStatement(stmtNode); + } + } + if (hasElse) { + BlockNode *elseBlock = ifNode->GetElsePart(); + for (auto &stmt : elseStmts) { + std::list mirStmts = stmt->GenMIRStmts(mirBuilder); + for (auto stmtNode : mirStmts) { + elseBlock->AddStatement(stmtNode); + } + } + } + stmts.emplace_back(ifNode); + return stmts; +} + +std::list FEIRStmtDoWhile::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { + std::list stmts; + auto *whileStmtNode = mirBuilder.GetCurrentFuncCodeMp()->New(opcode); + 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; + 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 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; +} } // namespace maple diff --git a/src/mplfe/common/src/feir_type.cpp b/src/mplfe/common/src/feir_type.cpp index a371cd248fc109c6b93b70c68f08c9421d187f0b..9a5e08ea89f04012278ec1c60aa1f93232578e69 100644 --- a/src/mplfe/common/src/feir_type.cpp +++ b/src/mplfe/common/src/feir_type.cpp @@ -65,6 +65,10 @@ std::map> FEIRType::InitLangConfig() { } MIRType *FEIRType::GenerateMIRTypeAuto(MIRSrcLang argSrcLang) const { + return GenerateMIRTypeAutoImpl(argSrcLang); +} + +MIRType *FEIRType::GenerateMIRTypeAutoImpl(MIRSrcLang argSrcLang) const { MPLFE_PARALLEL_FORBIDDEN(); auto it = langConfig.find(argSrcLang); if (it == langConfig.end()) { @@ -439,26 +443,45 @@ void FEIRTypePointer::SetPrimTypeImpl(PrimType pt) { } // ---------- FEIRTypeNative ---------- -FEIRTypeNative::FEIRTypeNative(MIRType &argMIRtype, TypeDim argDim) - : FEIRTypeDefault(argMIRtype.GetPrimType(), argMIRtype.GetNameStrIdx(), argDim), +FEIRTypeNative::FEIRTypeNative(MIRType &argMIRtype) + : FEIRType(kFEIRTypeNative), mirType(argMIRtype) { - kind = kFEIRTypenNative; + kind = kFEIRTypeNative; // Right now, FEIRTypeNative is only used for c-language. srcLang = kSrcLangC; } +PrimType FEIRTypeNative::GetPrimTypeImpl() const { + return mirType.GetPrimType(); +} + +void FEIRTypeNative::SetPrimTypeImpl(PrimType pt) { + CHECK_FATAL(false, "Should not get here"); +} + +void FEIRTypeNative::CopyFromImpl(const FEIRType &type) { + CHECK_FATAL(type.GetKind() == kFEIRTypeNative, "invalid opration"); + mirType = *(type.GenerateMIRTypeAuto()); +} + +MIRType *FEIRTypeNative::GenerateMIRTypeAutoImpl() const { + return &mirType; +} + std::unique_ptr FEIRTypeNative::CloneImpl() const { - std::unique_ptr newType = std::make_unique(mirType, dim); + std::unique_ptr newType = std::make_unique(mirType); return newType; } MIRType *FEIRTypeNative::GenerateMIRTypeImpl(bool usePtr, PrimType ptyPtr) const { // To optimize for array type + WARN(kLncWarn, + "FEIRTypeNative::GenerateMIRType is not recommended, use FEIRTypeNative::GenerateMIRTypeAuto instead."); return &mirType; } bool FEIRTypeNative::IsEqualToImpl(const FEIRType &argType) const { - if (!FEIRTypeDefault::IsEqualToImpl(argType)) { + if (argType.GetKind() != kFEIRTypeNative) { return false; } const FEIRTypeNative &argTypeNative = static_cast(argType); @@ -469,7 +492,29 @@ size_t FEIRTypeNative::HashImpl() const { return mirType.GetHashIndex(); } +std::string FEIRTypeNative::GetTypeNameImpl() const { + return mirType.GetName(); +} + bool FEIRTypeNative::IsScalarImpl() const { return mirType.IsScalarType(); } + +bool FEIRTypeNative::IsRefImpl() const { + return mirType.GetPrimType() == PTY_ref; +} + +bool FEIRTypeNative::IsArrayImpl() const { + return mirType.GetKind() == kTypeArray; +} + +TypeDim FEIRTypeNative::ArrayIncrDimImpl(TypeDim delta) { + CHECK_FATAL(false, "Should not get here"); + return delta; +} + +TypeDim FEIRTypeNative::ArrayDecrDimImpl(TypeDim delta) { + CHECK_FATAL(false, "Should not get here"); + return delta; +} } // namespace maple diff --git a/src/mplfe/common/src/feir_var_name.cpp b/src/mplfe/common/src/feir_var_name.cpp index b06eb79cc3e3730f8122d5e0e79fe6f149154068..9b2b8e8683ecc2dd20fa694b11b9fc48e7298af9 100644 --- a/src/mplfe/common/src/feir_var_name.cpp +++ b/src/mplfe/common/src/feir_var_name.cpp @@ -48,48 +48,10 @@ bool FEIRVarName::EqualsToImpl(const std::unique_ptr &var) const { } FEIRVarName *ptrVarName = static_cast(var.get()); ASSERT(ptrVarName != nullptr, "ptr var is nullptr"); - return ptrVarName->nameIdx == nameIdx; + return ptrVarName->nameIdx == nameIdx && GetType()->IsEqualTo(ptrVarName->GetType()); } size_t FEIRVarName::HashImpl() const { return std::hash{}(nameIdx); } - -// ---------- FEIRVarNameSpec ---------- -std::string FEIRVarNameSpec::GetNameImpl(const MIRType &mirType) const { - std::stringstream ss; - ss << name; - if (withType) { - ss << "_"; - if (type->IsPreciseRefType()) { - ss << "R" << mirType.GetTypeIndex().GetIdx(); - } else { - ss << GetPrimTypeName(type->GetPrimType()); - } - } - return ss.str(); -} - -std::string FEIRVarNameSpec::GetNameRawImpl() const { - return name; -} - -std::unique_ptr FEIRVarNameSpec::CloneImpl() const { - std::unique_ptr var = std::make_unique(name, type->Clone(), withType); - var->SetGlobal(isGlobal); - return var; -} - -bool FEIRVarNameSpec::EqualsToImpl(const std::unique_ptr &var) const { - if (var->GetKind() != kind) { - return false; - } - FEIRVarNameSpec *ptrVarNameSpec = static_cast(var.get()); - ASSERT(ptrVarNameSpec != nullptr, "ptr var is nullptr"); - return ptrVarNameSpec->name.compare(name) == 0; -} - -size_t FEIRVarNameSpec::HashImpl() const { - return std::hash{}(name); -} } // namespace maple \ No newline at end of file diff --git a/src/mrt/deplibs/libmplandroid.so b/src/mrt/deplibs/libmplandroid.so index 48552d4c7d630b5a718984b1cd2a20c40f042154..69ce02e3388c0780bc66cfed65f426cc7e61ec6c 100755 Binary files a/src/mrt/deplibs/libmplandroid.so and b/src/mrt/deplibs/libmplandroid.so differ