diff --git a/BUILD.gn b/BUILD.gn index 7c04edc9686fa58d3dcb41dca29234365d10c144..1627e7ed69c728c252d5c27cb8395fd8aa2d2463 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -30,6 +30,15 @@ group("mplfe") { ] } +group("ast2mpl") { + deps = [] + if (IS_AST2MPL_EXISTS == "1") { + deps = [ + "${AST2MPL_ROOT}/src:ast2mpl", + ] + } +} + group("aarch64isa_headers") { exec_script( "${MAPLEALL_ROOT}/maple_be/src/cg/script/genmop.py", diff --git a/Makefile b/Makefile index 6a00054a803dc2d404b95d4a5e9ac812c006194a..dd9312517fcc8f060d60a0b2a53bf372665eb7e4 100644 --- a/Makefile +++ b/Makefile @@ -47,6 +47,10 @@ maple: maplegendef irbuild: $(call build_gn, ${GN_OPTIONS}, irbuild) +.PHONY: ast2mpl +ast2mpl: + $(call build_gn, ${GN_OPTIONS}, ast2mpl) + .PHONY: mplfe mplfe: $(call build_gn, ${GN_OPTIONS}, mplfe) diff --git a/build/config.gni b/build/config.gni index 3a0877dcc8736779f2aec5d04f515590e83b27bd..dbd3731a619a78c824a5286b52d4f72fcec017d2 100644 --- a/build/config.gni +++ b/build/config.gni @@ -16,6 +16,8 @@ GN_C_COMPILER = "${MAPLE_ROOT}/tools/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04/bin/clang" GN_CXX_COMPILER = "${MAPLE_ROOT}/tools/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04/bin/clang++" GN_AR_COMPILER = "${MAPLE_ROOT}/tools/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04/bin/llvm-ar" +LLVMINC = "${MAPLE_ROOT}/tools/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04/include" +LLVMLIBDIR = "${MAPLE_ROOT}/tools/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04/lib" target_toolchain = "//build/toolchain:clang" set_default_toolchain(target_toolchain) diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index 2f4cb8c658d33c0b243b27bd4123b5d27219c5c4..7b0a0272447bfd49c0334fb0f6a015bd9e37866d 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn @@ -33,6 +33,8 @@ MARK_CYCLE_ROOTS = false OPENSOURCE_DEPS = "${MAPLE_ROOT}/src/deplibs" OPENSOURCE_OUTPUT = "${MAPLE_ROOT}/output" +AST2MPL_ROOT= "${MAPLE_ROOT}/src/ast2mpl" +IS_AST2MPL_EXISTS = getenv("IS_AST2MPL_EXISTS") MAPLEALL_ROOT = "${MAPLE_ROOT}/src" THIRD_PARTY_ROOT = "${MAPLE_ROOT}/src/third_party" diff --git a/build/envsetup.sh b/build/envsetup.sh index 1e34dae023e19e4c40b5398c82bc139c54ce88f5..9536e0a809d798df4a4af65eddd47700d189c0ec 100644 --- a/build/envsetup.sh +++ b/build/envsetup.sh @@ -20,3 +20,9 @@ export MAPLE_ROOT=${curdir} unset MAPLE_BUILD_CORE export MAPLE_BUILD_CORE=${MAPLE_ROOT}/build/core export PATH=$PATH:${MAPLE_ROOT}/output/bin +unset IS_AST2MPL_EXISTS +if [ -d ${MAPLE_ROOT}/src/ast2mpl ]; then + export IS_AST2MPL_EXISTS=1 +else + export IS_AST2MPL_EXISTS=0 +fi diff --git a/src/bin/jbc2mpl b/src/bin/jbc2mpl index 895371403308961ccbf2355b140ca65e49ee7d72..5c8c49c614a8a67c30a2fb551cae7ceaf6f3e732 100755 Binary files a/src/bin/jbc2mpl and b/src/bin/jbc2mpl differ diff --git a/src/bin/maple b/src/bin/maple index e9e29872d65ab78e800c961b2f14a6dec11b3804..c14f4b856aeebb1fc61dd6c896ef9b9cbb194821 100755 Binary files a/src/bin/maple and b/src/bin/maple differ diff --git a/src/maple_be/include/cg/aarch64/aarch64_color_ra.h b/src/maple_be/include/cg/aarch64/aarch64_color_ra.h index 95812d8bbf197e6f3bb882fc0d6a43f7cafd8c8c..7e3d5ced79644d9828f0968a654123ac295eb77c 100644 --- a/src/maple_be/include/cg/aarch64/aarch64_color_ra.h +++ b/src/maple_be/include/cg/aarch64/aarch64_color_ra.h @@ -258,6 +258,14 @@ class LiveRange { this->priority = priority; } + bool IsMustAssigned() const { + return mustAssigned; + } + + void SetMustAssigned() { + mustAssigned = true; + } + void SetBBBuckets(uint32 bucketNum) { bbBuckets = bucketNum; } @@ -553,11 +561,12 @@ class LiveRange { private: regno_t regNO = 0; - uint32 id = 0; /* for priority tie breaker */ + uint32 id = 0; /* for priority tie breaker */ regno_t assignedRegNO = 0; /* color assigned */ - uint32 numCall = 0; + uint32 numCall = 0; RegType regType = kRegTyUndef; - float priority = 0.0; + float priority = 0.0; + bool mustAssigned = false; uint32 bbBuckets = 0; /* size of bit array for bb (each bucket == 64 bits) */ uint32 regBuckets = 0; /* size of bit array for reg (each bucket == 64 bits) */ uint32 numBBMembers = 0; /* number of bits set in bbMember */ @@ -569,7 +578,7 @@ class LiveRange { uint32 numForbidden = 0; uint32 numBBConflicts = 0; /* number of bits set in bbConflict */ - uint64 *bbConflict = nullptr; /* vreg interference from graph neighbors (bit) */ + uint64 *bbConflict = nullptr; /* vreg interference from graph neighbors (bit) */ uint64 *oldConflict = nullptr; MapleSet prefs; /* pregs that prefer */ MapleMap luMap; /* info for each bb */ @@ -1071,6 +1080,7 @@ class GraphColorRegAllocator : public AArch64RegAllocator { bbRegInfo(alloc.Adapter()), unconstrained(alloc.Adapter()), constrained(alloc.Adapter()), + mustAssigned(alloc.Adapter()), #ifdef OPTIMIZE_FOR_PROLOG intDelayed(alloc.Adapter()), fpDelayed(alloc.Adapter()), @@ -1152,12 +1162,11 @@ class GraphColorRegAllocator : public AArch64RegAllocator { void ClassifyOperand(std::unordered_set &pregs, std::unordered_set &vregs, const Operand &opnd); void SetOpndConflict(const Insn &insn, bool onlyDef); void UpdateOpndConflict(const Insn &insn, bool multiDef); + void SetupMustAssignedLiveRanges(const Insn &insn); void ComputeLiveRangesForEachDefOperand(Insn &insn, bool &multiDef); void ComputeLiveRangesForEachUseOperand(Insn &insn); void ComputeLiveRangesUpdateIfInsnIsCall(const Insn &insn); void ComputeLiveRangesUpdateLiveUnitInsnRange(BB &bb, uint32 currPoint); - void UpdateRegLive(BB &bb, BB &succBB); - void ComputeLiveOut(BB &bb); void ComputeLiveRanges(); MemOperand *CreateSpillMem(uint32 spillIdx); bool CheckOverlap(uint64 val, uint32 &lastBitSet, uint32 &overlapNum, uint32 i) const; @@ -1167,6 +1176,7 @@ class GraphColorRegAllocator : public AArch64RegAllocator { void SetBBInfoGlobalAssigned(uint32 bbID, regno_t regNO); bool HaveAvailableColor(const LiveRange &lr, uint32 num) const; void Separate(); + void SplitAndColorForEachLr(MapleVector &targetLrVec, bool isConstrained); void SplitAndColor(); void ColorForOptPrologEpilog(); bool IsLocalReg(regno_t regNO) const; @@ -1251,6 +1261,7 @@ class GraphColorRegAllocator : public AArch64RegAllocator { MapleVector bbRegInfo; /* register assignment info for each bb */ MapleVector unconstrained; MapleVector constrained; + MapleVector mustAssigned; #ifdef OPTIMIZE_FOR_PROLOG MapleVector intDelayed; MapleVector fpDelayed; diff --git a/src/maple_be/include/cg/aarch64/aarch64_emitter.h b/src/maple_be/include/cg/aarch64/aarch64_emitter.h index dd8359d7aa3cc1c9dd2dcf54da3f4606e3fa374e..1485071ed2728d1f30077fbff40f6fe5e4ed6f5b 100644 --- a/src/maple_be/include/cg/aarch64/aarch64_emitter.h +++ b/src/maple_be/include/cg/aarch64/aarch64_emitter.h @@ -15,27 +15,25 @@ #ifndef MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_EMITTER_H #define MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_EMITTER_H -#include "emit.h" +#include "asm_emit.h" namespace maplebe { using namespace maple; -class AArch64Emitter { +class AArch64AsmEmitter : public AsmEmitter { public: - explicit AArch64Emitter(CGFunc &func) : cgFunc(&func) {} - ~AArch64Emitter() = default; + AArch64AsmEmitter(CG &cg, const std::string &asmFileName) : AsmEmitter(cg, asmFileName) {} + ~AArch64AsmEmitter() = default; - void EmitRefToMethodDesc(Emitter &emitter); - void EmitRefToMethodInfo(Emitter &emitter); - void EmitMethodDesc(Emitter &emitter); - void EmitFastLSDA(); - void EmitFullLSDA(); - void EmitBBHeaderLabel(const std::string &name, LabelIdx labIdx); - void EmitJavaInsnAddr(); - void Run(); - private: - CGFunc *cgFunc; + void EmitRefToMethodDesc(FuncEmitInfo &funcEmitInfo, Emitter &emitter) override; + void EmitRefToMethodInfo(FuncEmitInfo &funcEmitInfo, Emitter &emitter) override; + void EmitMethodDesc(FuncEmitInfo &funcEmitInfo, Emitter &emitter) override; + void EmitFastLSDA(FuncEmitInfo &funcEmitInfo) override; + void EmitFullLSDA(FuncEmitInfo &funcEmitInfo) override; + void EmitBBHeaderLabel(FuncEmitInfo &funcEmitInfo, const std::string &name, LabelIdx labIdx) override; + void EmitJavaInsnAddr(FuncEmitInfo &funcEmitInfo) override; + void Run(FuncEmitInfo &funcEmitInfo) override; }; } /* namespace maplebe */ -#endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_EMITTER_H */ \ No newline at end of file +#endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_EMITTER_H */ diff --git a/src/maple_be/include/cg/asm_emit.h b/src/maple_be/include/cg/asm_emit.h new file mode 100644 index 0000000000000000000000000000000000000000..6d7afcf2a9d7e92d28c1f583b28e6e294352af64 --- /dev/null +++ b/src/maple_be/include/cg/asm_emit.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * + * http://license.coscl.org.cn/MulanPSL + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v1 for more details. + */ +#ifndef MAPLEBE_INCLUDE_CG_ASM_EMIT_H +#define MAPLEBE_INCLUDE_CG_ASM_EMIT_H + +#include "emit.h" + +namespace maplebe { +class AsmFuncEmitInfo : public FuncEmitInfo { + public: + AsmFuncEmitInfo(CGFunc &func) : FuncEmitInfo(func) {} + virtual ~AsmFuncEmitInfo() = default; +}; + +class AsmEmitter : public Emitter { + protected: + AsmEmitter(CG &cg, const std::string &asmFileName) : Emitter(cg, asmFileName) {} + virtual ~AsmEmitter() = default; + + virtual void EmitRefToMethodDesc(FuncEmitInfo &funcEmitInfo, Emitter &emitter) = 0; + virtual void EmitRefToMethodInfo(FuncEmitInfo &funcEmitInfo, Emitter &emitter) = 0; + virtual void EmitMethodDesc(FuncEmitInfo &funcEmitInfo, Emitter &emitter) = 0; + virtual void EmitFastLSDA(FuncEmitInfo &funcEmitInfo) = 0; + virtual void EmitFullLSDA(FuncEmitInfo &funcEmitInfo) = 0; + virtual void EmitBBHeaderLabel(FuncEmitInfo &funcEmitInfo, const std::string &name, LabelIdx labIdx) = 0; + virtual void EmitJavaInsnAddr(FuncEmitInfo &funcEmitInfo) = 0; + virtual void Run(FuncEmitInfo &funcEmitInfo) = 0; +}; +} /* namespace maplebe */ + +#endif /* MAPLEBE_INCLUDE_CG_ASM_EMIT_H */ diff --git a/src/maple_be/include/cg/cg_option.h b/src/maple_be/include/cg/cg_option.h index 2339424f483ff5b0a213430c2e94c05e22664b27..276c266c47e5b7b3e024a8488130bfa62efb4417 100644 --- a/src/maple_be/include/cg/cg_option.h +++ b/src/maple_be/include/cg/cg_option.h @@ -84,6 +84,12 @@ class CGOptions : public MapleDriverOptionBase { kABISoft, kABISoftFP }; + + enum EmitFileType : uint8 { + kAsm, + kObj, + kNone, + }; /* * The default CG option values are: * Don't BE_QUITE; verbose, @@ -743,6 +749,23 @@ class CGOptions : public MapleDriverOptionBase { } + static void SetEmitFileType(const std::string &type) { + if (type == "asm") { + emitFileType = kAsm; + } else if (type == "obj") { + emitFileType = kObj; + } else if (type == "null") { + emitFileType = kNone; + CHECK_FATAL(false, "null is not supported Currently."); + } else { + CHECK_FATAL(false, "unexpected file-type, only asm, obj, and null are supported"); + } + } + + static EmitFileType GetEmitFileType() { + return emitFileType; + } + static void EnableLongCalls() { genLongCalls = true; } @@ -828,6 +851,7 @@ class CGOptions : public MapleDriverOptionBase { static bool bruteForceSched; /* if true do SimulateSched */ static bool simulateSched; + static EmitFileType emitFileType; /* if true generate adrp/ldr/blr */ static bool genLongCalls; static bool gcOnly; diff --git a/src/maple_be/include/cg/emit.h b/src/maple_be/include/cg/emit.h index 450ef5167f29d59736a2bb37318936ff5bbe39ba..aad06eac189e7d655d336a613134995a460df7d6 100644 --- a/src/maple_be/include/cg/emit.h +++ b/src/maple_be/include/cg/emit.h @@ -101,20 +101,26 @@ class StructEmitInfo { uint64 totalSize = 0; }; -class Emitter { +class FuncEmitInfo { public: - Emitter(CG &cg, const std::string &asmFileName) - : cg(&cg), - rangeIdx2PrefixStr(cg.GetMIRModule()->GetMPAllocator().Adapter()), - hugeSoTargets(cg.GetMIRModule()->GetMPAllocator().Adapter()) { - outStream.open(asmFileName, std::ios::trunc); - MIRModule &mirModule = *cg.GetMIRModule(); - memPool = mirModule.GetMemPool(); - asmInfo = memPool->New(*memPool); + CGFunc &GetCGFunc() { + return cgFunc; } - ~Emitter() = default; + const CGFunc &GetCGFunc() const { + return cgFunc; + } + + protected: + explicit FuncEmitInfo(CGFunc &func) : cgFunc(func) {} + ~FuncEmitInfo() = default; + + private: + CGFunc &cgFunc; +}; +class Emitter { + public: void CloseOutput() { if (outStream.is_open()) { outStream.close(); @@ -251,6 +257,19 @@ class Emitter { } #endif + protected: + Emitter(CG &cg, const std::string &fileName) + : cg(&cg), + rangeIdx2PrefixStr(cg.GetMIRModule()->GetMPAllocator().Adapter()), + hugeSoTargets(cg.GetMIRModule()->GetMPAllocator().Adapter()) { + outStream.open(fileName, std::ios::trunc); + MIRModule &mirModule = *cg.GetMIRModule(); + memPool = mirModule.GetMemPool(); + asmInfo = memPool->New(*memPool); + } + + ~Emitter() = default; + private: AsmLabel GetTypeAsmInfoName(PrimType primType) const; void EmitDWRef(const std::string &name); diff --git a/src/maple_be/src/cg/aarch64/aarch64_color_ra.cpp b/src/maple_be/src/cg/aarch64/aarch64_color_ra.cpp index 714683e0f205832845fa75f143f6fbf59b2e00ae..73bdbc0dc7a7b4d3d4088a28f95f58c27c73c678 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_color_ra.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_color_ra.cpp @@ -849,6 +849,26 @@ void GraphColorRegAllocator::UpdateCallInfo(uint32 bbId) { } } +void GraphColorRegAllocator::SetupMustAssignedLiveRanges(const Insn &insn) { + if (!insn.IsSpecialIntrinsic()) { + return; + } + uint32 opndNum = insn.GetOperandSize(); + for (uint32 i = 0; i < opndNum; ++i) { + Operand &opnd = insn.GetOperand(i); + if (!opnd.IsRegister()) { + continue; + } + auto ®Opnd = static_cast(opnd); + regno_t regNO = regOpnd.GetRegisterNumber(); + LiveRange *lr = lrVec[regNO]; + if (lr != nullptr) { + lr->SetMustAssigned(); + lr->SetIsNonLocal(true); + } + } +} + /* * For each succ bb->GetSuccs(), if bb->liveout - succ->livein is not empty, the vreg(s) is * dead on this path (but alive on the other path as there is some use of it on the @@ -893,6 +913,7 @@ void GraphColorRegAllocator::ComputeLiveRanges() { ComputeLiveRangesForEachUseOperand(*insn); UpdateOpndConflict(*insn, multiDef); + SetupMustAssignedLiveRanges(*insn); if (ninsn != nullptr && ninsn->IsCall()) { UpdateCallInfo(bb->GetId()); @@ -1003,7 +1024,7 @@ void GraphColorRegAllocator::BuildInterferenceGraphSeparateIntFp(std::vectorGetNumBBMembers() == 1) { + if (IsLocalReg(*lr)) { continue; } #endif /* USE_LRA */ @@ -1102,6 +1123,8 @@ void GraphColorRegAllocator::Separate() { #endif /* OPTIMIZE_FOR_PROLOG */ if (HaveAvailableColor(*lr, lr->GetNumBBConflicts() + lr->GetPregvetoSize() + lr->GetForbiddenSize())) { unconstrained.emplace_back(lr); + } else if (lr->IsMustAssigned()) { + mustAssigned.emplace_back(lr); } else { constrained.emplace_back(lr); } @@ -1117,6 +1140,11 @@ void GraphColorRegAllocator::Separate() { LogInfo::MapleLogger() << lr->GetRegNO() << " "; } LogInfo::MapleLogger() << "\n"; + LogInfo::MapleLogger() << "mustAssigned : "; + for (auto lr : mustAssigned) { + LogInfo::MapleLogger() << lr->GetRegNO() << " "; + } + LogInfo::MapleLogger() << "\n"; } } @@ -1914,24 +1942,26 @@ void GraphColorRegAllocator::ColorForOptPrologEpilog() { * * Color the unconstrained LRs. */ -void GraphColorRegAllocator::SplitAndColor() { - /* handle constrained */ - while (!constrained.empty()) { - auto highestIt = GetHighPriorityLr(constrained); +void GraphColorRegAllocator::SplitAndColorForEachLr(MapleVector &targetLrVec, bool isConstrained) { + while (!targetLrVec.empty()) { + auto highestIt = GetHighPriorityLr(targetLrVec); LiveRange *lr = *highestIt; /* check those lrs in lr->sconflict which is in unconstrained whether it turns to constrined */ - if (highestIt != constrained.end()) { - constrained.erase(highestIt); + if (highestIt != targetLrVec.end()) { + targetLrVec.erase(highestIt); } else { - ASSERT(false, "Error: not in constrained"); + ASSERT(false, "Error: not in targetLrVec"); } if (AssignColorToLr(*lr)) { continue; } + if (!isConstrained) { + ASSERT(false, "unconstrained lr should be colorable"); + LogInfo::MapleLogger() << "error: LR should be colorable " << lr->GetRegNO() << "\n"; + } #ifdef USE_SPLIT SplitLr(*lr); #endif /* USE_SPLIT */ - /* * When LR is spilled, it potentially has no conflicts as * each def/use is spilled/reloaded. @@ -1944,26 +1974,17 @@ void GraphColorRegAllocator::SplitAndColor() { } #endif /* COLOR_SPLIT */ } +} + +void GraphColorRegAllocator::SplitAndColor() { + /* handle mustAssigned */ + SplitAndColorForEachLr(mustAssigned, true); + + /* handle constrained */ + SplitAndColorForEachLr(constrained, true); /* assign color for unconstained */ - while (!unconstrained.empty()) { - MapleVector::iterator highestIt = GetHighPriorityLr(unconstrained); - LiveRange *lr = *highestIt; - if (highestIt != unconstrained.end()) { - unconstrained.erase(highestIt); - } else { - ASSERT(false, "Error: not in unconstrained"); - LogInfo::MapleLogger() << "Error: not in unconstrained\n"; - /* with error, iterator not erased */ - break; - } - if (!AssignColorToLr(*lr)) { - ASSERT(false, "LR should be colorable"); - LogInfo::MapleLogger() << "error: LR should be colorable " << lr->GetRegNO() << "\n"; - /* with error, iterator not erased */ - break; - } - } + SplitAndColorForEachLr(unconstrained, false); #ifdef OPTIMIZE_FOR_PROLOG ColorForOptPrologEpilog(); diff --git a/src/maple_be/src/cg/aarch64/aarch64_emitter.cpp b/src/maple_be/src/cg/aarch64/aarch64_emitter.cpp index 3f9e47ab5a210987a142b61791ed7b16305c4f2c..000278718e2ecafac1fa7f0473f6ed814859ac61 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_emitter.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_emitter.cpp @@ -29,19 +29,21 @@ void GetMethodLabel(const std::string &methodName, std::string &methodLabel) { namespace maplebe { using namespace maple; -void AArch64Emitter::EmitRefToMethodDesc(Emitter &emitter) { - if (!cgFunc->GetFunction().IsJava()) { +void AArch64AsmEmitter::EmitRefToMethodDesc(FuncEmitInfo &funcEmitInfo, Emitter &emitter) { + CGFunc &cgFunc = funcEmitInfo.GetCGFunc(); + if (!cgFunc.GetFunction().IsJava()) { return; } std::string methodDescLabel; - GetMethodLabel(cgFunc->GetFunction().GetName(), methodDescLabel); + GetMethodLabel(cgFunc.GetFunction().GetName(), methodDescLabel); emitter.Emit("\t.word " + methodDescLabel + "-.\n"); emitter.IncreaseJavaInsnCount(); } -void AArch64Emitter::EmitRefToMethodInfo(Emitter &emitter) { - if (cgFunc->GetFunction().GetModule()->IsJavaModule()) { - std::string labelName = ".Label.name." + cgFunc->GetFunction().GetName(); +void AArch64AsmEmitter::EmitRefToMethodInfo(FuncEmitInfo &funcEmitInfo, Emitter &emitter) { + CGFunc &cgFunc = funcEmitInfo.GetCGFunc(); + if (cgFunc.GetFunction().GetModule()->IsJavaModule()) { + std::string labelName = ".Label.name." + cgFunc.GetFunction().GetName(); emitter.Emit("\t.word " + labelName + " - .\n"); } } @@ -50,23 +52,24 @@ void AArch64Emitter::EmitRefToMethodInfo(Emitter &emitter) { * emit java method description which contains address and size of local reference area * as well as method metadata. */ -void AArch64Emitter::EmitMethodDesc(Emitter &emitter) { - if (!cgFunc->GetFunction().IsJava()) { +void AArch64AsmEmitter::EmitMethodDesc(FuncEmitInfo &funcEmitInfo, Emitter &emitter) { + CGFunc &cgFunc = funcEmitInfo.GetCGFunc(); + if (!cgFunc.GetFunction().IsJava()) { return; } emitter.Emit("\t.section\t.rodata\n"); emitter.Emit("\t.align\t2\n"); std::string methodInfoLabel; - GetMethodLabel(cgFunc->GetFunction().GetName(), methodInfoLabel); + GetMethodLabel(cgFunc.GetFunction().GetName(), methodInfoLabel); emitter.Emit(methodInfoLabel + ":\n"); - EmitRefToMethodInfo(emitter); + EmitRefToMethodInfo(funcEmitInfo, emitter); /* local reference area */ - AArch64MemLayout *memLayout = static_cast(cgFunc->GetMemlayout()); + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); int32 refOffset = memLayout->GetRefLocBaseLoc(); uint32 refNum = memLayout->GetSizeOfRefLocals() / kOffsetAlign; /* for ea usage */ - AArch64CGFunc *aarchCGFunc = static_cast(cgFunc); - IntrinsiccallNode *cleanEANode = aarchCGFunc->GetCleanEANode(); + AArch64CGFunc &aarchCGFunc = static_cast(cgFunc); + IntrinsiccallNode *cleanEANode = aarchCGFunc.GetCleanEANode(); if (cleanEANode != nullptr) { refNum += cleanEANode->NumOpnds(); refOffset -= cleanEANode->NumOpnds() * kIntregBytelen; @@ -76,35 +79,37 @@ void AArch64Emitter::EmitMethodDesc(Emitter &emitter) { } /* the fast_exception_handling lsda */ -void AArch64Emitter::EmitFastLSDA() { - AArch64CGFunc *aarchCGFunc = static_cast(cgFunc); - CG *currCG = cgFunc->GetCG(); +void AArch64AsmEmitter::EmitFastLSDA(FuncEmitInfo &funcEmitInfo) { + CGFunc &cgFunc = funcEmitInfo.GetCGFunc(); + AArch64CGFunc &aarchCGFunc = static_cast(cgFunc); + CG *currCG = cgFunc.GetCG(); Emitter *emitter = currCG->GetEmitter(); - const std::string &funcName = std::string(cgFunc->GetShortFuncName().c_str()); + const std::string &funcName = std::string(cgFunc.GetShortFuncName().c_str()); /* * .word 0xFFFFFFFF * .word .Label.LTest_3B_7C_3Cinit_3E_7C_28_29V3-func_start_label */ emitter->Emit("\t.word 0xFFFFFFFF\n"); emitter->Emit("\t.word .L." + funcName + "."); - if (aarchCGFunc->NeedCleanup()) { - emitter->Emit(cgFunc->GetCleanupLabel()->GetLabelIdx()); + if (aarchCGFunc.NeedCleanup()) { + emitter->Emit(cgFunc.GetCleanupLabel()->GetLabelIdx()); } else { - ASSERT(!cgFunc->GetExitBBsVec().empty(), "exitbbsvec is empty in AArch64Emitter::EmitFastLSDA"); - emitter->Emit(cgFunc->GetExitBB(0)->GetLabIdx()); + ASSERT(!cgFunc.GetExitBBsVec().empty(), "exitbbsvec is empty in AArch64AsmEmitter::EmitFastLSDA"); + emitter->Emit(cgFunc.GetExitBB(0)->GetLabIdx()); } emitter->Emit("-.L." + funcName + ".") - .Emit(cgFunc->GetStartLabel()->GetLabelIdx()) + .Emit(cgFunc.GetStartLabel()->GetLabelIdx()) .Emit("\n"); emitter->IncreaseJavaInsnCount(); } /* the normal gcc_except_table */ -void AArch64Emitter::EmitFullLSDA() { - AArch64CGFunc *aarchCGFunc = static_cast(cgFunc); - CG *currCG = cgFunc->GetCG(); - EHFunc *ehFunc = cgFunc->GetEHFunc(); +void AArch64AsmEmitter::EmitFullLSDA(FuncEmitInfo &funcEmitInfo) { + CGFunc &cgFunc = funcEmitInfo.GetCGFunc(); + AArch64CGFunc &aarchCGFunc = static_cast(cgFunc); + CG *currCG = cgFunc.GetCG(); + EHFunc *ehFunc = cgFunc.GetEHFunc(); Emitter *emitter = currCG->GetEmitter(); /* emit header */ emitter->Emit("\t.align 2\n"); @@ -112,7 +117,7 @@ void AArch64Emitter::EmitFullLSDA() { emitter->Emit("\t.align 2\n"); /* emit LSDA header */ LSDAHeader *lsdaHeader = ehFunc->GetLSDAHeader(); - const std::string &funcName = std::string(cgFunc->GetShortFuncName().c_str()); + const std::string &funcName = std::string(cgFunc.GetShortFuncName().c_str()); emitter->EmitStmtLabel(funcName, lsdaHeader->GetLSDALabel()->GetLabelIdx()); emitter->Emit("\t.byte ").Emit(lsdaHeader->GetLPStartEncoding()).Emit("\n"); emitter->Emit("\t.byte ").Emit(lsdaHeader->GetTTypeEncoding()).Emit("\n"); @@ -126,11 +131,11 @@ void AArch64Emitter::EmitFullLSDA() { emitter->EmitLabelPair(funcName, ehFunc->GetLSDACallSiteTable()->GetCSTable()); /* callsite start */ emitter->EmitStmtLabel(funcName, ehFunc->GetLSDACallSiteTable()->GetCSTable().GetStartOffset()->GetLabelIdx()); - ehFunc->GetLSDACallSiteTable()->SortCallSiteTable([aarchCGFunc](LSDACallSite *a, LSDACallSite *b) { + ehFunc->GetLSDACallSiteTable()->SortCallSiteTable([&aarchCGFunc](LSDACallSite *a, LSDACallSite *b) { CHECK_FATAL(a != nullptr, "nullptr check"); CHECK_FATAL(b != nullptr, "nullptr check"); - LabelIDOrder id1 = aarchCGFunc->GetLabelOperand(a->csStart.GetEndOffset()->GetLabelIdx())->GetLabelOrder(); - LabelIDOrder id2 = aarchCGFunc->GetLabelOperand(b->csStart.GetEndOffset()->GetLabelIdx())->GetLabelOrder(); + LabelIDOrder id1 = aarchCGFunc.GetLabelOperand(a->csStart.GetEndOffset()->GetLabelIdx())->GetLabelOrder(); + LabelIDOrder id2 = aarchCGFunc.GetLabelOperand(b->csStart.GetEndOffset()->GetLabelIdx())->GetLabelOrder(); /* id1 and id2 should not be default value -1u */ CHECK_FATAL(id1 != 0xFFFFFFFF, "illegal label order assigned"); CHECK_FATAL(id2 != 0xFFFFFFFF, "illegal label order assigned"); @@ -151,16 +156,16 @@ void AArch64Emitter::EmitFullLSDA() { } else { ASSERT(lsdaCallSite->csAction == 0, "csAction error!"); emitter->Emit("\t.uleb128 "); - if (aarchCGFunc->NeedCleanup()) { + if (aarchCGFunc.NeedCleanup()) { /* if landing pad is 0, we emit this call site as cleanup code */ LabelPair cleaupCode; - cleaupCode.SetStartOffset(cgFunc->GetStartLabel()); - cleaupCode.SetEndOffset(cgFunc->GetCleanupLabel()); + cleaupCode.SetStartOffset(cgFunc.GetStartLabel()); + cleaupCode.SetEndOffset(cgFunc.GetCleanupLabel()); emitter->EmitLabelPair(funcName, cleaupCode); - } else if (cgFunc->GetFunction().IsJava()) { - ASSERT(!cgFunc->GetExitBBsVec().empty(), "exitbbsvec is empty in AArch64Emitter::EmitFullLSDA"); - emitter->Emit(".L." + funcName).Emit(".").Emit(cgFunc->GetExitBB(0)->GetLabIdx()); - emitter->Emit(" - .L." + funcName).Emit(".").Emit(cgFunc->GetStartLabel()->GetLabelIdx()).Emit("\n"); + } else if (cgFunc.GetFunction().IsJava()) { + ASSERT(!cgFunc.GetExitBBsVec().empty(), "exitbbsvec is empty in AArch64AsmEmitter::EmitFullLSDA"); + emitter->Emit(".L." + funcName).Emit(".").Emit(cgFunc.GetExitBB(0)->GetLabIdx()); + emitter->Emit(" - .L." + funcName).Emit(".").Emit(cgFunc.GetStartLabel()->GetLabelIdx()).Emit("\n"); } else { emitter->Emit("0\n"); } @@ -176,40 +181,40 @@ void AArch64Emitter::EmitFullLSDA() { * otherwise __cxa_call_terminate will be invoked immediately, thus the caller * does not get the chance to take charge. */ - if (aarchCGFunc->NeedCleanup() || cgFunc->GetFunction().IsJava()) { + if (aarchCGFunc.NeedCleanup() || cgFunc.GetFunction().IsJava()) { /* call site for clean-up */ LabelPair funcStart; - funcStart.SetStartOffset(cgFunc->GetStartLabel()); - funcStart.SetEndOffset(cgFunc->GetStartLabel()); + funcStart.SetStartOffset(cgFunc.GetStartLabel()); + funcStart.SetEndOffset(cgFunc.GetStartLabel()); emitter->Emit("\t.uleb128 "); emitter->EmitLabelPair(funcName, funcStart); LabelPair funcLength; - funcLength.SetStartOffset(cgFunc->GetStartLabel()); - funcLength.SetEndOffset(cgFunc->GetCleanupLabel()); + funcLength.SetStartOffset(cgFunc.GetStartLabel()); + funcLength.SetEndOffset(cgFunc.GetCleanupLabel()); emitter->Emit("\t.uleb128 "); emitter->EmitLabelPair(funcName, funcLength); LabelPair cleaupCode; - cleaupCode.SetStartOffset(cgFunc->GetStartLabel()); - cleaupCode.SetEndOffset(cgFunc->GetCleanupLabel()); + cleaupCode.SetStartOffset(cgFunc.GetStartLabel()); + cleaupCode.SetEndOffset(cgFunc.GetCleanupLabel()); emitter->Emit("\t.uleb128 "); - if (aarchCGFunc->NeedCleanup()) { + if (aarchCGFunc.NeedCleanup()) { emitter->EmitLabelPair(funcName, cleaupCode); } else { - ASSERT(!cgFunc->GetExitBBsVec().empty(), "exitbbsvec is empty in AArch64Emitter::EmitFullLSDA"); - emitter->Emit(".L." + funcName).Emit(".").Emit(cgFunc->GetExitBB(0)->GetLabIdx()); - emitter->Emit(" - .L." + funcName).Emit(".").Emit(cgFunc->GetStartLabel()->GetLabelIdx()).Emit("\n"); + ASSERT(!cgFunc.GetExitBBsVec().empty(), "exitbbsvec is empty in AArch64AsmEmitter::EmitFullLSDA"); + emitter->Emit(".L." + funcName).Emit(".").Emit(cgFunc.GetExitBB(0)->GetLabIdx()); + emitter->Emit(" - .L." + funcName).Emit(".").Emit(cgFunc.GetStartLabel()->GetLabelIdx()).Emit("\n"); } emitter->Emit("\t.uleb128 0\n"); - if (!cgFunc->GetFunction().IsJava()) { + if (!cgFunc.GetFunction().IsJava()) { /* call site for stack unwind */ LabelPair unwindStart; - unwindStart.SetStartOffset(cgFunc->GetStartLabel()); - unwindStart.SetEndOffset(cgFunc->GetCleanupLabel()); + unwindStart.SetStartOffset(cgFunc.GetStartLabel()); + unwindStart.SetEndOffset(cgFunc.GetCleanupLabel()); emitter->Emit("\t.uleb128 "); emitter->EmitLabelPair(funcName, unwindStart); LabelPair unwindLength; - unwindLength.SetStartOffset(cgFunc->GetCleanupLabel()); - unwindLength.SetEndOffset(cgFunc->GetEndLabel()); + unwindLength.SetStartOffset(cgFunc.GetCleanupLabel()); + unwindLength.SetEndOffset(cgFunc.GetEndLabel()); emitter->Emit("\t.uleb128 "); emitter->EmitLabelPair(funcName, unwindLength); emitter->Emit("\t.uleb128 0\n"); @@ -245,11 +250,12 @@ void AArch64Emitter::EmitFullLSDA() { emitter->EmitStmtLabel(funcName, lsdaHeader->GetTTypeOffset().GetEndOffset()->GetLabelIdx()); } -void AArch64Emitter::EmitBBHeaderLabel(const std::string &name, LabelIdx labIdx) { - AArch64CGFunc *aarchCGFunc = static_cast(cgFunc); - CG *currCG = cgFunc->GetCG(); +void AArch64AsmEmitter::EmitBBHeaderLabel(FuncEmitInfo &funcEmitInfo, const std::string &name, LabelIdx labIdx) { + CGFunc &cgFunc = funcEmitInfo.GetCGFunc(); + AArch64CGFunc &aarchCGFunc = static_cast(cgFunc); + CG *currCG = cgFunc.GetCG(); Emitter &emitter = *(currCG->GetEmitter()); - LabelOperand &label = aarchCGFunc->GetOrCreateLabelOperand(labIdx); + LabelOperand &label = aarchCGFunc.GetOrCreateLabelOperand(labIdx); /* if label order is default value -1, set new order */ if (label.GetLabelOrder() == 0xFFFFFFFF) { label.SetLabelOrder(currCG->GetLabelOrderCnt()); @@ -263,38 +269,40 @@ void AArch64Emitter::EmitBBHeaderLabel(const std::string &name, LabelIdx labIdx) } } -void AArch64Emitter::EmitJavaInsnAddr() { - if (cgFunc->GetFunction().IsJava()) { - Emitter *emitter = cgFunc->GetCG()->GetEmitter(); +void AArch64AsmEmitter::EmitJavaInsnAddr(FuncEmitInfo &funcEmitInfo) { + CGFunc &cgFunc = funcEmitInfo.GetCGFunc(); + if (cgFunc.GetFunction().IsJava()) { + Emitter *emitter = cgFunc.GetCG()->GetEmitter(); /* emit a comment of current address from the begining of java text section */ std::stringstream ss; ss << "\n\t// addr: 0x" << std::hex << (emitter->GetJavaInsnCount() * kInsnSize) << "\n"; - cgFunc->GetCG()->GetEmitter()->Emit(ss.str()); + cgFunc.GetCG()->GetEmitter()->Emit(ss.str()); } } -void AArch64Emitter::Run() { - AArch64CGFunc *aarchCGFunc = static_cast(cgFunc); - CG *currCG = cgFunc->GetCG(); +void AArch64AsmEmitter::Run(FuncEmitInfo &funcEmitInfo) { + CGFunc &cgFunc = funcEmitInfo.GetCGFunc(); + AArch64CGFunc &aarchCGFunc = static_cast(cgFunc); + CG *currCG = cgFunc.GetCG(); /* emit header of this function */ Emitter &emitter = *currCG->GetEmitter(); // insert for __cxx_global_var_init - if (cgFunc->GetName() == "__cxx_global_var_init") { + if (cgFunc.GetName() == "__cxx_global_var_init") { emitter.Emit("\t.section\t.init_array,\"aw\"\n"); - emitter.Emit("\t.quad\t").Emit(cgFunc->GetName()).Emit("\n"); + emitter.Emit("\t.quad\t").Emit(cgFunc.GetName()).Emit("\n"); } emitter.Emit("\n"); - EmitMethodDesc(emitter); + EmitMethodDesc(funcEmitInfo, emitter); /* emit java code to the java section. */ - if (cgFunc->GetFunction().IsJava()) { + if (cgFunc.GetFunction().IsJava()) { std::string sectionName = namemangler::kMuidJavatextPrefixStr; emitter.Emit("\t.section ." + sectionName + ",\"ax\"\n"); } else { emitter.Emit("\t.text\n"); } emitter.Emit("\t.align 2\n"); - MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(cgFunc->GetFunction().GetStIdx().Idx()); - const std::string &funcName = std::string(cgFunc->GetShortFuncName().c_str()); + MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(cgFunc.GetFunction().GetStIdx().Idx()); + const std::string &funcName = std::string(cgFunc.GetShortFuncName().c_str()); std::string funcStName = funcSt->GetName(); @@ -312,11 +320,11 @@ void AArch64Emitter::Run() { } emitter.Emit("\t.type\t" + funcStName + ", %function\n"); /* add these messege , solve the simpleperf tool error */ - EmitRefToMethodDesc(emitter); + EmitRefToMethodDesc(funcEmitInfo, emitter); emitter.Emit(funcStName + ":\n"); /* if the last insn is call, then insert nop */ bool found = false; - FOR_ALL_BB_REV(bb, aarchCGFunc) { + FOR_ALL_BB_REV(bb, &aarchCGFunc) { FOR_BB_INSNS_REV(insn, bb) { if (insn->IsMachineInstruction()) { if (insn->IsCall()) { @@ -332,13 +340,13 @@ void AArch64Emitter::Run() { } } /* emit instructions */ - FOR_ALL_BB(bb, aarchCGFunc) { + FOR_ALL_BB(bb, &aarchCGFunc) { if (currCG->GenerateVerboseCG()) { emitter.Emit("# freq:").Emit(bb->GetFrequency()).Emit("\n"); } /* emit bb headers */ if (bb->GetLabIdx() != 0) { - EmitBBHeaderLabel(funcName, bb->GetLabIdx()); + EmitBBHeaderLabel(funcEmitInfo, funcName, bb->GetLabIdx()); } FOR_BB_INSNS(insn, bb) { @@ -351,25 +359,25 @@ void AArch64Emitter::Run() { } emitter.Emit("\t.size\t" + funcStName + ", .-").Emit(funcStName + "\n"); - EHFunc *ehFunc = cgFunc->GetEHFunc(); + EHFunc *ehFunc = cgFunc.GetEHFunc(); /* emit LSDA */ if (ehFunc != nullptr) { - if (!cgFunc->GetHasProEpilogue()) { + if (!cgFunc.GetHasProEpilogue()) { emitter.Emit("\t.word 0x55555555\n"); emitter.IncreaseJavaInsnCount(); } else if (ehFunc->NeedFullLSDA()) { LSDAHeader *lsdaHeader = ehFunc->GetLSDAHeader(); /* .word .Label.lsda_label-func_start_label */ emitter.Emit("\t.word .L." + funcName).Emit(".").Emit(lsdaHeader->GetLSDALabel()->GetLabelIdx()); - emitter.Emit("-.L." + funcName).Emit(".").Emit(cgFunc->GetStartLabel()->GetLabelIdx()).Emit("\n"); + emitter.Emit("-.L." + funcName).Emit(".").Emit(cgFunc.GetStartLabel()->GetLabelIdx()).Emit("\n"); emitter.IncreaseJavaInsnCount(); } else if (ehFunc->NeedFastLSDA()) { - EmitFastLSDA(); + EmitFastLSDA(funcEmitInfo); } } - uint32 size = cgFunc->GetFunction().GetSymTab()->GetSymbolTableSize(); + uint32 size = cgFunc.GetFunction().GetSymTab()->GetSymbolTableSize(); for (size_t i = 0; i < size; ++i) { - MIRSymbol *st = cgFunc->GetFunction().GetSymTab()->GetSymbolFromStIdx(i); + MIRSymbol *st = cgFunc.GetFunction().GetSymTab()->GetSymbolFromStIdx(i); if (st == nullptr) { continue; } @@ -418,7 +426,7 @@ void AArch64Emitter::Run() { } } - for (auto *st : cgFunc->GetEmitStVec()) { + for (auto *st : cgFunc.GetEmitStVec()) { /* emit switch table only here */ ASSERT(st->IsReadOnly(), "NYI"); emitter.Emit("\n"); @@ -436,8 +444,8 @@ void AArch64Emitter::Run() { } } - for (const auto &mpPair : cgFunc->GetLabelAndValueMap()) { - LabelOperand &labelOpnd = aarchCGFunc->GetOrCreateLabelOperand(mpPair.first); + for (const auto &mpPair : cgFunc.GetLabelAndValueMap()) { + LabelOperand &labelOpnd = aarchCGFunc.GetOrCreateLabelOperand(mpPair.first); labelOpnd.Emit(emitter, nullptr); emitter.Emit(":\n"); emitter.Emit("\t.quad ").Emit(mpPair.second).Emit("\n"); @@ -445,11 +453,11 @@ void AArch64Emitter::Run() { } if (ehFunc != nullptr && ehFunc->NeedFullLSDA()) { - EmitFullLSDA(); + EmitFullLSDA(funcEmitInfo); } #ifdef EMIT_INSN_COUNT - if (cgFunc->GetFunction().IsJava()) { - EmitJavaInsnAddr(); + if (cgFunc.GetFunction().IsJava()) { + EmitJavaInsnAddr(funcEmitInfo); } #endif /* ~EMIT_INSN_COUNT */ } @@ -457,9 +465,10 @@ void AArch64Emitter::Run() { AnalysisResult *CgDoEmission::Run(CGFunc *cgFunc, CgFuncResultMgr *cgFuncResultMgr) { (void)cgFuncResultMgr; ASSERT(cgFunc != nullptr, "null ptr check"); - MemPool *memPool = NewMemPool(); - AArch64Emitter *aarch64Emitter = memPool->New(*cgFunc); - aarch64Emitter->Run(); + Emitter *emitter = cgFunc->GetCG()->GetEmitter(); + CHECK_NULL_FATAL(emitter); + AsmFuncEmitInfo funcEmitInfo(*cgFunc); + static_cast(emitter)->Run(funcEmitInfo); return nullptr; } } /* namespace maplebe */ diff --git a/src/maple_be/src/cg/cg_option.cpp b/src/maple_be/src/cg/cg_option.cpp index c5a87b6cd8ff8a96045d8da57e0c26ada650a3bb..e78f9353bb000251eb8a93bf45ba6fca35acded0 100644 --- a/src/maple_be/src/cg/cg_option.cpp +++ b/src/maple_be/src/cg/cg_option.cpp @@ -74,6 +74,7 @@ bool CGOptions::hotFix = false; bool CGOptions::debugSched = false; bool CGOptions::bruteForceSched = false; bool CGOptions::simulateSched = false; +CGOptions::EmitFileType CGOptions::emitFileType = kAsm; bool CGOptions::genLongCalls = false; bool CGOptions::gcOnly = false; bool CGOptions::quiet = true; @@ -142,6 +143,7 @@ enum OptionIndex : uint64 { kDebugSched, kBruteForceSched, kSimulateSched, + kEmitFileType, kLongCalls, }; @@ -719,6 +721,18 @@ const Descriptor kUsage[] = { " --no-simulate-schedule\n", "mplcg", {} }, + { kEmitFileType, + 0, + "", + "filetype", + kBuildTypeExperimental, + kArgCheckPolicyRequired, + " --filetype=name \tChoose a file type.\n" + " \tname=asm: Emit an assembly file (Default)\n" + " \tname=obj: Emit an object file\n" + " \tname=null: not support yet\n", + "mplcg", + {} }, { kLongCalls, kEnable, "", @@ -1020,6 +1034,9 @@ bool CGOptions::SolveOptions(const std::vector