diff --git a/src/mapleall/bin/dex2mpl b/src/mapleall/bin/dex2mpl index b1166de284b11cd90f8437f5270d9851174e7134..f81c2d35ec04100620078e8bf1d0ce32a378930c 100755 Binary files a/src/mapleall/bin/dex2mpl and b/src/mapleall/bin/dex2mpl differ diff --git a/src/mapleall/bin/jbc2mpl b/src/mapleall/bin/jbc2mpl index f4b667eddf19b55158bf2c8690d3d79de3ce44c6..1b37e3b04a12f02f27e530dfece9bfa1b0c6d216 100755 Binary files a/src/mapleall/bin/jbc2mpl and b/src/mapleall/bin/jbc2mpl differ diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h index fd4ae2a9df244255abba33a3ed43b49011796322..2cbd68cfc3bf0f4c520558f6d99defc2c67c7083 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h @@ -595,7 +595,9 @@ class AArch64MemOperand : public MemOperand { idxOpt(kIntact), noExtend(false), isStackMem(false) { - ASSERT(dSize == (k8BitSize << shift), "incompatible data size and shift amount"); + if (shift != 0 && dSize != (k8BitSize << shift)) { + ASSERT(false, "incompatible data size and shift amount"); + } if (baseOpnd.GetRegisterNumber() == RSP || baseOpnd.GetRegisterNumber() == RFP) { isStackMem = true; } diff --git a/src/mapleall/maple_be/include/cg/insn.h b/src/mapleall/maple_be/include/cg/insn.h index e8d0efe736abec8d9b3ec5559f8841142e63aa28..90d17ac0e78ced6a4af21db077279a365976eb51 100644 --- a/src/mapleall/maple_be/include/cg/insn.h +++ b/src/mapleall/maple_be/include/cg/insn.h @@ -172,7 +172,7 @@ class Insn { } virtual void SetMemOpnd(MemOperand *memOpnd) { - return; + (void)memOpnd; } virtual Operand *GetResult(uint32 index) const{ diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp index fbd2a0285a0ff33f5e02eb6500d4ded225c7a8c9..7336588d351ec975bf40eb0dba6cc1544b52ae6f 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1489,8 +1489,8 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { uint32 numRegs = (lhsSize <= k8ByteSize) ? kOneRegister : kTwoRegister; for (uint32 i = 0; i < numRegs; i++) { AArch64OfstOperand *rhsOffOpnd = &GetOrCreateOfstOpnd(rhsOffset + i * loadSize, loadSize * kBitsPerByte); - Operand &rhsmemopnd = - GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, loadSize, rhsAddrOpnd, nullptr, rhsOffOpnd, nullptr); + Operand &rhsmemopnd = GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, loadSize * kBitsPerByte, + rhsAddrOpnd, nullptr, rhsOffOpnd, nullptr); result[i] = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, loadSize)); MOperator mop1 = PickLdInsn(loadSize * kBitsPerByte, PTY_u32); Insn &ld = GetCG()->BuildInstruction(mop1, *(result[i]), rhsmemopnd); diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp index c4fff6655a0e4e2c7117e44e8e15514b08e1a211..6a5714ad91de08e296fcc9dc6ea955b5d5f5383a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp @@ -1264,7 +1264,6 @@ void AArch64Insn::SetMemOpnd(MemOperand *memOpnd) { return; } } - return ; } bool AArch64Insn::IsVolatile() const { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp index 1053988571756c373dfe959992ea2fe358cffabd..81cc38f83e3cd09da1b0915b31693277cd71246c 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp @@ -2039,7 +2039,7 @@ void ComplexMemOperandAArch64::Run(BB &bb, Insn &insn) { aarch64CGFunc->GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeLo12Li, memOpnd->GetSize(), &newBaseOpnd, nullptr, &offOpnd, stImmOpnd.GetSymbol()); - nextInsn->SetMemOpnd(static_cast(&newMemOpnd)); + nextInsn->SetMemOpnd(static_cast(&newMemOpnd)); bb.RemoveInsn(insn); CHECK_FATAL(!CGOptions::IsLazyBinding() || cgFunc.GetCG()->IsLibcore(), "this pattern can't be found in this phase"); diff --git a/src/mapleall/maple_driver/defs/phases.def b/src/mapleall/maple_driver/defs/phases.def index cd56a454402a44ee8c7045306852af4689a7945b..9db9b21400b64143e4651792ab5035b8083e30a7 100644 --- a/src/mapleall/maple_driver/defs/phases.def +++ b/src/mapleall/maple_driver/defs/phases.def @@ -24,6 +24,8 @@ ADD_PHASE("gencheckcast", JAVALANG) ADD_PHASE("javaintrnlowering", JAVALANG) ADD_PHASE("inline", Options::O2 && Options::useInline) // mephase begin +ADD_PHASE("mecfgbuild", CLANG && MeOption::optLevel >= 3) +ADD_PHASE("injectiv", CLANG && MeOption::optLevel >= 3) ADD_PHASE("mecfgbuild", MeOption::optLevel >= 2 || JAVALANG) ADD_PHASE("bypatheh", JAVALANG && MeOption::optLevel >= 2) ADD_PHASE("loopcanon", MeOption::optLevel >= 2) diff --git a/src/mapleall/maple_driver/include/driver_runner.h b/src/mapleall/maple_driver/include/driver_runner.h index add69d77ecbaaebcfc6352f9d6642fadafb183a3..4c9921e12e3e0ffce9c81e181d0d2654a4f46f2b 100644 --- a/src/mapleall/maple_driver/include/driver_runner.h +++ b/src/mapleall/maple_driver/include/driver_runner.h @@ -55,9 +55,8 @@ class DriverRunner final { DriverRunner(MIRModule *theModule, const std::vector &exeNames, InputFileType inpFileType, std::string actualInput, bool dwarf, MemPool *optMp, bool fileParsed = false, bool timePhases = false, bool genVtableImpl = false, bool genMeMpl = false) - : DriverRunner(theModule, exeNames, inpFileType, "", "", actualInput, dwarf, optMp, fileParsed, timePhases, - genVtableImpl, genMeMpl) - { + : DriverRunner(theModule, exeNames, inpFileType, "", "", actualInput, dwarf, optMp, + fileParsed, timePhases, genVtableImpl, genMeMpl) { auto lastDot = actualInput.find_last_of("."); baseName = (lastDot == std::string::npos) ? actualInput : actualInput.substr(0, lastDot); } diff --git a/src/mapleall/maple_driver/src/driver_runner.cpp b/src/mapleall/maple_driver/src/driver_runner.cpp index ed2a86e7d468e429e3e20808eafc686524e99d0a..741f050c72e7c4435bc4e9c22f7170ee73730d37 100644 --- a/src/mapleall/maple_driver/src/driver_runner.cpp +++ b/src/mapleall/maple_driver/src/driver_runner.cpp @@ -292,7 +292,7 @@ void DriverRunner::AddPhase(std::vector &phases, const std::string void DriverRunner::ProcessCGPhase(const std::string &outputFile, const std::string &originBaseName) { CHECK_MODULE(); if (withDwarf && !theModule->IsWithDbgInfo()) { - std::cout << "set up debug info " << std::endl; + LogInfo::MapleLogger() << "set up debug info " << '\n'; theMIRModule->GetDbgInfo()->BuildDebugInfo(); } if (cgOptions == nullptr) { diff --git a/src/mapleall/maple_ir/include/mir_lower.h b/src/mapleall/maple_ir/include/mir_lower.h index 2f90d5c4ac8aad7b887ffa73a1ee385bee5b462b..039c3402315ea3ceea940d73efaa356803f41a75 100644 --- a/src/mapleall/maple_ir/include/mir_lower.h +++ b/src/mapleall/maple_ir/include/mir_lower.h @@ -66,6 +66,8 @@ class MIRLower { BlockNode *LowerBlock(BlockNode&); void LowerBrCondition(BlockNode &block); void LowerFunc(MIRFunction &func); + BaseNode *LowerFarray(ArrayNode *array); + BaseNode *LowerCArray(ArrayNode *array); void ExpandArrayMrt(MIRFunction &func); IfStmtNode *ExpandArrayMrtIfBlock(IfStmtNode &node); WhileStmtNode *ExpandArrayMrtWhileBlock(WhileStmtNode &node); @@ -114,9 +116,9 @@ class MIRLower { } static bool ShouldOptArrayMrt(const MIRFunction &func); - - private: + protected: MIRModule &mirModule; + private: MIRFunction *mirFunc; MIRBuilder *mirBuilder = nullptr; uint32 lowerPhase = 0; diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 4e249212b4288b0739a04a892d03d4ca2f37c30e..9df95824217792d2d9d375b8a4addb810a19a11c 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -17,6 +17,18 @@ #define DO_LT_0_CHECK 1 namespace maple { + +static constexpr uint64 RoundUpConst(uint64 offset, uint32 align) { + return (-align) & (offset + align - 1); +} + +static inline uint64 RoundUp(uint64 offset, uint32 align) { + if (align == 0) { + return offset; + } + return RoundUpConst(offset, align); +} + LabelIdx MIRLower::CreateCondGotoStmt(Opcode op, BlockNode &blk, const IfStmtNode &ifStmt) { auto *brStmt = mirModule.CurFuncCodeMemPool()->New(op); brStmt->SetOpnd(ifStmt.Opnd(), 0); @@ -346,6 +358,189 @@ void MIRLower::LowerFunc(MIRFunction &func) { func.SetBody(newBody); } +BaseNode *MIRLower::LowerFarray(ArrayNode *array) { + auto *farrayType = static_cast(array->GetArrayType(GlobalTables::GetTypeTable())); + size_t eSize = GlobalTables::GetTypeTable().GetTypeFromTyIdx(farrayType->GetElemTyIdx())->GetSize(); + MIRType &arrayType = *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array->GetPrimType())); + /* how about multi-dimension array? */ + if (array->GetIndex(0)->GetOpCode() == OP_constval) { + const ConstvalNode *constvalNode = static_cast(array->GetIndex(0)); + if (constvalNode->GetConstVal()->GetKind() == kConstInt) { + const MIRIntConst *pIntConst = static_cast(constvalNode->GetConstVal()); + CHECK_FATAL(mirModule.IsJavaModule() || pIntConst->GetValue() >= 0, "Array index should >= 0."); + int64 eleOffset = pIntConst->GetValue() * eSize; + + BaseNode *baseNode = array->GetBase(); + if (eleOffset == 0) { + return baseNode; + } + + MIRIntConst *eleConst = + GlobalTables::GetIntConstTable().GetOrCreateIntConst(eleOffset, arrayType); + BaseNode *offsetNode = mirModule.CurFuncCodeMemPool()->New(eleConst); + offsetNode->SetPrimType(array->GetPrimType()); + + BaseNode *rAdd = mirModule.CurFuncCodeMemPool()->New(OP_add); + rAdd->SetPrimType(array->GetPrimType()); + rAdd->SetOpnd(baseNode, 0); + rAdd->SetOpnd(offsetNode, 1); + return rAdd; + } + } + + BaseNode *rMul = nullptr; + + BaseNode *baseNode = array->GetBase(); + + BaseNode *rAdd = mirModule.CurFuncCodeMemPool()->New(OP_add); + rAdd->SetPrimType(array->GetPrimType()); + rAdd->SetOpnd(baseNode, 0); + rAdd->SetOpnd(rMul, 1); + return rAdd; +} + +BaseNode *MIRLower::LowerCArray(ArrayNode *array) { + MIRType *aType = array->GetArrayType(GlobalTables::GetTypeTable()); + if (aType->GetKind() == kTypeJArray) { + return array; + } + if (aType->GetKind() == kTypeFArray) { + return LowerFarray(array); + } + + MIRArrayType *arrayType = static_cast(aType); + /* There are two cases where dimension > 1. + * 1) arrayType->dim > 1. Process the current arrayType. (nestedArray = false) + * 2) arrayType->dim == 1, but arraytype->eTyIdx is another array. (nestedArray = true) + * Assume at this time 1) and 2) cannot mix. + * Along with the array dimension, there is the array indexing. + * It is allowed to index arrays less than the dimension. + * This is dictated by the number of indexes. + */ + bool nestedArray = false; + int dim = arrayType->GetDim(); + MIRType *innerType = nullptr; + MIRArrayType *innerArrayType = nullptr; + uint64 elemSize = 0; + if (dim == 1) { + innerType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(arrayType->GetElemTyIdx()); + if (innerType->GetKind() == kTypeArray) { + nestedArray = true; + do { + innerArrayType = static_cast(innerType); + elemSize = RoundUp(innerArrayType->GetElemType()->GetSize(), + arrayType->GetElemType()->GetAlign()); + dim++; + innerType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(innerArrayType->GetElemTyIdx()); + } while (innerType->GetKind() == kTypeArray); + } + } + + int32 numIndex = static_cast(array->NumOpnds()) - 1; + MIRArrayType *curArrayType = arrayType; + BaseNode *resNode = array->GetIndex(0); + if (dim > 1) { + BaseNode *prevNode = nullptr; + for (int i = 0; (i < dim) && (i < numIndex); i++) { + uint32 mpyDim = 1; + if (nestedArray) { + CHECK_FATAL(arrayType->GetSizeArrayItem(0) > 0, "Zero size array dimension"); + innerType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(curArrayType->GetElemTyIdx()); + curArrayType = static_cast(innerType); + while (innerType->GetKind() == kTypeArray) { + innerArrayType = static_cast(innerType); + mpyDim *= innerArrayType->GetSizeArrayItem(0); + innerType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(innerArrayType->GetElemTyIdx()); + } + } else { + CHECK_FATAL(arrayType->GetSizeArrayItem(static_cast(i)) > 0, "Zero size array dimension"); + for (int j = i + 1; j < dim; j++) { + mpyDim *= arrayType->GetSizeArrayItem(static_cast(j)); + } + } + + BaseNode *index = static_cast(array->GetIndex(static_cast(i))); + bool isConst = false; + int64 indexVal = 0; + if (index->op == OP_constval) { + ConstvalNode *constNode = static_cast(index); + indexVal = (static_cast(constNode->GetConstVal()))->GetValue(); + isConst = true; + MIRIntConst *newConstNode = mirModule.GetMemPool()->New( + indexVal * static_cast(mpyDim), + *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array->GetPrimType()))); + BaseNode *newValNode = mirModule.CurFuncCodeMemPool()->New(newConstNode); + newValNode->SetPrimType(array->GetPrimType()); + if (i == 0) { + prevNode = newValNode; + continue; + } else { + resNode = newValNode; + } + } + if (i > 0 && isConst == false) { + resNode = array->GetIndex(static_cast(i)); + } + + BaseNode *mpyNode; + if (isConst) { + MIRIntConst *mulConst = mirModule.GetMemPool()->New( + static_cast(mpyDim) * indexVal, + *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array->GetPrimType()))); + BaseNode *mulSize = mirModule.CurFuncCodeMemPool()->New(mulConst); + mulSize->SetPrimType(array->GetPrimType()); + mpyNode = mulSize; + } else if (mpyDim == 1 && prevNode) { + mpyNode = prevNode; + prevNode = resNode; + } else { + mpyNode = mirModule.CurFuncCodeMemPool()->New(OP_mul); + mpyNode->SetPrimType(array->GetPrimType()); + MIRIntConst *mulConst = mirModule.GetMemPool()->New( + mpyDim, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array->GetPrimType()))); + BaseNode *mulSize = mirModule.CurFuncCodeMemPool()->New(mulConst); + mulSize->SetPrimType(array->GetPrimType()); + mpyNode->SetOpnd(mulSize, 0); + mpyNode->SetOpnd(resNode, 1); + } + if (i == 0) { + prevNode = mpyNode; + continue; + } + BaseNode *newResNode = mirModule.CurFuncCodeMemPool()->New(OP_add); + newResNode->SetPrimType(array->GetPrimType()); + newResNode->SetOpnd(mpyNode, 0); + newResNode->SetOpnd(prevNode, 1); + prevNode = newResNode; + } + resNode = prevNode; + } + + BaseNode *rMul = nullptr; + // esize is the size of the array element (eg. int = 4 long = 8) + uint64 esize; + if (nestedArray) { + esize = elemSize; + } else { + esize = arrayType->GetElemType()->GetSize(); + } + Opcode opadd = OP_add; + MIRIntConst *econst = mirModule.GetMemPool()->New(esize, + *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array->GetPrimType()))); + BaseNode *eSize = mirModule.CurFuncCodeMemPool()->New(econst); + eSize->SetPrimType(array->GetPrimType()); + rMul = mirModule.CurFuncCodeMemPool()->New(OP_mul); + rMul->SetPrimType(array->GetPrimType()); + rMul->SetOpnd(resNode, 0); + rMul->SetOpnd(eSize, 1); + BaseNode *baseNode = array->GetBase(); + BaseNode *rAdd = mirModule.CurFuncCodeMemPool()->New(opadd); + rAdd->SetPrimType(array->GetPrimType()); + rAdd->SetOpnd(baseNode, 0); + rAdd->SetOpnd(rMul, 1); + return rAdd; +} + IfStmtNode *MIRLower::ExpandArrayMrtIfBlock(IfStmtNode &node) { if (node.GetThenPart() != nullptr) { node.SetThenPart(ExpandArrayMrtBlock(*node.GetThenPart())); diff --git a/src/mapleall/maple_me/BUILD.gn b/src/mapleall/maple_me/BUILD.gn index 2f8e6db555985fc3ed2e73c6a8cfb2744f7f9176..9e6567c90f34981ae41a62a811fa187e1f31f7a2 100755 --- a/src/mapleall/maple_me/BUILD.gn +++ b/src/mapleall/maple_me/BUILD.gn @@ -71,8 +71,8 @@ src_libmplme = [ "src/me_ssa_lpre.cpp", "src/me_ssu_pre.cpp", "src/ssa_epre.cpp", - "src/ssa_epre_for_sr.cpp", "src/ssa_pre.cpp", + "src/ssa_epre_for_sr.cpp", "src/occur.cpp", "src/me_inequality_graph.cpp", "src/me_abco.cpp", @@ -90,6 +90,8 @@ src_libmplme = [ "src/me_func_opt.cpp", "src/me_verify.cpp", "src/me_fsaa.cpp", + "src/lfo_mir_lower.cpp", + "src/lfo_inject_iv.cpp", ] src_libmplmewpo = [ diff --git a/src/mapleall/maple_me/include/lfo_function.h b/src/mapleall/maple_me/include/lfo_function.h new file mode 100644 index 0000000000000000000000000000000000000000..5a74f9ff37b19ee025a3f46e859ef7e176a5d185 --- /dev/null +++ b/src/mapleall/maple_me/include/lfo_function.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. + * You can use this software according to the terms and conditions of the MulanPSL - 2.0. + * You may obtain a copy of MulanPSL - 2.0 at: + * + * https://opensource.org/licenses/MulanPSL-2.0 + * + * 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 MulanPSL - 2.0 for more details. + */ + +#ifndef MAPLE_LFO_INCLUDE_LFO_FUNCTION_H +#define MAPLE_LFO_INCLUDE_LFO_FUNCTION_H +#include "lfo_mir_nodes.h" +#include "me_ir.h" + +namespace maple { + +class MeFunction; + +class LfoWhileInfo { + public: + MIRSymbol *injectedIVSym = nullptr; // the injected IV + OriginalSt *ivOst = nullptr; // the primary IV + MeExpr *initExpr = nullptr; + int32 stepValue = 0; + MeExpr *tripCount = nullptr; + bool canConvertDoloop = false; +}; + +class LfoIfInfo { + public: + LabelIdx endLabel = 0; // the label that is out of the if statement + LabelIdx elseLabel = 0; // the label that is the begin of else branch +}; + + +class LfoFunction { + public: + MemPool *lfomp; + MapleAllocator lfoAlloc; + MeFunction *meFunc; + MapleMap label2WhileInfo; // key is label at beginning of lowered while code sequence + MapleMap label2IfInfo; // key is target label of first conditional branch of lowered if code sequence + MapleSet lfoCreatedLabelSet; // for the labels that were created by lfo, we won't emit it + + public: + LfoFunction(MemPool *mp, MeFunction *func) : + lfomp(mp), + lfoAlloc(mp), + meFunc(func), + label2WhileInfo(lfoAlloc.Adapter()), + label2IfInfo(lfoAlloc.Adapter()), + lfoCreatedLabelSet(lfoAlloc.Adapter()) {} + + void SetLabelCreatedByLfo(LabelIdx lbidx) { + lfoCreatedLabelSet.insert(lbidx); + } + + bool LabelCreatedByLfo(LabelIdx lbidx) { + return lfoCreatedLabelSet.count(lbidx) != 0; + } +}; + +} // namespace maple +#endif // MAPLE_LFO_INCLUDE_LFO_FUNCTION_H diff --git a/src/mapleall/maple_me/include/lfo_inject_iv.h b/src/mapleall/maple_me/include/lfo_inject_iv.h new file mode 100644 index 0000000000000000000000000000000000000000..1181f2b6f20fd052ca18c310b5939bc6e8f6deb4 --- /dev/null +++ b/src/mapleall/maple_me/include/lfo_inject_iv.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. + * You can use this software according to the terms and conditions of the MulanPSL - 2.0. + * You may obtain a copy of MulanPSL - 2.0 at: + * + * https://opensource.org/licenses/MulanPSL-2.0 + * + * 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 MulanPSL - 2.0 for more details. + */ + +#ifndef MAPLE_ME_INCLUDE_LFO_INJECT_IV_H +#define MAPLE_ME_INCLUDE_LFO_INJECT_IV_H +#include "me_phase.h" + +namespace maple { + +/*emit ir to specified file*/ +class DoLfoInjectIV : public MeFuncPhase { + public: + DoLfoInjectIV(MePhaseID id) : MeFuncPhase(id) {} + + AnalysisResult *Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr*) override; + std::string PhaseName() const override { return "injectiv"; } +}; + +} // namespace maple +#endif // MAPLE_ME_INCLUDE_LFO_INJECT_IV_H diff --git a/src/mapleall/maple_me/include/lfo_mir_lower.h b/src/mapleall/maple_me/include/lfo_mir_lower.h new file mode 100644 index 0000000000000000000000000000000000000000..cb3aa490db63c9d41c860372fbc54d5d32f90908 --- /dev/null +++ b/src/mapleall/maple_me/include/lfo_mir_lower.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. + * You can use this software according to the terms and conditions of the MulanPSL - 2.0. + * You may obtain a copy of MulanPSL - 2.0 at: + * + * https://opensource.org/licenses/MulanPSL-2.0 + * + * 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 MulanPSL - 2.0 for more details. + */ + +#ifndef MAPLE_ME_INCLUDE_LFO_MIR_LOWER_H +#define MAPLE_ME_INCLUDE_LFO_MIR_LOWER_H +#include "mir_lower.h" +#include "me_function.h" +namespace maple { +class LFOMIRLower : public MIRLower { + public: + MeFunction *func; + LfoFunction *lfoFunc; + + public: + LFOMIRLower(MIRModule &mod, MeFunction *f) : MIRLower(mod, f->GetMirFunc()), + func(f), + lfoFunc(f->GetLfoFunc()) {} + + BlockNode *LowerWhileStmt(WhileStmtNode&); + BlockNode *LowerIfStmt(IfStmtNode &ifstmt, bool recursive = true); +}; +} +#endif // MAPLE_ME_INCLUDE_LFO_MIR_LOWER_H diff --git a/src/mapleall/maple_me/include/lfo_mir_nodes.h b/src/mapleall/maple_me/include/lfo_mir_nodes.h new file mode 100644 index 0000000000000000000000000000000000000000..fe408391352d1a824148b2548fb65f35f8fa4e16 --- /dev/null +++ b/src/mapleall/maple_me/include/lfo_mir_nodes.h @@ -0,0 +1,335 @@ +/* + * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. + * You can use this software according to the terms and conditions of the MulanPSL - 2.0. + * You may obtain a copy of MulanPSL - 2.0 at: + * + * https://opensource.org/licenses/MulanPSL-2.0 + * + * 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 MulanPSL - 2.0 for more details. + */ + +#ifndef MAPLE_ME_INCLUDE_LFO_MIR_NODES_H_ +#define MAPLE_ME_INCLUDE_LFO_MIR_NODES_H_ +#include "me_ir.h" +#include "mir_nodes.h" + +namespace maple { + +class LfoParentPart { + public: + LfoParentPart *parent; + + public: + LfoParentPart (LfoParentPart *pt) : parent(pt) {} + virtual BaseNode *Cvt2BaseNode() = 0; + bool IsParentOf(LfoParentPart *canNode) { + LfoParentPart *dParent = canNode->parent; + while(dParent && dParent != this) + dParent = dParent->parent; + return dParent != NULL; + } +}; + +class LfoUnaryNode : public UnaryNode, public LfoParentPart{ + public: + LfoUnaryNode(Opcode o, PrimType ptyp, LfoParentPart *parent) : UnaryNode(o, ptyp), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoTypeCvtNode : public TypeCvtNode, public LfoParentPart { + public: + LfoTypeCvtNode(Opcode o, PrimType ptyp, LfoParentPart *parent) : + TypeCvtNode(o, ptyp), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoRetypeNode : public RetypeNode, public LfoParentPart { + public: + LfoRetypeNode(Opcode o, PrimType ptyp, LfoParentPart *parent) : + RetypeNode(ptyp), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoExtractbitsNode : public ExtractbitsNode, public LfoParentPart { + public: + LfoExtractbitsNode(Opcode o, PrimType ptyp, LfoParentPart *parent) : ExtractbitsNode(o, ptyp), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoIreadNode : public IreadNode, public LfoParentPart { + public: + IvarMeExpr *ivarx; + + public: + LfoIreadNode(Opcode o, PrimType ptyp, LfoParentPart *parent, IvarMeExpr *v) : + IreadNode(o, ptyp), LfoParentPart(parent), ivarx(v) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoIaddrofNode : public IreadNode, public LfoParentPart { + public: + LfoIaddrofNode(Opcode o, PrimType pty, LfoParentPart *parent) : IreadNode(o, pty), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoBinaryNode : public BinaryNode, public LfoParentPart { + public: + LfoBinaryNode (Opcode o, PrimType typ, LfoParentPart *parent) : BinaryNode (o,typ), + LfoParentPart (parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoCompareNode : public CompareNode, public LfoParentPart { + public: + LfoCompareNode (Opcode o, PrimType typ, PrimType otype, BaseNode *l, BaseNode *r, LfoParentPart *parent) : + CompareNode (o, typ, otype, l, r), LfoParentPart (parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoTernaryNode : public TernaryNode, public LfoParentPart { + public: + LfoTernaryNode (Opcode o, PrimType ptyp, LfoParentPart *parent) : TernaryNode(o, ptyp), + LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoNaryNode : public NaryNode, public LfoParentPart { + public: + LfoNaryNode (MapleAllocator *allc, Opcode o, PrimType pty, LfoParentPart *parent) : NaryNode (*allc, o, pty), + LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoIntrinsicopNode : public IntrinsicopNode, public LfoParentPart { + public: + LfoIntrinsicopNode (MapleAllocator *allc, Opcode o, PrimType ptyp, TyIdx tidx, LfoParentPart *parent) : + IntrinsicopNode(*allc, o, ptyp, tidx), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoConstvalNode : public ConstvalNode, public LfoParentPart { + public: + LfoConstvalNode(MIRConst *constv, LfoParentPart *parent) : ConstvalNode(constv->GetType().GetPrimType(), constv), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoConststrNode : public ConststrNode, public LfoParentPart { + public: + LfoConststrNode(PrimType ptyp, UStrIdx i, LfoParentPart *parent) : ConststrNode(ptyp, i), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoConststr16Node : public Conststr16Node, public LfoParentPart { + public: + LfoConststr16Node(PrimType ptyp, U16StrIdx i, LfoParentPart *parent) : Conststr16Node(ptyp, i), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoSizeoftypeNode : public SizeoftypeNode, public LfoParentPart { + public: + LfoSizeoftypeNode(PrimType ptyp, TyIdx tidx, LfoParentPart *parent) : SizeoftypeNode(ptyp, tidx), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoArrayNode : public ArrayNode, public LfoParentPart { + public: + LfoArrayNode(MapleAllocator *allc, PrimType typ, TyIdx idx, LfoParentPart *parent) : ArrayNode (*allc, typ, idx), LfoParentPart (parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoDreadNode : public AddrofNode, public LfoParentPart { + public: + VarMeExpr *varx; + + public: + LfoDreadNode(PrimType ptyp, StIdx sidx, FieldID fid, LfoParentPart *parent, VarMeExpr *v) : + AddrofNode(OP_dread, ptyp, sidx, fid), LfoParentPart(parent), varx(v) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoAddrofNode : public AddrofNode, public LfoParentPart { + public: + LfoAddrofNode(PrimType ptyp, StIdx sidx, FieldID fid, LfoParentPart *parent) : AddrofNode(OP_addrof, ptyp, sidx, fid), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoRegreadNode : public RegreadNode, public LfoParentPart { + public: + ScalarMeExpr *scalarx; + + public: + LfoRegreadNode(LfoParentPart *parent, ScalarMeExpr *s) : RegreadNode(), LfoParentPart(parent), scalarx(s) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoAddroffuncNode : public AddroffuncNode, public LfoParentPart { + public: + LfoAddroffuncNode(PrimType ptyp, PUIdx pidx, LfoParentPart *parent) : AddroffuncNode(ptyp, pidx), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoAddroflabelNode : public AddroflabelNode, public LfoParentPart { + public: + LfoAddroflabelNode(uint32 o, LfoParentPart *parent) : AddroflabelNode(o), LfoParentPart (parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoGCMallocNode : public GCMallocNode, public LfoParentPart { + public: + LfoGCMallocNode(Opcode o, PrimType pty, TyIdx tidx, LfoParentPart *parent) : GCMallocNode(o, pty, tidx), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoFieldsDistNode : public FieldsDistNode, public LfoParentPart { + public: + LfoFieldsDistNode(PrimType ptyp, TyIdx tidx, FieldID f1, FieldID f2, LfoParentPart *parent) : + FieldsDistNode(ptyp, tidx, f1, f2), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoIassignNode : public IassignNode, public LfoParentPart { + public: + IassignMeStmt *iasgn; + + public: + LfoIassignNode(LfoParentPart *parent, IassignMeStmt *ia) : IassignNode(), LfoParentPart(parent), iasgn(ia) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoGotoNode : public GotoNode, public LfoParentPart { + public: + LfoGotoNode (Opcode o, LfoParentPart *parent) : GotoNode(o), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoDassignNode : public DassignNode, public LfoParentPart { + public: + DassignMeStmt *dasgn; + + public: + LfoDassignNode(LfoParentPart *parent, DassignMeStmt *das) : DassignNode(), LfoParentPart(parent), dasgn(das) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoRegassignNode : public RegassignNode, public LfoParentPart { + public: + AssignMeStmt *asgn; + + public: + LfoRegassignNode(LfoParentPart *parent, AssignMeStmt *as) : RegassignNode(), LfoParentPart(parent), asgn(as) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoCondGotoNode : public CondGotoNode, public LfoParentPart { + public: + LfoCondGotoNode(Opcode o, LfoParentPart *parent) : CondGotoNode(o), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoWhileStmtNode : public WhileStmtNode, public LfoParentPart { + public: + LfoWhileStmtNode(LfoParentPart *parent) : WhileStmtNode(OP_while), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoDoloopNode : public DoloopNode, public LfoParentPart { + public: + LfoDoloopNode (LfoParentPart *parent) : DoloopNode (), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } + void InitLfoDoloopNode (StIdx stIdx, bool ispg, BaseNode *startExp, BaseNode *contExp, BaseNode *incrExp, BlockNode *blk) { + SetDoVarStIdx(stIdx); + SetIsPreg(ispg); + SetStartExpr(startExp); + SetContExpr(contExp); + SetIncrExpr(incrExp); + SetDoBody(blk); + } +}; + +class LfoNaryStmtNode : public NaryStmtNode, public LfoParentPart { + public: + LfoNaryStmtNode (MapleAllocator *allc, Opcode o, LfoParentPart *parent) : + NaryStmtNode(*allc, o), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoReturnStmtNode : public NaryStmtNode, public LfoParentPart { + public: + RetMeStmt *retmestmt; + + public: + LfoReturnStmtNode(MapleAllocator *allc, LfoParentPart *parent, RetMeStmt *ret) : + NaryStmtNode(*allc, OP_return), LfoParentPart(parent), retmestmt(ret) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoCallNode : public CallNode, public LfoParentPart { + public: + CallMeStmt *callmestmt; + + public: + LfoCallNode(MapleAllocator *allc, Opcode o, LfoParentPart *parent, CallMeStmt *cl) : CallNode(*allc, o), LfoParentPart(parent), callmestmt(cl) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoIcallNode : public IcallNode, public LfoParentPart { + public: + IcallMeStmt *icallmestmt; + + public: + LfoIcallNode (MapleAllocator *allc, Opcode o, TyIdx idx, LfoParentPart *parent, IcallMeStmt *ic) : + IcallNode (*allc, o, idx), LfoParentPart(parent), icallmestmt(ic) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoIntrinsiccallNode : public IntrinsiccallNode, public LfoParentPart { + public: + IntrinsiccallMeStmt *intrinmestmt; + + public: + LfoIntrinsiccallNode (MapleAllocator *allc, Opcode o, MIRIntrinsicID id, LfoParentPart *parent, IntrinsiccallMeStmt *intncall) : + IntrinsiccallNode(*allc, o, id), LfoParentPart(parent), intrinmestmt(intncall) {} + BaseNode *Cvt2BaseNode () { return this; } +}; + +class LfoIfStmtNode : public IfStmtNode, public LfoParentPart { + public: + LfoIfStmtNode(LfoParentPart *parent) : IfStmtNode(),LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoBlockNode : public BlockNode, public LfoParentPart { + public: + LfoBlockNode (LfoParentPart *parent) : BlockNode(),LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoStmtNode : public StmtNode, public LfoParentPart { + public: + LfoStmtNode (LfoParentPart *parent, Opcode o) : StmtNode (o), + LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoUnaryStmtNode : public UnaryStmtNode, public LfoParentPart { + public: + LfoUnaryStmtNode(Opcode o, LfoParentPart *parent) : UnaryStmtNode(o), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { + return this; + } +}; + +class LfoSwitchNode : public SwitchNode, public LfoParentPart { + public: + LfoSwitchNode(MapleAllocator *allc, LfoParentPart *parent) : + SwitchNode(*allc), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +} // namespace maple +#endif // MAPLE_LFO_INCLUDE_LFO_MIR_NODES_H_ diff --git a/src/mapleall/maple_me/include/me_function.h b/src/mapleall/maple_me/include/me_function.h index ab38ee0cd13168d1de1add7a0b635c6e24ca9a7f..b64e32ce0217b9825396be64d8926dd4ff2f7e8d 100644 --- a/src/mapleall/maple_me/include/me_function.h +++ b/src/mapleall/maple_me/include/me_function.h @@ -26,6 +26,7 @@ #include "func_emit.h" #include "me_ir.h" #include "profile.h" +#include "lfo_function.h" namespace maple { class MeCFG; // circular dependency exists, no other choice @@ -156,7 +157,10 @@ class MeFunction : public FuncEmit { mirModule(*mod), mirFunc(func), laidOutBBVec(alloc.Adapter()), - fileName(fileName, memPool) {} + fileName(fileName, memPool), + lfoFunc(nullptr), lfoMp(nullptr) { + isLfo = (MeOption::optLevel == 3); + } ~MeFunction() override = default; @@ -311,6 +315,11 @@ class MeFunction : public FuncEmit { MIRFunction *CurFunction() const { return mirModule.CurFunction(); } + void SetLfoFunc(LfoFunction *lfoF) { lfoFunc = lfoF; } + LfoFunction *GetLfoFunc() { return lfoFunc; } + void SetLfoMempool(MemPool *mp) { lfoMp = mp; } + MemPool *GetLfoMempool() { return lfoMp; } + bool IsLfo() const { return isLfo; } private: MemPool *memPool; StackMemPool &stackMP; @@ -332,6 +341,10 @@ class MeFunction : public FuncEmit { bool profValid = false; IRProfileDesc *profileDesc = nullptr; uint32 frequency = 0; + // lfo + bool isLfo; + LfoFunction *lfoFunc; + MemPool *lfoMp; // used for lfo function }; } // namespace maple #endif // MAPLE_ME_INCLUDE_ME_FUNCTION_H diff --git a/src/mapleall/maple_me/include/me_ir.h b/src/mapleall/maple_me/include/me_ir.h index 80041f17cd8b846be5d6acc1cdcbcb7f4abaabef..b29cea191db926d899f7f571985e4f69f52ae57c 100644 --- a/src/mapleall/maple_me/include/me_ir.h +++ b/src/mapleall/maple_me/include/me_ir.h @@ -1568,7 +1568,7 @@ class AssignMeStmt : public MeStmt { bool needIncref = false; // to be determined by analyzerc phase bool needDecref = false; // to be determined by analyzerc phase public: - bool isIncDecStmt = false;// has the form of an increment or decrement stmt + bool isIncDecStmt = false; // has the form of an increment or decrement stmt }; class DassignMeStmt : public AssignMeStmt { diff --git a/src/mapleall/maple_me/include/me_loop_canon.h b/src/mapleall/maple_me/include/me_loop_canon.h index b917fab6f9bb493c4562d1a0471f6549faa964a1..239774d062a6e96ab39a8b1284c8d44b996a326f 100644 --- a/src/mapleall/maple_me/include/me_loop_canon.h +++ b/src/mapleall/maple_me/include/me_loop_canon.h @@ -30,7 +30,7 @@ class MeDoLoopCanon : public MeFuncPhase { std::string PhaseName() const override { return "loopcanon"; } - + bool cfgchanged = false; private: using Key = std::pair; std::map> heads; diff --git a/src/mapleall/maple_me/include/me_phases.def b/src/mapleall/maple_me/include/me_phases.def index c625af60c7c8621f1060c3b410105365dfa25343..290eeab33a9d16bb63eb1b56bd04b3dae6d4db22 100644 --- a/src/mapleall/maple_me/include/me_phases.def +++ b/src/mapleall/maple_me/include/me_phases.def @@ -50,6 +50,7 @@ FUNCAPHASE(MeFuncPhase_MEVERIFY, MeDoVerify) FUNCTPHASE(MeFuncPhase_INTRACONSTPROP, MeDoIntraConstProp) FUNCTPHASE(MeFuncPhase_INTERCONSTPROP, MeDoInterConstProp) FUNCAPHASE(MeFuncPhase_MECFG, MeDoMeCfg) +FUNCTPHASE(MeFuncPhase_LFOINJECTIV, DoLfoInjectIV) #if MIR_JAVA FUNCTPHASE(MeFuncPhase_SYNCSELECT, MeDoSyncSelect) #endif diff --git a/src/mapleall/maple_me/include/ssa_epre.h b/src/mapleall/maple_me/include/ssa_epre.h index 88e5833eab0384fa98879ea8a02833ccb877e778..a360c9ca6bb4eb25e162ae7f410e707c80eae822 100644 --- a/src/mapleall/maple_me/include/ssa_epre.h +++ b/src/mapleall/maple_me/include/ssa_epre.h @@ -33,7 +33,8 @@ class SSAEPre : public SSAPre { void GenerateReloadRealOcc(MeRealOcc &realOcc) override; MeExpr *PhiOpndFromRes(MeRealOcc &realZ, size_t j) const override; void ComputeVarAndDfPhis() override; - void BuildWorkListExpr(MeStmt &meStmt, int32 seqStmt, MeExpr&, bool isReBuild, MeExpr *tempVar, bool isRootExpr) override; + void BuildWorkListExpr(MeStmt &meStmt, int32 seqStmt, MeExpr&, bool isReBuild, + MeExpr *tempVar, bool isRootExpr) override; void BuildWorkListIvarLHSOcc(MeStmt &meStmt, int32 seqStmt, bool isReBuild, MeExpr *tempVar) override; void CollectVarForMeExpr(MeExpr &meExpr, std::vector &varVec) const override; void CollectVarForCand(MeRealOcc &realOcc, std::vector &varVec) const override; @@ -72,7 +73,6 @@ class SSAEPre : public SSAPre { std::set *needRepairInjuringDefs, std::set *repairedInjuringDefs) override; - private: bool epreIncludeRef; bool enableLHSIvar; }; diff --git a/src/mapleall/maple_me/include/ssa_pre.h b/src/mapleall/maple_me/include/ssa_pre.h index f91b312f8d4d0a52b6e67aed04c305ed87779496..b242e7529bcb8fc69acd7825196ef84dea473dad 100644 --- a/src/mapleall/maple_me/include/ssa_pre.h +++ b/src/mapleall/maple_me/include/ssa_pre.h @@ -203,11 +203,23 @@ class SSAPre { virtual VarMeExpr *ResolveAllInjuringDefs(VarMeExpr *varx) const { return varx; } virtual RegMeExpr *ResolveAllInjuringDefs(RegMeExpr *regx) const { return regx; } virtual MeExpr *ResolveAllInjuringDefs(MeExpr *x) const { return x; } - virtual void SubstituteOpnd(MeExpr *x, MeExpr *oldopnd, MeExpr *newopnd) {} - virtual void SRSetNeedRepair(MeOccur *useocc, std::set *needRepairInjuringDefs) {} + virtual void SubstituteOpnd(MeExpr *x, MeExpr *oldopnd, MeExpr *newopnd) { + (void)x; + (void)oldopnd; + (void)newopnd; + } + virtual void SRSetNeedRepair(MeOccur *useocc, std::set *needRepairInjuringDefs) { + (void)useocc; + (void)needRepairInjuringDefs; + } virtual MeExpr *SRRepairInjuries(MeOccur *useocc, std::set *needRepairInjuringDefs, - std::set *repairedInjuringDefs) { return nullptr; } + std::set *repairedInjuringDefs) { + (void)useocc; + (void)needRepairInjuringDefs; + (void)repairedInjuringDefs; + return nullptr; + } IRMap *irMap; SSATab *ssaTab; diff --git a/src/mapleall/maple_me/include/ssa_tab.h b/src/mapleall/maple_me/include/ssa_tab.h index c6d2256a5ce007aa8176ba1228fc918cbe04827b..028e9f63b09395d751ea941b538ce0d0ca434d0a 100644 --- a/src/mapleall/maple_me/include/ssa_tab.h +++ b/src/mapleall/maple_me/include/ssa_tab.h @@ -35,7 +35,7 @@ class SSATab : public AnalysisResult { ~SSATab() = default; - BaseNode *CreateSSAExpr(BaseNode &expr); + BaseNode *CreateSSAExpr(BaseNode *expr); void CreateSSAStmt(StmtNode &stmt, const BB *curbb); bool HasDefBB(OStIdx oidx) { return oidx < defBBs4Ost.size() && defBBs4Ost[oidx] && !defBBs4Ost[oidx]->empty(); diff --git a/src/mapleall/maple_me/src/irmap.cpp b/src/mapleall/maple_me/src/irmap.cpp index ea5a67319e3a5bd973166e31903ad5c5179bf97a..3518c9ead4b01f5776a60c7e12f508b1d55800f4 100644 --- a/src/mapleall/maple_me/src/irmap.cpp +++ b/src/mapleall/maple_me/src/irmap.cpp @@ -120,10 +120,7 @@ RegMeExpr *IRMap::CreateRegMeExpr(MIRType &mirType) { return CreateRegMeExpr(mirType.GetPrimType()); } if (mirType.GetPrimType() == PTY_ptr) { - MIRType *pointedType = static_cast(mirType).GetPointedType(); - if (pointedType == nullptr || pointedType->GetKind() != kTypeFunction) { - return CreateRegMeExpr(mirType.GetPrimType()); - } + return CreateRegMeExpr(mirType.GetPrimType()); } MIRFunction *mirFunc = mirModule.CurFunction(); PregIdx regIdx = mirFunc->GetPregTab()->CreatePreg(PTY_ref, &mirType); diff --git a/src/mapleall/maple_me/src/lfo_inject_iv.cpp b/src/mapleall/maple_me/src/lfo_inject_iv.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c978e2dbdc587f666e505c83fab38630dc92c928 --- /dev/null +++ b/src/mapleall/maple_me/src/lfo_inject_iv.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. + * You can use this software according to the terms and conditions of the MulanPSL - 2.0. + * You may obtain a copy of MulanPSL - 2.0 at: + * + * https://opensource.org/licenses/MulanPSL-2.0 + * + * 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 MulanPSL - 2.0 for more details. + */ + +#include "lfo_inject_iv.h" +#include "dominance.h" +#include "me_loop_analysis.h" +#include "me_option.h" +#include "mir_builder.h" +#include + +namespace maple { + +AnalysisResult *DoLfoInjectIV::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr*) { + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + CHECK_FATAL(dom, "dominance phase has problem"); + IdentifyLoops *identloops = static_cast(m->GetAnalysisResult(MeFuncPhase_MELOOP, func)); + CHECK_FATAL(identloops != nullptr, "identloops has problem"); + + uint32 ivCount = 0; + MIRBuilder *mirbuilder = func->GetMIRModule().GetMIRBuilder(); + LfoFunction *lfoFunc = func->GetLfoFunc(); + + for (LoopDesc *aloop : identloops->GetMeLoops()) { + BB *headbb = aloop->head; + // check if the label has associated LfoWhileInfo + if (headbb->GetBBLabel() == 0) { + continue; + } + if (headbb->GetPred().size() != 2) { + continue; // won't insert IV for loops with > 1 tail bbs + } + MapleMap::iterator it = lfoFunc->label2WhileInfo.find(headbb->GetBBLabel()); + if (it == lfoFunc->label2WhileInfo.end()) { + continue; + } + LfoWhileInfo *whileInfo = it->second; + // find the entry BB as the predecessor of headbb that dominates headbb + MapleVector::iterator predit = headbb->GetPred().begin(); + for ( ; predit != headbb->GetPred().end(); predit++) { + if (dom->Dominate(**predit, *headbb)) + break; + } + if (predit == headbb->GetPred().end()) { + continue; // cannot insert IV for this loop + } + BB *entrybb = *predit; + + // create the IV for this loop + std::string ivName("injected.iv"); + ivName.append(std::to_string(++ivCount)); + GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(ivName); + MIRSymbol *st = mirbuilder->CreateSymbol((TyIdx)PTY_i64, strIdx, kStVar, kScAuto, func->GetMirFunc(), kScopeLocal); + whileInfo->injectedIVSym = st; + if (DEBUGFUNC(func)) { + LogInfo::MapleLogger() << "****** Injected IV " << st->GetName() << " in while loop at label "; + LogInfo::MapleLogger() << "@" << func->GetMirFunc()->GetLabelName(headbb->GetBBLabel()) << std::endl; + } + + // initialize IV to 0 at loop entry + DassignNode *dass = mirbuilder->CreateStmtDassign(st->GetStIdx(), 0, mirbuilder->CreateIntConst(0, PTY_i64)); + StmtNode *laststmt = &entrybb->GetLast(); + if (laststmt && + (laststmt->op == OP_brfalse || laststmt->op == OP_brtrue || laststmt->op == OP_goto || laststmt->op == OP_igoto || laststmt->op == OP_switch)) { + entrybb->InsertStmtBefore(laststmt, dass); + } else { + entrybb->AddStmtNode(dass); + } + + // insert IV increment at loop tail BB + BB *tailbb = aloop->tail; + AddrofNode *dread = mirbuilder->CreateExprDread(*GlobalTables::GetTypeTable().GetInt64(), *st); + BinaryNode *addnode = mirbuilder->CreateExprBinary(OP_add, *GlobalTables::GetTypeTable().GetInt64(), dread, mirbuilder->CreateIntConst(1, PTY_i64)); + dass = mirbuilder->CreateStmtDassign(*st, 0, addnode); + laststmt = &tailbb->GetLast(); + tailbb->InsertStmtBefore(laststmt, dass); + } + return nullptr; +} + +} // namespace maple diff --git a/src/mapleall/maple_me/src/lfo_mir_lower.cpp b/src/mapleall/maple_me/src/lfo_mir_lower.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9a23ef211eed584b3f2c94b23abbc31d7da9624d --- /dev/null +++ b/src/mapleall/maple_me/src/lfo_mir_lower.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. + * You can use this software according to the terms and conditions of the MulanPSL - 2.0. + * You may obtain a copy of MulanPSL - 2.0 at: + * + * https://opensource.org/licenses/MulanPSL-2.0 + * + * 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 MulanPSL - 2.0 for more details. + */ + +#include "mir_builder.h" +#include "lfo_mir_lower.h" + +using namespace maple; + +// is lowered to : +// label +// brfalse +// +// goto +// label + +BlockNode *LFOMIRLower::LowerWhileStmt(WhileStmtNode &whilestmt) { + MIRBuilder *mirbuilder = mirModule.GetMIRBuilder(); +//DoCondVarProp(whilestmt); + whilestmt.SetBody(LowerBlock(*whilestmt.GetBody())); + BlockNode *blk = mirModule.CurFuncCodeMemPool()->New(); + LabelIdx whilelblidx = func->GetMirFunc()->GetLabelTab()->CreateLabel(); + mirModule.CurFunction()->GetLabelTab()->AddToStringLabelMap(whilelblidx); + LabelNode *whilelblstmt = mirModule.CurFuncCodeMemPool()->New(); + whilelblstmt->SetLabelIdx(whilelblidx); + LfoWhileInfo *whileInfo = lfoFunc->lfomp->New(); + lfoFunc->SetLabelCreatedByLfo(whilelblidx); + lfoFunc->label2WhileInfo.insert(std::make_pair(whilelblidx, whileInfo)); + blk->AddStatement(whilelblstmt); + CondGotoNode *brfalsestmt = mirModule.CurFuncCodeMemPool()->New(OP_brfalse); + brfalsestmt->SetOpnd(whilestmt.Opnd(), 0); + brfalsestmt->SetSrcPos(whilestmt.GetSrcPos()); + // add jump label target later + blk->AddStatement(brfalsestmt); + + // create body + CHECK_FATAL(whilestmt.GetBody(), "null ptr check"); + blk->AppendStatementsFromBlock(*whilestmt.GetBody()); + GotoNode *whilegotonode = mirbuilder->CreateStmtGoto(OP_goto, whilelblidx); + blk->AddStatement(whilegotonode); + // create endlabel + LabelIdx endlblidx = mirModule.CurFunction()->GetLabelTab()->CreateLabel(); + lfoFunc->SetLabelCreatedByLfo(endlblidx); + mirModule.CurFunction()->GetLabelTab()->AddToStringLabelMap(endlblidx); + LabelNode *endlblstmt = mirModule.CurFuncCodeMemPool()->New(); + endlblstmt->SetLabelIdx(endlblidx); + brfalsestmt->SetOffset(endlblidx); + blk->AddStatement(endlblstmt); + return blk; +} + +BlockNode *LFOMIRLower::LowerIfStmt(IfStmtNode &ifstmt, bool recursive) { + bool thenempty = ifstmt.GetThenPart() == nullptr || ifstmt.GetThenPart()->GetFirst() == nullptr; + bool elseempty = ifstmt.GetElsePart() == nullptr || ifstmt.GetElsePart()->GetFirst() == nullptr; + + if (recursive) { + if (!thenempty) { + ifstmt.SetThenPart(LowerBlock(*ifstmt.GetThenPart())); + } + if (!elseempty) { + ifstmt.SetElsePart(LowerBlock(*ifstmt.GetElsePart())); + } + } + + BlockNode *blk = mirModule.CurFuncCodeMemPool()->New(); + MIRFunction *mirFunc = func->GetMirFunc(); + MIRBuilder *mirbuilder = mirModule.GetMIRBuilder(); + + if (thenempty && elseempty) { + // generate EVAL statement + UnaryStmtNode *evalstmt = mirModule.CurFuncCodeMemPool()->New(OP_eval); + evalstmt->SetOpnd(ifstmt.Opnd(), 0); + evalstmt->SetSrcPos(ifstmt.GetSrcPos()); + blk->AddStatement(evalstmt); + } else if (elseempty) { + // brfalse + // + // label + CondGotoNode *brfalsestmt = mirModule.CurFuncCodeMemPool()->New(OP_brfalse); + brfalsestmt->SetOpnd(ifstmt.Opnd(), 0); + brfalsestmt->SetSrcPos(ifstmt.GetSrcPos()); + LabelIdx endlabelidx = mirFunc->GetLabelTab()->CreateLabel(); + mirFunc->GetLabelTab()->AddToStringLabelMap(endlabelidx); + lfoFunc->SetLabelCreatedByLfo(endlabelidx); + LfoIfInfo *ifInfo = lfoFunc->lfomp->New(); + brfalsestmt->SetOffset(endlabelidx); + blk->AddStatement(brfalsestmt); + + blk->AppendStatementsFromBlock(*ifstmt.GetThenPart()); + + LabelNode *labstmt = mirModule.CurFuncCodeMemPool()->New(); + labstmt->SetLabelIdx(endlabelidx); + ifInfo->endLabel = endlabelidx; + lfoFunc->label2IfInfo.insert(std::make_pair(endlabelidx, ifInfo)); + blk->AddStatement(labstmt); + } else if (thenempty) { + // brtrue + // + // label + CondGotoNode *brtruestmt = mirModule.CurFuncCodeMemPool()->New(OP_brtrue); + brtruestmt->SetOpnd(ifstmt.Opnd(), 0); + brtruestmt->SetSrcPos(ifstmt.GetSrcPos()); + LabelIdx endlabelidx = mirFunc->GetLabelTab()->CreateLabel(); + lfoFunc->SetLabelCreatedByLfo(endlabelidx); + LfoIfInfo *ifInfo = lfoFunc->lfomp->New(); + mirFunc->GetLabelTab()->AddToStringLabelMap(endlabelidx); + brtruestmt->SetOffset(endlabelidx); + blk->AddStatement(brtruestmt); + + blk->AppendStatementsFromBlock(*ifstmt.GetElsePart()); + LabelNode *labstmt = mirModule.CurFuncCodeMemPool()->New(); + labstmt->SetLabelIdx(endlabelidx); + ifInfo->endLabel = endlabelidx; + lfoFunc->label2IfInfo.insert(std::make_pair(endlabelidx, ifInfo)); + blk->AddStatement(labstmt); + } else { + // brfalse + // + // goto + // label + // + // label + CondGotoNode *brfalsestmt = mirModule.CurFuncCodeMemPool()->New(OP_brfalse); + brfalsestmt->SetOpnd(ifstmt.Opnd(), 0); + brfalsestmt->SetSrcPos(ifstmt.GetSrcPos()); + LabelIdx elselabelidx = mirFunc->GetLabelTab()->CreateLabel(); + mirFunc->GetLabelTab()->AddToStringLabelMap(elselabelidx); + lfoFunc->SetLabelCreatedByLfo(elselabelidx); + LfoIfInfo *ifInfo = lfoFunc->lfomp->New(); + brfalsestmt->SetOffset(elselabelidx); + blk->AddStatement(brfalsestmt); + ifInfo->elseLabel = elselabelidx; + lfoFunc->label2IfInfo.insert(std::make_pair(elselabelidx, ifInfo)); + + blk->AppendStatementsFromBlock(*ifstmt.GetThenPart()); + bool fallthru_from_then = !OpCodeNoFallThrough(ifstmt.GetThenPart()->GetLast()->GetOpCode()); + LabelIdx endlabelidx = 0; + + if (fallthru_from_then) { + GotoNode *gotostmt = mirModule.CurFuncCodeMemPool()->New(OP_goto); + endlabelidx = mirFunc->GetLabelTab()->CreateLabel(); + mirFunc->GetLabelTab()->AddToStringLabelMap(endlabelidx); + lfoFunc->SetLabelCreatedByLfo(endlabelidx); + gotostmt->SetOffset(endlabelidx); + blk->AddStatement(gotostmt); + } + + LabelNode *labstmt = mirModule.CurFuncCodeMemPool()->New(); + labstmt->SetLabelIdx(elselabelidx); + blk->AddStatement(labstmt); + + blk->AppendStatementsFromBlock(*ifstmt.GetElsePart()); + + if (fallthru_from_then) { + labstmt = mirModule.CurFuncCodeMemPool()->New(); + labstmt->SetLabelIdx(endlabelidx); + blk->AddStatement(labstmt); + } + if (endlabelidx == 0) { // create end label + endlabelidx = mirbuilder->CreateLabIdx(*mirFunc); + lfoFunc->SetLabelCreatedByLfo(endlabelidx); + LabelNode *endlabelnode = mirbuilder->CreateStmtLabel(endlabelidx); + blk->AddStatement(endlabelnode); + } + ifInfo->endLabel = endlabelidx; + } + return blk; +} diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index 4bdebafcfed9fd9b6f00171ec21ba2ba95b2d90a..8535b4952110e0db09833501fbf565e112164973 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1478,6 +1478,15 @@ void MeCFG::CreateBasicBlocks() { SetBBTryNodeMap(*newBB, *tryStmt); } curBB = newBB; + } else if (func.GetLfoFunc() && + (func.GetLfoFunc()->label2WhileInfo.find(labelIdx) != func.GetLfoFunc()->label2WhileInfo.end())) { + curBB->SetKind(kBBFallthru); + BB *newBB = NewBasicBlock(); + if (tryStmt != nullptr) { + newBB->SetAttributes(kBBAttrIsTry); + SetBBTryNodeMap(*newBB, *tryStmt); + } + curBB = newBB; } labelBBIdMap[labelIdx] = curBB; curBB->SetBBLabel(labelIdx); @@ -1690,7 +1699,7 @@ void MeCFG::BuildSCC() { SCCTopologicalSort(sccNodes); } -AnalysisResult *MeDoMeCfg::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr *mrm) { +AnalysisResult *MeDoMeCfg::Run(MeFunction *func, MeFuncResultMgr*, ModuleResultMgr*) { MemPool *meCfgMp = NewMemPool(); MeCFG *theCFG = meCfgMp->New(meCfgMp, *func); func->SetTheCfg(theCFG); @@ -1708,21 +1717,6 @@ AnalysisResult *MeDoMeCfg::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResul theCFG->UnreachCodeAnalysis(); theCFG->WontExitAnalysis(); theCFG->Verify(); -#if 0 // these 2 phases will be invoked by phase manager - if (mrm == nullptr) { - MeDoLoopCanon doLoopCanon(MeFuncPhase_LOOPCANON); - if (!MeOption::quiet) { - LogInfo::MapleLogger() << " == " << PhaseName() << " invokes [ " << doLoopCanon.PhaseName() << " ] ==\n"; - } - doLoopCanon.Run(func, m, NULL); - - MeDoSplitCEdge doSplitCEdge(MeFuncPhase_SPLITCEDGE); - if (!MeOption::quiet) { - LogInfo::MapleLogger() << " == " << PhaseName() << " invokes [ " << doSplitCEdge.PhaseName() << " ] ==\n"; - } - doSplitCEdge.Run(func, m, NULL); - } -#endif return theCFG; } } // namespace maple diff --git a/src/mapleall/maple_me/src/me_function.cpp b/src/mapleall/maple_me/src/me_function.cpp index 7676ce76188b4cf3023c0328e6f130f25952f04e..15f4e5a123c0229f3262bc616b939d86cdd0bf23 100644 --- a/src/mapleall/maple_me/src/me_function.cpp +++ b/src/mapleall/maple_me/src/me_function.cpp @@ -22,6 +22,7 @@ #include "constantfold.h" #include "me_irmap.h" #include "me_phase.h" +#include "lfo_mir_lower.h" namespace maple { #if DEBUG @@ -129,13 +130,23 @@ void MeFunction::Prepare(unsigned long rangeNum) { LogInfo::MapleLogger() << "---Preparing Function < " << CurFunction()->GetName() << " > [" << rangeNum << "] ---\n"; } - /* lower first */ - MIRLower mirLowerer(mirModule, CurFunction()); - mirLowerer.Init(); - mirLowerer.SetLowerME(); - mirLowerer.SetLowerExpandArray(); - ASSERT(CurFunction() != nullptr, "nullptr check"); - mirLowerer.LowerFunc(*CurFunction()); + if (MeOption::optLevel >= 3) { + MemPool* lfomp = memPoolCtrler.NewMemPool("lfo", true); + SetLfoFunc(lfomp->New(lfomp, this)); + SetLfoMempool(lfomp); + LFOMIRLower lfomirlowerer(mirModule, this); + lfomirlowerer.LowerFunc(*CurFunction()); + } else { + /* lower first */ + MIRLower mirLowerer(mirModule, CurFunction()); + mirLowerer.Init(); + mirLowerer.SetLowerME(); + if (mirModule.IsJavaModule()) { + mirLowerer.SetLowerExpandArray(); + } + ASSERT(CurFunction() != nullptr, "nullptr check"); + mirLowerer.LowerFunc(*CurFunction()); + } } void MeFunction::Verify() const { diff --git a/src/mapleall/maple_me/src/me_ir.cpp b/src/mapleall/maple_me/src/me_ir.cpp index c257bf53175620c3f0a4bd1ada81aa984a7e9ea4..8afd106422abc5cb1149e90539bc8616b9144a70 100644 --- a/src/mapleall/maple_me/src/me_ir.cpp +++ b/src/mapleall/maple_me/src/me_ir.cpp @@ -37,7 +37,7 @@ bool MeExpr::IsTheSameWorkcand(const MeExpr &expr) const { if (IsPrimitiveFloat(primType) != IsPrimitiveFloat(expr.GetPrimType())) { return false; } - if (GetPrimTypeSize(primType) != GetPrimTypeSize(expr.GetPrimType())) { + if (GetPrimTypeSize(GetRegPrimType(primType)) != GetPrimTypeSize(GetRegPrimType(expr.GetPrimType()))) { return false; } if (kOpcodeInfo.IsTypeCvt(op) || kOpcodeInfo.IsCompare(op)) { diff --git a/src/mapleall/maple_me/src/me_loop_analysis.cpp b/src/mapleall/maple_me/src/me_loop_analysis.cpp index 48da3541faa2a3ed9c66ae4aca0ec6f2300f4179..eacd5b47d170975c358ca4fa30f59384cd294253 100644 --- a/src/mapleall/maple_me/src/me_loop_analysis.cpp +++ b/src/mapleall/maple_me/src/me_loop_analysis.cpp @@ -46,6 +46,14 @@ void IdentifyLoops::InsertExitBB(LoopDesc &loop) { while (!inLoopBBs.empty()) { BB *curBB = inLoopBBs.front(); inLoopBBs.pop(); + if (curBB->GetKind() == kBBCondGoto) { + if (curBB->GetSucc().size() == 1) { + // When the size of succs is one, one of succs may be commonExitBB. Need insert to loopBB2exitBBs. + CHECK_FATAL(false, "return bb"); + } + } else if (!curBB->GetStmtNodes().empty() && curBB->GetLast().GetOpCode() == OP_return) { + CHECK_FATAL(false, "return bb"); + } for (BB *succ : curBB->GetSucc()) { if (traveledBBs.count(succ) != 0) { continue; @@ -56,14 +64,6 @@ void IdentifyLoops::InsertExitBB(LoopDesc &loop) { } else { loop.InsertInloopBB2exitBBs(*curBB, *succ); } - if (curBB->GetKind() == kBBCondGoto) { - if (curBB->GetSucc().size() == 1) { - // When the size of succs is one, one of succs may be commonExitBB. Need insert to loopBB2exitBBs. - CHECK_FATAL(false, "return bb"); - } - } else if (!curBB->GetStmtNodes().empty() && curBB->GetLast().GetOpCode() == OP_return) { - CHECK_FATAL(false, "return bb"); - } } } for (auto pair : loop.inloopBB2exitBBs) { diff --git a/src/mapleall/maple_me/src/me_loop_canon.cpp b/src/mapleall/maple_me/src/me_loop_canon.cpp index 723883a598c2e19abad777f11fcad2968bf33f0a..fcdb0113839409d243ed7b1b852c480ff8a0dd0b 100644 --- a/src/mapleall/maple_me/src/me_loop_canon.cpp +++ b/src/mapleall/maple_me/src/me_loop_canon.cpp @@ -51,6 +51,10 @@ static bool CompareBackedge(const std::pair &a, const std::pair &swapSuccs) const { + // loop is transformed + if (pred.GetAttributes(kBBAttrArtificial)) { + return false; + } bb.SetAttributes(kBBAttrIsInLoop); pred.SetAttributes(kBBAttrIsInLoop); // do not convert do-while loop @@ -119,6 +123,7 @@ void MeDoLoopCanon::Convert(MeFunction &func, BB &bb, BB &pred, MapleMapNewBasicBlock(); latchBB->SetAttributes(kBBAttrArtificial); + latchBB->SetAttributes(kBBAttrIsInLoop); // latchBB is inloop // update pred bb pred.ReplaceSucc(&bb, latchBB); // replace pred.succ with latchBB and set pred of latchBB // update pred stmt if needed @@ -339,8 +344,15 @@ void MeDoLoopCanon::Merge(MeFunction &func) { MeCFG *cfg = func.GetCfg(); for (auto iter = heads.begin(); iter != heads.end(); ++iter) { BB *head = cfg->GetBBFromID(iter->first); + // skip case : check latch bb is already added + if ((head->GetPred().size() == 2) && + (head->GetPred(1)->GetAttributes(kBBAttrArtificial)) && + (head->GetPred(1)->GetKind() == kBBFallthru)) { + continue; + } auto *latchBB = cfg->NewBasicBlock(); latchBB->SetAttributes(kBBAttrArtificial); + latchBB->SetAttributes(kBBAttrIsInLoop); // latchBB is inloop latchBB->SetKind(kBBFallthru); for (BB *tail : iter->second) { tail->ReplaceSucc(head, latchBB); @@ -350,6 +362,7 @@ void MeDoLoopCanon::Merge(MeFunction &func) { UpdateTheOffsetOfStmtWhenTargetBBIsChange(func, *tail, *head, *latchBB); } head->AddPred(*latchBB); + cfgchanged = true; } } @@ -384,6 +397,7 @@ void MeDoLoopCanon::AddPreheader(MeFunction &func) { UpdateTheOffsetOfStmtWhenTargetBBIsChange(func, *pred, *head, *preheader); } head->AddPred(*preheader); + cfgchanged = true; // set cfgchanged flag } } @@ -436,6 +450,15 @@ void MeDoLoopCanon::InsertExitBB(MeFunction &func, LoopDesc &loop) { while (!inLoopBBs.empty()) { BB *curBB = inLoopBBs.front(); inLoopBBs.pop(); + if (curBB->GetKind() == kBBCondGoto) { + if (curBB->GetSucc().size() == 1) { + CHECK_FATAL(false, "return bb"); + loop.InsertInloopBB2exitBBs(*curBB, *cfg->GetCommonExitBB()); + } + } else if (!curBB->GetStmtNodes().empty() && curBB->GetLast().GetOpCode() == OP_return) { + CHECK_FATAL(false, "return bb"); + loop.InsertInloopBB2exitBBs(*curBB, *cfg->GetCommonExitBB()); + } for (BB *succ : curBB->GetSucc()) { if (traveledBBs.count(succ) != 0) { continue; @@ -446,15 +469,6 @@ void MeDoLoopCanon::InsertExitBB(MeFunction &func, LoopDesc &loop) { } else { loop.InsertInloopBB2exitBBs(*curBB, *succ); } - if (curBB->GetKind() == kBBCondGoto) { - if (curBB->GetSucc().size() == 1) { - CHECK_FATAL(false, "return bb"); - loop.InsertInloopBB2exitBBs(*curBB, *cfg->GetCommonExitBB()); - } - } else if (!curBB->GetStmtNodes().empty() && curBB->GetLast().GetOpCode() == OP_return) { - CHECK_FATAL(false, "return bb"); - loop.InsertInloopBB2exitBBs(*curBB, *cfg->GetCommonExitBB()); - } } } InsertNewExitBB(func, loop); @@ -523,11 +537,12 @@ void MeDoLoopCanon::ExecuteLoopNormalization(MeFunction &func, MeFuncResultMgr func.GetCfg()->DumpToFile("cfgbeforLoopNormalization"); } heads.clear(); + cfgchanged = false; FindHeadBBs(func, dom, func.GetCfg()->GetCommonEntryBB()); AddPreheader(func); Merge(func); - // cfg changes only if heads is not empty - if (!heads.empty()) { + // cfgchanged is true if preheader bb or latchbb is added + if (cfgchanged) { m->InvalidAnalysisResult(MeFuncPhase_DOMINANCE, &func); m->InvalidAnalysisResult(MeFuncPhase_MELOOP, &func); } @@ -535,7 +550,7 @@ void MeDoLoopCanon::ExecuteLoopNormalization(MeFunction &func, MeFuncResultMgr if (meLoop == nullptr) { return; } - bool cfgChange = false; + cfgchanged = false; for (auto loop : meLoop->GetMeLoops()) { if (loop->HasTryBB()) { continue; @@ -545,12 +560,12 @@ void MeDoLoopCanon::ExecuteLoopNormalization(MeFunction &func, MeFuncResultMgr CHECK_FATAL(loop->inloopBB2exitBBs.size() == 0, "must be zero"); InsertExitBB(func, *loop); loop->SetIsCanonicalLoop(true); - cfgChange = true; + cfgchanged = true; } if (loop->inloopBB2exitBBs.size() == 1 && loop->inloopBB2exitBBs.begin()->second->size() == 1 && IsDoWhileLoop(func, *loop)) { SplitCondGotBB(func, *loop); - cfgChange = true; + cfgchanged = true; } } if (DEBUGFUNC(&func)) { @@ -558,7 +573,7 @@ void MeDoLoopCanon::ExecuteLoopNormalization(MeFunction &func, MeFuncResultMgr func.Dump(true); func.GetCfg()->DumpToFile("cfgafterLoopNormalization"); } - if (cfgChange) { + if (cfgchanged) { m->InvalidAnalysisResult(MeFuncPhase_DOMINANCE, &func); m->InvalidAnalysisResult(MeFuncPhase_MELOOP, &func); } diff --git a/src/mapleall/maple_me/src/me_option.cpp b/src/mapleall/maple_me/src/me_option.cpp index c75940319c1633a52d16b0279158f457816c8ebb..01e8cd4030d7f3dada10ab7604bd93ef9fa7a4c6 100644 --- a/src/mapleall/maple_me/src/me_option.cpp +++ b/src/mapleall/maple_me/src/me_option.cpp @@ -1064,6 +1064,7 @@ void MeOption::DecideMeRealLevel(const std::vector &inputOp break; case kMeOptL3: realLevel = kLevelThree; + break; default: break; } diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index 96d1572c82af9ef04106ced2d2a4f0e42aefb3b7..b3926c9fbe4783d779a71174fe7bd8a9f5ad8b7c 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -69,6 +69,7 @@ #include "mpl_timer.h" #include "constantfold.h" #include "me_verify.h" +#include "lfo_inject_iv.h" #define JAVALANG (mirModule.IsJavaModule()) @@ -312,6 +313,10 @@ void MeFuncPhaseManager::Run(MIRFunction *mirFunc, uint64 rangeNum, const std::s extraMeTimers["invalidResult"] += invalidTimer.ElapsedMicroseconds(); } } + // release lfo mempool + if (MeOption::optLevel >= 3) { + memPoolCtrler.DeleteMemPool(func.GetLfoMempool()); + } } MeFuncPhaseManager &MeFuncPhaseManager::Clone(MemPool &mp, MemPoolCtrler &ctrler) const { diff --git a/src/mapleall/maple_me/src/me_rename2preg.cpp b/src/mapleall/maple_me/src/me_rename2preg.cpp index f693750d51181cabdbbd96f78c1f09b14fb1e81a..5cc0f56ff7c79f6dd22853d769af7c821aa6757c 100644 --- a/src/mapleall/maple_me/src/me_rename2preg.cpp +++ b/src/mapleall/maple_me/src/me_rename2preg.cpp @@ -348,7 +348,7 @@ void SSARename2Preg::PromoteEmptyFunction() { } AnalysisResult *MeDoSSARename2Preg::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr *mrMgr) { - if (func->IsEmpty()) { + if (func->GetCfg()->empty()) { return nullptr; } (void)mrMgr; diff --git a/src/mapleall/maple_me/src/prop.cpp b/src/mapleall/maple_me/src/prop.cpp index e427276ea17c0e59ad9917c1647c7bb065955af7..b1d1edf9fb8e30ab4924ebd31fb515924430e6de 100644 --- a/src/mapleall/maple_me/src/prop.cpp +++ b/src/mapleall/maple_me/src/prop.cpp @@ -529,7 +529,7 @@ void Prop::TraversalMeStmt(MeStmt &meStmt) { } break; } - case OP_dassign: + case OP_dassign: case OP_regassign: { AssignMeStmt *asmestmt = static_cast(&meStmt); asmestmt->SetRHS(&PropMeExpr(*asmestmt->GetRHS(), subProped, false)); diff --git a/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp b/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp index ffec581c8e1fe5e2acb79ff00c9ba3cb4af401dd..9882180098b4e6548c18f824b16d1cec47a0e337 100644 --- a/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp +++ b/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) [2021] Huawei Technologies Co., Ltd. All rights reserved. * * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. * You can use this software according to the terms and conditions of the MulanPSL - 2.0. @@ -27,11 +27,14 @@ static VarMeExpr* ResolveOneInjuringDef(VarMeExpr *varx) { if (!dass->isIncDecStmt) { return varx; } - CHECK_FATAL(dass->GetRHS()->GetMeOp() == kMeOpOp, "ResolveOneInjuringDef: dassign marked isIncDecStmt has unexpected rhs form."); + CHECK_FATAL(dass->GetRHS()->GetMeOp() == kMeOpOp, + "ResolveOneInjuringDef: dassign marked isIncDecStmt has unexpected rhs form."); OpMeExpr *oprhs = static_cast(dass->GetRHS()); - CHECK_FATAL(oprhs->GetOpnd(0)->GetMeOp() == kMeOpVar, "ResolveOneInjuringDef: dassign marked isIncDecStmt has unexpected form."); + CHECK_FATAL(oprhs->GetOpnd(0)->GetMeOp() == kMeOpVar, + "ResolveOneInjuringDef: dassign marked isIncDecStmt has unexpected form."); VarMeExpr *rhsvar = static_cast(oprhs->GetOpnd(0)); - CHECK_FATAL(rhsvar->GetOst() == varx->GetOst(), "ResolveOneInjuringDef: dassign marked isIncDecStmt has unexpected rhs var."); + CHECK_FATAL(rhsvar->GetOst() == varx->GetOst(), + "ResolveOneInjuringDef: dassign marked isIncDecStmt has unexpected rhs var."); return rhsvar; } @@ -59,11 +62,14 @@ static RegMeExpr* ResolveOneInjuringDef(RegMeExpr *regx) { if (!rass->isIncDecStmt) { return regx; } - CHECK_FATAL(rass->GetRHS()->GetMeOp() == kMeOpOp, "ResolveOneInjuringDef: regassign marked isIncDecStmt has unexpected rhs form."); + CHECK_FATAL(rass->GetRHS()->GetMeOp() == kMeOpOp, + "ResolveOneInjuringDef: regassign marked isIncDecStmt has unexpected rhs form."); OpMeExpr *oprhs = static_cast(rass->GetRHS()); - CHECK_FATAL(oprhs->GetOpnd(0)->GetMeOp() == kMeOpReg, "ResolveOneInjuringDef: regassign marked isIncDecStmt has unexpected form."); + CHECK_FATAL(oprhs->GetOpnd(0)->GetMeOp() == kMeOpReg, + "ResolveOneInjuringDef: regassign marked isIncDecStmt has unexpected form."); RegMeExpr *rhsreg = static_cast(oprhs->GetOpnd(0)); - CHECK_FATAL(rhsreg->GetOst() == regx->GetOst(), "ResolveOneInjuringDef: regassign marked isIncDecStmt has unexpected rhs reg."); + CHECK_FATAL(rhsreg->GetOst() == regx->GetOst(), + "ResolveOneInjuringDef: regassign marked isIncDecStmt has unexpected rhs reg."); return rhsreg; } @@ -162,9 +168,11 @@ static int64 GetIncreAmtAndRhsReg(MeExpr *x, RegMeExpr *&rhsreg) { MeExpr* SSAEPre::InsertRepairStmt(MeExpr *temp, int64 increAmt, MeStmt *injuringDef) { MeExpr *rhs = nullptr; if (increAmt >= 0) { - rhs = irMap->CreateMeExprBinary(OP_add, temp->GetPrimType(), *temp, *irMap->CreateIntConstMeExpr(increAmt, temp->GetPrimType())); + rhs = irMap->CreateMeExprBinary(OP_add, temp->GetPrimType(), *temp, + *irMap->CreateIntConstMeExpr(increAmt, temp->GetPrimType())); } else { - rhs = irMap->CreateMeExprBinary(OP_sub, temp->GetPrimType(), *temp, *irMap->CreateIntConstMeExpr(-increAmt, temp->GetPrimType())); + rhs = irMap->CreateMeExprBinary(OP_sub, temp->GetPrimType(), *temp, + *irMap->CreateIntConstMeExpr(-increAmt, temp->GetPrimType())); } BB *bb = injuringDef->GetBB(); MeStmt *newstmt = nullptr; @@ -188,7 +196,7 @@ static MeExpr *FindLaterRepairedTemp(MeExpr *temp, MeStmt *injuringDef) { AssignMeStmt *rass = static_cast(injuringDef->GetNext()); while (rass != nullptr) { CHECK_FATAL(rass->GetOp() == OP_regassign && rass->isIncDecStmt, - "FindLaterRepairedTemp: failed to find repair statement"); + "FindLaterRepairedTemp: failed to find repair statement"); if (rass->GetLHS()->GetRegIdx() == static_cast(temp)->GetRegIdx()) { return rass->GetLHS(); } @@ -198,7 +206,7 @@ static MeExpr *FindLaterRepairedTemp(MeExpr *temp, MeStmt *injuringDef) { DassignMeStmt *dass = static_cast(injuringDef->GetNext()); while (dass != nullptr) { CHECK_FATAL(dass->GetOp() == OP_dassign && dass->isIncDecStmt, - "FindLaterRepairedTemp: failed to find repair statement"); + "FindLaterRepairedTemp: failed to find repair statement"); if (dass->GetLHS()->GetOst() == static_cast(temp)->GetOst()) { return dass->GetLHS(); } @@ -210,9 +218,9 @@ static MeExpr *FindLaterRepairedTemp(MeExpr *temp, MeStmt *injuringDef) { } MeExpr* SSAEPre::SRRepairOpndInjuries(MeExpr *curopnd, MeOccur *defocc, int32 i, - MeExpr *tempAtDef, - std::set *needRepairInjuringDefs, - std::set *repairedInjuringDefs) { + MeExpr *tempAtDef, + std::set *needRepairInjuringDefs, + std::set *repairedInjuringDefs) { MeExpr *repairedTemp = tempAtDef; if (curopnd->GetMeOp() == kMeOpVar) { VarMeExpr *varx = static_cast(curopnd); @@ -235,14 +243,16 @@ MeExpr* SSAEPre::SRRepairOpndInjuries(MeExpr *curopnd, MeOccur *defocc, int32 i, done = needRepairInjuringDefs->count(dass) == 1; if (done) { if (repairedInjuringDefs->count(dass) == 0) { - repairedTemp = SRRepairOpndInjuries(varx, defocc, i, tempAtDef, needRepairInjuringDefs, repairedInjuringDefs); + repairedTemp = SRRepairOpndInjuries(varx, defocc, i, tempAtDef, needRepairInjuringDefs, + repairedInjuringDefs); } repairedTemp = FindLaterRepairedTemp(repairedTemp, dass); } } } while (!done); // generate the increment statement at latestInjuringDef - repairedTemp = InsertRepairStmt(repairedTemp, increAmt*workCand->GetTheMeExpr()->SRMultiplier(), latestInjuringDef); + repairedTemp = InsertRepairStmt(repairedTemp, increAmt * workCand->GetTheMeExpr()->SRMultiplier(), + latestInjuringDef); } else { // find the last repair increment statement repairedTemp = FindLaterRepairedTemp(repairedTemp, latestInjuringDef); @@ -268,14 +278,16 @@ MeExpr* SSAEPre::SRRepairOpndInjuries(MeExpr *curopnd, MeOccur *defocc, int32 i, done = needRepairInjuringDefs->count(rass) == 1; if (done) { if (repairedInjuringDefs->count(rass) == 0) { - repairedTemp = SRRepairOpndInjuries(regx, defocc, i, tempAtDef, needRepairInjuringDefs, repairedInjuringDefs); + repairedTemp = SRRepairOpndInjuries(regx, defocc, i, tempAtDef, needRepairInjuringDefs, + repairedInjuringDefs); } repairedTemp = FindLaterRepairedTemp(repairedTemp, rass); } } } while (!done); // generate the increment statement at latestInjuringDef - repairedTemp = InsertRepairStmt(repairedTemp, increAmt*workCand->GetTheMeExpr()->SRMultiplier(), latestInjuringDef); + repairedTemp = InsertRepairStmt(repairedTemp, increAmt * workCand->GetTheMeExpr()->SRMultiplier(), + latestInjuringDef); } else { // find the last repair increment statement repairedTemp = FindLaterRepairedTemp(repairedTemp, latestInjuringDef); @@ -285,8 +297,8 @@ MeExpr* SSAEPre::SRRepairOpndInjuries(MeExpr *curopnd, MeOccur *defocc, int32 i, } MeExpr* SSAEPre::SRRepairInjuries(MeOccur *useocc, - std::set *needRepairInjuringDefs, - std::set *repairedInjuringDefs) { + std::set *needRepairInjuringDefs, + std::set *repairedInjuringDefs) { MeExpr *useexpr = nullptr; if (useocc->GetOccType() == kOccReal) { MeRealOcc *realocc = static_cast(useocc); @@ -318,7 +330,8 @@ MeExpr* SSAEPre::SRRepairInjuries(MeOccur *useocc, continue; } if (!OpndInDefOcc(curopnd, defocc, i)) { - repairedTemp = SRRepairOpndInjuries(curopnd, defocc, i, repairedTemp, needRepairInjuringDefs, repairedInjuringDefs); + repairedTemp = SRRepairOpndInjuries(curopnd, defocc, i, repairedTemp, needRepairInjuringDefs, + repairedInjuringDefs); // restricted to only 1 var or reg injured break; } diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index db02549cf7d67e69c0c3648c4020bfdae78b384e..c4081e40462b58e74c9595fbbda6e0a5073fbf25 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -48,7 +48,24 @@ ScalarMeExpr *SSAPre::CreateNewCurTemp(const MeExpr &meExpr) { if (workCand->GetPUIdx() != 0) { // allocate a new temp SetCurFunction(workCand->GetPUIdx()); - RegMeExpr *regVar = irMap->CreateRegMeExpr(meExpr); + RegMeExpr *regVar = nullptr; + if (meExpr.GetMeOp() == kMeOpIvar) { + auto *ivarMeExpr = static_cast(&meExpr); + MIRType *ptrMIRType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ivarMeExpr->GetTyIdx()); + CHECK_FATAL(ptrMIRType->GetKind() == kTypePointer, "must be point type for ivar"); + auto *realMIRType = static_cast(ptrMIRType); + FieldID fieldId = ivarMeExpr->GetFieldID(); + MIRType *ty = nullptr; + if (fieldId > 0) { + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(realMIRType->GetPointedTyIdxWithFieldID(fieldId)); + } else { + ty = realMIRType->GetPointedType(); + } + regVar = (ty->GetPrimType() == PTY_ref) ? (irMap->CreateRegMeExpr(*ty)) + : (irMap->CreateRegMeExpr(ivarMeExpr->GetPrimType())); + } else { + regVar = irMap->CreateRegMeExpr(meExpr); + } curTemp = regVar; if (preKind == kLoadPre) { irMap->SetLpreTmps(static_cast(&meExpr)->GetOstIdx(), *regVar); @@ -1419,7 +1436,8 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE if (dassMeStmt->isIncDecStmt && preKind == kExprPre) { break; } - if (dassMeStmt->GetRHS()->GetMeOp() == dassMeStmt->GetLHS()->GetMeOp() && dassMeStmt->GetLHS()->GetOst() == static_cast(dassMeStmt->GetRHS())->GetOst()) { + if (dassMeStmt->GetRHS()->GetMeOp() == dassMeStmt->GetLHS()->GetMeOp() && + dassMeStmt->GetLHS()->GetOst() == static_cast(dassMeStmt->GetRHS())->GetOst()) { break; // identity assignment converted from phi } BuildWorkListExpr(*meStmt, static_cast(seqStmt), *dassMeStmt->GetRHS(), isRebuilt, tempVar, true); diff --git a/src/mapleall/maple_me/src/ssa_tab.cpp b/src/mapleall/maple_me/src/ssa_tab.cpp index 7405f2dc0b0b416a70be868970a542da787483f8..261099d9d62996367ce4acc6bb3ea6fe66edebb1 100644 --- a/src/mapleall/maple_me/src/ssa_tab.cpp +++ b/src/mapleall/maple_me/src/ssa_tab.cpp @@ -18,6 +18,8 @@ #include "ssa_mir_nodes.h" #include "opcode_info.h" #include "mir_function.h" +#include "mir_lower.h" +#include "me_option.h" // Allocate data structures to store SSA information. Only statement nodes and // tree nodes that incur defs and uses are relevant. Tree nodes are made larger @@ -25,47 +27,54 @@ // stored in class SSATab's StmtsSSAPart, which has an array of pointers indexed // by the stmtID field of each statement node. namespace maple { -BaseNode *SSATab::CreateSSAExpr(BaseNode &expr) { - if (expr.GetOpCode() == OP_addrof || expr.GetOpCode() == OP_dread) { - if (expr.IsSSANode()) { - return mirModule.CurFunction()->GetCodeMemPool()->New(static_cast(expr)); +BaseNode *SSATab::CreateSSAExpr(BaseNode *expr) { + bool arrayLowered = false; + if (expr->GetOpCode() == OP_array && !mirModule.IsJavaModule() && + MeOption::strengthReduction /* && in-main-me-phase */) { + MIRLower mirLower(mirModule, mirModule.CurFunction()); + expr = mirLower.LowerCArray(static_cast(expr)); + arrayLowered = true; + } + if (expr->GetOpCode() == OP_addrof || expr->GetOpCode() == OP_dread) { + if (expr->IsSSANode()) { + return mirModule.CurFunction()->GetCodeMemPool()->New(*static_cast(expr)); } - auto &addrofNode = static_cast(expr); - AddrofSSANode *ssaNode = mirModule.CurFunction()->GetCodeMemPool()->New(addrofNode); + AddrofNode *addrofNode = static_cast(expr); + AddrofSSANode *ssaNode = mirModule.CurFunction()->GetCodeMemPool()->New(*addrofNode); MIRSymbol *st = mirModule.CurFunction()->GetLocalOrGlobalSymbol(ssaNode->GetStIdx()); OriginalSt *ost = FindOrCreateSymbolOriginalSt(*st, mirModule.CurFunction()->GetPuidx(), ssaNode->GetFieldID()); versionStTable.CreateZeroVersionSt(ost); ssaNode->SetSSAVar(*versionStTable.GetZeroVersionSt(ost)); return ssaNode; - } else if (expr.GetOpCode() == OP_regread) { - auto ®ReadNode = static_cast(expr); - RegreadSSANode *ssaNode = mirModule.CurFunction()->GetCodeMemPool()->New(regReadNode); + } else if (expr->GetOpCode() == OP_regread) { + RegreadNode *regReadNode = static_cast(expr); + RegreadSSANode *ssaNode = mirModule.CurFunction()->GetCodeMemPool()->New(*regReadNode); OriginalSt *ost = originalStTable.FindOrCreatePregOriginalSt(ssaNode->GetRegIdx(), mirModule.CurFunction()->GetPuidx()); versionStTable.CreateZeroVersionSt(ost); ssaNode->SetSSAVar(*versionStTable.GetZeroVersionSt(ost)); return ssaNode; - } else if (expr.GetOpCode() == OP_iread) { - auto &ireadNode = static_cast(expr); - IreadSSANode *ssaNode = mirModule.CurFunction()->GetCodeMempool()->New(ireadNode); - BaseNode *newOpnd = CreateSSAExpr(*ireadNode.Opnd(0)); + } else if (expr->GetOpCode() == OP_iread) { + IreadNode *ireadNode = static_cast(expr); + IreadSSANode *ssaNode = mirModule.CurFunction()->GetCodeMempool()->New(*ireadNode); + BaseNode *newOpnd = CreateSSAExpr(ireadNode->Opnd(0)); if (newOpnd != nullptr) { ssaNode->SetOpnd(newOpnd, 0); } return ssaNode; } - for (size_t i = 0; i < expr.NumOpnds(); ++i) { - BaseNode *newOpnd = CreateSSAExpr(*expr.Opnd(i)); + for (size_t i = 0; i < expr->NumOpnds(); ++i) { + BaseNode *newOpnd = CreateSSAExpr(expr->Opnd(i)); if (newOpnd != nullptr) { - expr.SetOpnd(newOpnd, i); + expr->SetOpnd(newOpnd, i); } } - return nullptr; + return arrayLowered ? expr : nullptr; } void SSATab::CreateSSAStmt(StmtNode &stmt, const BB *curbb) { for (size_t i = 0; i < stmt.NumOpnds(); ++i) { - BaseNode *newOpnd = CreateSSAExpr(*stmt.Opnd(i)); + BaseNode *newOpnd = CreateSSAExpr(stmt.Opnd(i)); if (newOpnd != nullptr) { stmt.SetOpnd(newOpnd, i); } diff --git a/src/mplfe/ast_input/include/ast_builtin_func.def b/src/mplfe/ast_input/include/ast_builtin_func.def index d579ae573a00e1331aedc5d404cf6a98b641255f..f6a92a9cebf8f3fcfb76349aeaba2b2b5c48ec1c 100644 --- a/src/mplfe/ast_input/include/ast_builtin_func.def +++ b/src/mplfe/ast_input/include/ast_builtin_func.def @@ -20,11 +20,5 @@ BUILTIN_FUNC(bswap64) BUILTIN_FUNC(bswap16) BUILTIN_FUNC(mul_overflow) // not support builtin func -BUILTIN_FUNC(ctz) -BUILTIN_FUNC(clz) BUILTIN_FUNC(clzl) -BUILTIN_FUNC(alloca) BUILTIN_FUNC(prefetch) -BUILTIN_FUNC(expect) -BUILTIN_FUNC(constant_p) -BUILTIN_FUNC(signbit) diff --git a/src/mplfe/ast_input/include/ast_decl.h b/src/mplfe/ast_input/include/ast_decl.h index a3225a215fc043a9c770d3133983de99d3bb6eaa..646920bf9af029504f6dd326b80f2b27d5ee7ab9 100644 --- a/src/mplfe/ast_input/include/ast_decl.h +++ b/src/mplfe/ast_input/include/ast_decl.h @@ -62,6 +62,16 @@ class ASTDecl { return isParam; } + void SetAlign(uint32 n) { + if (n > align) { + align = n; + } + } + + uint32 GetAlign() const { + return align; + } + void GenerateInitStmt(std::list &stmts) { return GenerateInitStmtImpl(stmts); } @@ -86,6 +96,7 @@ class ASTDecl { virtual void GenerateInitStmtImpl(std::list &stmts) {} bool isGlobalDecl; bool isParam = false; + uint32 align = 1; // in byte const std::string srcFileName; std::string name; std::vector typeDesc; @@ -193,6 +204,8 @@ class ASTVar : public ASTDecl { private: MIRConst *Translate2MIRConstImpl() const override; void GenerateInitStmtImpl(std::list &stmts) override; + void GenerateInitStmt4StringLiteral(ASTExpr *initASTExpr, UniqueFEIRVar feirVar, UniqueFEIRExpr initFeirExpr, + std::list &stmts); ASTExpr *initExpr = nullptr; }; diff --git a/src/mplfe/ast_input/include/ast_expr.h b/src/mplfe/ast_input/include/ast_expr.h index 4f765302c256482003d3bb710bec8f9cde8729d5..1593c5790adc1aa09db48d724763c1d8723a3c45 100644 --- a/src/mplfe/ast_input/include/ast_expr.h +++ b/src/mplfe/ast_input/include/ast_expr.h @@ -181,6 +181,8 @@ class ASTImplicitCastExpr : public ASTExpr { return child->GetASTDecl(); } + UniqueFEIRExpr Emit2FEExprForComplex(UniqueFEIRExpr subExpr, UniqueFEIRType srcType, + std::list &stmts) const; private: MIRConst *GenerateMIRDoubleConst() const; MIRConst *GenerateMIRFloatConst() const; @@ -216,8 +218,8 @@ class ASTUnaryOperatorExpr : public ASTExpr { return subType; } - MIRType *SetUOType(MIRType *type) { - return uoType = type; + void SetUOType(MIRType *type) { + uoType = type; } const MIRType *GetUOType() const { @@ -326,6 +328,23 @@ class ASTUOAddrOfExpr: public ASTUnaryOperatorExpr { UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; }; +class ASTUOAddrOfLabelExpr : public ASTUnaryOperatorExpr { + public: + ASTUOAddrOfLabelExpr() : ASTUnaryOperatorExpr(kASTOpAddrOfLabel) {} + ~ASTUOAddrOfLabelExpr() = default; + + void SetLabelName(const std::string &name) { + labelName = name; + } + + protected: + MIRConst *GenerateMIRConstImpl() const override; + + private: + UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; + std::string labelName; +}; + class ASTUODerefExpr: public ASTUnaryOperatorExpr { public: ASTUODerefExpr() : ASTUnaryOperatorExpr(kASTOpDeref) {} @@ -355,7 +374,7 @@ class ASTUORealExpr: public ASTUnaryOperatorExpr { private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; - MIRType *elementType; + MIRType *elementType = nullptr; }; class ASTUOImagExpr: public ASTUnaryOperatorExpr { @@ -369,7 +388,7 @@ class ASTUOImagExpr: public ASTUnaryOperatorExpr { private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; - MIRType *elementType; + MIRType *elementType = nullptr; }; class ASTUOExtensionExpr: public ASTUnaryOperatorExpr { @@ -465,10 +484,18 @@ class ASTInitListExpr : public ASTExpr { return initListType; } + std::vector GetFillers() const { + return fillers; + } + void SetInitListVarName(const std::string &argVarName) { varName = argVarName; } + std::string GetInitListVarName() const { + return varName; + } + void SetParentFlag(ParentFlag argParentFlag) { parentFlag = argParentFlag; } @@ -489,11 +516,20 @@ class ASTInitListExpr : public ASTExpr { return hasArrayFiller; } + void SetTransparent(bool flag) { + isTransparent = flag; + } + + bool IsTransparent() const { + return isTransparent; + } + private: MIRConst *GenerateMIRConstImpl() const override; UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; void Emit2FEExprForStruct4ArrayElemIsStruct(uint32 i, std::list &stmts) const; void Emit2FEExprForArray(std::list &stmts) const; + void Emit2FEExprForStringLiteral(UniqueFEIRVar feirVar, std::list &stmts) const; void Emit2FEExprForArrayForNest(UniqueFEIRType typeNative, UniqueFEIRExpr arrayExpr, std::list &stmts) const; void Emit2FEExprForStruct(std::list &stmts) const; @@ -505,6 +541,7 @@ class ASTInitListExpr : public ASTExpr { ParentFlag parentFlag = kNoParent; bool isUnionInitListExpr = false; bool hasArrayFiller = false; + bool isTransparent = false; }; class ASTBinaryConditionalOperator : public ASTExpr { @@ -625,22 +662,31 @@ class ASTStringLiteral : public ASTExpr { length = len; } - void SetCodeUnits(std::vector &units) { + void SetCodeUnits(std::vector &units) { codeUnits = std::move(units); } - const std::vector &GetCodeUnits() const { + const std::vector &GetCodeUnits() const { return codeUnits; } + void SetIsArrayToPointerDecay(bool argIsArrayToPointerDecay) { + isArrayToPointerDecay = argIsArrayToPointerDecay; + } + + bool IsArrayToPointerDecay() const { + return isArrayToPointerDecay; + } + protected: MIRConst *GenerateMIRConstImpl() const override; private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; - MIRType *type; + MIRType *type = nullptr; size_t length; - std::vector codeUnits; + std::vector codeUnits; + bool isArrayToPointerDecay = false; }; class ASTArraySubscriptExpr : public ASTExpr { @@ -917,12 +963,19 @@ class ASTCallExpr : public ASTExpr { private: using FuncPtrBuiltinFunc = UniqueFEIRExpr (ASTCallExpr::*)(std::list &stmts) const; - static std::map InitFuncPtrMap(); + static std::map InitBuiltinFuncPtrMap(); + UniqueFEIRExpr EmitBuiltinFunc(std::list &stmts) const; +#define EMIT_BUILTIIN_FUNC(FUNC) EmitBuiltin##FUNC(std::list &stmts) const + UniqueFEIRExpr EMIT_BUILTIIN_FUNC(Ctz); + UniqueFEIRExpr EMIT_BUILTIIN_FUNC(Clz); + UniqueFEIRExpr EMIT_BUILTIIN_FUNC(Alloca); + UniqueFEIRExpr EMIT_BUILTIIN_FUNC(Expect); + UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; UniqueFEIRExpr Emit2FEExprCall(std::list &stmts) const; UniqueFEIRExpr Emit2FEExprICall(std::list &stmts) const; - static std::map funcPtrMap; + static std::map builtingFuncPtrMap; std::vector args; ASTExpr *calleeExpr = nullptr; MIRType *retType = nullptr; @@ -1007,11 +1060,11 @@ class ASTCharacterLiteral : public ASTExpr { ASTCharacterLiteral() : ASTExpr(kASTCharacterLiteral) {} ~ASTCharacterLiteral() = default; - int8 GetVal() const { + int64 GetVal() const { return val; } - void SetVal(int8 valIn) { + void SetVal(int64 valIn) { val = valIn; } @@ -1021,7 +1074,7 @@ class ASTCharacterLiteral : public ASTExpr { private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; - int8 val; + int64 val; PrimType type; }; @@ -1032,7 +1085,7 @@ struct VaArgInfo { // If the argument type is a Composite Type that is larger than 16 bytes, // then the argument is copied to memory allocated by the caller and replaced by a pointer to the copy. bool isCopyedMem; - bool isHFA; // Homogeneous Floating-point Aggregate + MIRType *HFAType; // Homogeneous Floating-point Aggregate }; class ASTVAArgExpr : public ASTExpr { @@ -1047,9 +1100,9 @@ class ASTVAArgExpr : public ASTExpr { private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; VaArgInfo ProcessValistArgInfo(MIRType &type) const; - bool IsHFAType(MIRStructType &type) const; - void CvtHFA2Struct(MIRStructType &structType, UniqueFEIRVar vaArgVar, UniqueFEIRVar copyedVar, - std::list &stmts) const; + MIRType *IsHFAType(MIRStructType &type) const; + void CvtHFA2Struct(MIRStructType &type, MIRType &fieldType, UniqueFEIRVar vaArgVar, + UniqueFEIRVar copyedVar, std::list &stmts) const; ASTExpr *child = nullptr; }; @@ -1153,6 +1206,7 @@ class ASTCStyleCastExpr : public ASTExpr { private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; + MIRConst *GenerateMIRConstImpl() const override; ASTExpr *child = nullptr; MIRType *srcType = nullptr; MIRType *destType = nullptr; diff --git a/src/mplfe/ast_input/include/ast_op.h b/src/mplfe/ast_input/include/ast_op.h index dac9b2ad93f2d2e71477d8535fb1f085280ff479..b793ba48ab6a8e7d50a46053b4c957a1a564bee4 100644 --- a/src/mplfe/ast_input/include/ast_op.h +++ b/src/mplfe/ast_input/include/ast_op.h @@ -34,6 +34,7 @@ enum ASTOp { kASTOpPreInc, kASTOpPreDec, kASTOpAddrOf, + kASTOpAddrOfLabel, kASTOpDeref, kASTOpPlus, kASTOpReal, @@ -128,6 +129,7 @@ enum ASTStmtOp { // branch kASTStmtIf, kASTStmtGoto, + kASTStmtIndirectGoto, kASTStmtLabel, diff --git a/src/mplfe/ast_input/include/ast_parser.h b/src/mplfe/ast_input/include/ast_parser.h index bd9884557ea6395258b63254fa1e822348b8b5a4..2d38aca32e2110325b79f00db5ca3c45ef3738b6 100644 --- a/src/mplfe/ast_input/include/ast_parser.h +++ b/src/mplfe/ast_input/include/ast_parser.h @@ -72,6 +72,7 @@ class ASTParser { ASTStmt *PROCESS_STMT(ContinueStmt); ASTStmt *PROCESS_STMT(CompoundStmt); ASTStmt *PROCESS_STMT(GotoStmt); + ASTStmt *PROCESS_STMT(IndirectGotoStmt); ASTStmt *PROCESS_STMT(SwitchStmt); ASTStmt *PROCESS_STMT(CaseStmt); ASTStmt *PROCESS_STMT(DefaultStmt); @@ -91,6 +92,7 @@ class ASTParser { ASTBinaryOperatorExpr *AllocBinaryOperatorExpr(MapleAllocator &allocator, const clang::BinaryOperator &bo); #define PROCESS_EXPR(CLASS) ProcessExpr##CLASS(MapleAllocator&, const clang::CLASS&) ASTExpr *PROCESS_EXPR(UnaryOperator); + ASTExpr *PROCESS_EXPR(AddrLabelExpr); ASTExpr *PROCESS_EXPR(NoInitExpr); ASTExpr *PROCESS_EXPR(PredefinedExpr); ASTExpr *PROCESS_EXPR(OpaqueValueExpr); @@ -153,19 +155,21 @@ class ASTParser { uint32 GetSizeFromQualType(const clang::QualType qualType); uint32_t GetAlignOfType(const clang::QualType currQualType, clang::UnaryExprOrTypeTrait exprKind); uint32_t GetAlignOfExpr(const clang::Expr &expr, clang::UnaryExprOrTypeTrait exprKind); + ASTExpr *BuildExprToComputeSizeFromVLA(MapleAllocator &allocator, const clang::QualType &qualType); ASTExpr *ProcessExprBinaryOperatorComplex(MapleAllocator &allocator, const clang::BinaryOperator &bo); - using ParseBuiltinFunc = ASTExpr *(ASTParser::*)(MapleAllocator &allocator, const clang::CallExpr &expr) const; - static std::map InitFuncPtrMap(); - ASTExpr *ParseBuiltingClassifyType(MapleAllocator &allocator, const clang::CallExpr &expr) const; - ASTExpr *ParseBuiltingCtz(MapleAllocator &allocator, const clang::CallExpr &expr) const; - ASTExpr *ParseBuiltingClz(MapleAllocator &allocator, const clang::CallExpr &expr) const; - ASTExpr *ParseBuiltingAlloca(MapleAllocator &allocator, const clang::CallExpr &expr) const; - ASTExpr *ParseBuiltingConstantP(MapleAllocator &allocator, const clang::CallExpr &expr) const; - ASTExpr *ParseBuiltingExpect(MapleAllocator &allocator, const clang::CallExpr &expr) const; - ASTExpr *ParseBuiltingSignbit(MapleAllocator &allocator, const clang::CallExpr &expr) const; - ASTExpr *ParseBuiltingIsinfSign(MapleAllocator &allocator, const clang::CallExpr &expr) const; - static std::map builtingFuncPtrMap; +using FuncPtrBuiltinFunc = ASTExpr *(ASTParser::*)(MapleAllocator &allocator, const clang::CallExpr &expr, + std::stringstream &ss) const; +static std::map InitBuiltinFuncPtrMap(); +ASTExpr *ParseBuiltinFunc(MapleAllocator &allocator, const clang::CallExpr &expr, std::stringstream &ss) const; +#define PARSE_BUILTIIN_FUNC(FUNC) ParseBuiltin##FUNC(MapleAllocator &allocator, const clang::CallExpr &expr,\ + std::stringstream &ss) const + ASTExpr *PARSE_BUILTIIN_FUNC(ClassifyType); + ASTExpr *PARSE_BUILTIIN_FUNC(ConstantP); + ASTExpr *PARSE_BUILTIIN_FUNC(Signbit); + ASTExpr *PARSE_BUILTIIN_FUNC(Isinfsign); + + static std::map builtingFuncPtrMap; 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 aafa2180be340a68356842aa69d99a29fe980609..9edd78f65245f1be6a02d29876a5f04780430913 100644 --- a/src/mplfe/ast_input/include/ast_stmt.h +++ b/src/mplfe/ast_input/include/ast_stmt.h @@ -198,7 +198,7 @@ class ASTLabelStmt : public ASTStmt { private: std::list Emit2FEStmtImpl() const override; std::string labelName; - ASTStmt *subStmt; + ASTStmt *subStmt = nullptr; }; class ASTContinueStmt : public ASTStmt { @@ -246,6 +246,15 @@ class ASTGotoStmt : public ASTStmt { std::string labelName; }; +class ASTIndirectGotoStmt : public ASTStmt { + public: + ASTIndirectGotoStmt() : ASTStmt(kASTStmtIndirectGoto) {} + ~ASTIndirectGotoStmt() = default; + + protected: + std::list Emit2FEStmtImpl() const override; +}; + class ASTSwitchStmt : public ASTStmt { public: ASTSwitchStmt() : ASTStmt(kASTStmtSwitch) {} @@ -490,6 +499,7 @@ class ASTCallExprStmt : public ASTStmt { std::list Emit2FEStmtICall() const; std::list ProcessBuiltinVaStart() const; std::list ProcessBuiltinVaEnd() const; + std::list ProcessBuiltinVaCopy() const; static std::map funcPtrMap; std::string varName; diff --git a/src/mplfe/ast_input/lib/ast_interface.cpp b/src/mplfe/ast_input/lib/ast_interface.cpp index fa5db60f079bd06e65385341d8b139dab162e35e..65800a4c5d33b9ce3bc14262c9b488685f8d325e 100644 --- a/src/mplfe/ast_input/lib/ast_interface.cpp +++ b/src/mplfe/ast_input/lib/ast_interface.cpp @@ -48,6 +48,10 @@ const AstASTContext *LibAstFile::GetAstContext() { return astContext; } +AstASTContext *LibAstFile::GetNonConstAstContext() { + return astContext; +} + AstUnitDecl *LibAstFile::GetAstUnitDecl() { return astUnitDecl; } @@ -89,6 +93,30 @@ Pos LibAstFile::GetLOC(const clang::SourceLocation &srcLoc) const { static_cast(fullLocation.getSpellingLineNumber())); } +uint32 LibAstFile::GetMaxAlign(const clang::Decl &decl) const { + uint32 align = 0; + const clang::Decl *canonicalDecl = decl.getCanonicalDecl(); + if (canonicalDecl->getKind() == clang::Decl::Field) { + const clang::FieldDecl *fieldDecl = llvm::cast(canonicalDecl); + clang::QualType qualTy = fieldDecl->getType().getCanonicalType(); + align = RetrieveAggTypeAlign(qualTy.getTypePtr()); + } + uint32 selfAlign = canonicalDecl->getMaxAlignment(); + return align > selfAlign ? align : selfAlign; +} + +uint32 LibAstFile::RetrieveAggTypeAlign(const clang::Type *ty) const { + if (ty->isRecordType()) { + const auto *recordType = llvm::cast(ty); + clang::RecordDecl *recordDecl = recordType->getDecl(); + return (recordDecl->getMaxAlignment()) >> 3; // 8 bit = 2^3 bit = 1 byte + } else if (ty->isArrayType()) { + const clang::Type *elemType = ty->getArrayElementTypeNoTypeQual(); + return RetrieveAggTypeAlign(elemType); + } + return 0; +} + void LibAstFile::GetCVRAttrs(uint32_t qualifiers, GenericAttrs &genAttrs) { if (qualifiers & clang::Qualifiers::Const) { genAttrs.SetAttr(GENATTR_const); diff --git a/src/mplfe/ast_input/lib/ast_interface.h b/src/mplfe/ast_input/lib/ast_interface.h index f37736f6d422523e4992a24de8a96b7de17997ea..bb5fe53b17f31126c83df2a265a777dbc1e3976f 100644 --- a/src/mplfe/ast_input/lib/ast_interface.h +++ b/src/mplfe/ast_input/lib/ast_interface.h @@ -38,6 +38,7 @@ class LibAstFile { bool Open(const std::string &fileName, int excludeDeclFromPCH, int displayDiagnostics); const AstASTContext *GetAstContext(); + AstASTContext *GetNonConstAstContext(); AstUnitDecl *GetAstUnitDecl(); std::string GetMangledName(const clang::NamedDecl &decl); const std::string GetOrCreateMappedUnnamedName(uint32_t id); @@ -78,6 +79,8 @@ class LibAstFile { Pos GetDeclPosInfo(const clang::Decl &decl) const; Pos GetStmtLOC(const clang::Stmt &stmt) const; Pos GetLOC(const clang::SourceLocation &srcLoc) const; + uint32 GetMaxAlign(const clang::Decl &decl) const; + uint32 RetrieveAggTypeAlign(const clang::Type *ty) const; private: using RecordDeclMap = std::map; diff --git a/src/mplfe/ast_input/src/ast_decl.cpp b/src/mplfe/ast_input/src/ast_decl.cpp index 22001e01d882039f72811ad03340523df007985f..03b31b8e097b43781761172ae1c06961c9733bd1 100644 --- a/src/mplfe/ast_input/src/ast_decl.cpp +++ b/src/mplfe/ast_input/src/ast_decl.cpp @@ -59,26 +59,71 @@ MIRConst *ASTVar::Translate2MIRConstImpl() const { return initExpr->GenerateMIRConst(); } +void ASTVar::GenerateInitStmt4StringLiteral(ASTExpr *initASTExpr, UniqueFEIRVar feirVar, UniqueFEIRExpr initFeirExpr, + std::list &stmts) { +#ifdef USE_OPS + if (!static_cast(initASTExpr)->IsArrayToPointerDecay()) { + std::unique_ptr> argExprList = std::make_unique>(); + UniqueFEIRExpr dstExpr = FEIRBuilder::CreateExprAddrofVar(feirVar->Clone()); + uint32 stringLiteralSize = static_cast(initFeirExpr.get())->GetStringLiteralSize(); + auto uDstExpr = dstExpr->Clone(); + auto uSrcExpr = initFeirExpr->Clone(); + argExprList->emplace_back(std::move(uDstExpr)); + argExprList->emplace_back(std::move(uSrcExpr)); + argExprList->emplace_back(FEIRBuilder::CreateExprConstI32(stringLiteralSize)); + std::unique_ptr memcpyStmt = std::make_unique( + INTRN_C_memcpy, nullptr, nullptr, std::move(argExprList)); + stmts.emplace_back(std::move(memcpyStmt)); + + MIRType *mirArrayType = feirVar->GetType()->GenerateMIRTypeAuto(); + if (mirArrayType->GetKind() != kTypeArray) { + return; + } + auto allSize = static_cast(mirArrayType)->GetSize(); + auto elemSize = static_cast(mirArrayType)->GetElemType()->GetSize(); + CHECK_FATAL(elemSize != 0, "elemSize should not 0"); + auto allElemCnt = allSize / elemSize; + uint32 needInitFurtherCnt = allElemCnt - stringLiteralSize; + if (needInitFurtherCnt > 0) { + std::unique_ptr> argExprList = std::make_unique>(); + auto addExpr = FEIRBuilder::CreateExprBinary(OP_add, std::move(dstExpr), + FEIRBuilder::CreateExprConstI32(stringLiteralSize)); + argExprList->emplace_back(std::move(addExpr)); + argExprList->emplace_back(FEIRBuilder::CreateExprConstI32(0)); + argExprList->emplace_back(FEIRBuilder::CreateExprConstI32(needInitFurtherCnt)); + std::unique_ptr memsetStmt = std::make_unique( + INTRN_C_memset, nullptr, nullptr, std::move(argExprList)); + stmts.emplace_back(std::move(memsetStmt)); + } + return; + } +#endif +} + void ASTVar::GenerateInitStmtImpl(std::list &stmts) { if (genAttrs.GetAttr(GenericAttrKind::GENATTR_static)) { return; } - ASTExpr *initExpr = GetInitExpr(); - if (initExpr == nullptr) { + ASTExpr *initASTExpr = GetInitExpr(); + if (initASTExpr == nullptr) { return; } UniqueFEIRVar feirVar = Translate2FEIRVar(); - UniqueFEIRExpr expr = initExpr->Emit2FEExpr(stmts); - if (expr == nullptr) { + UniqueFEIRExpr initFeirExpr = initASTExpr->Emit2FEExpr(stmts); + if (initFeirExpr == nullptr) { return; } - PrimType srcPrimType = expr->GetPrimType(); + if (initASTExpr->GetASTOp() == kASTStringLiteral) { // init for StringLiteral + return GenerateInitStmt4StringLiteral(initASTExpr, feirVar->Clone(), initFeirExpr->Clone(), stmts); + } + + PrimType srcPrimType = initFeirExpr->GetPrimType(); UniqueFEIRStmt stmt; if (srcPrimType != feirVar->GetType()->GetPrimType() && srcPrimType != PTY_agg && srcPrimType != PTY_void) { - UniqueFEIRExpr cvtExpr = FEIRBuilder::CreateExprCvtPrim(std::move(expr), feirVar->GetType()->GetPrimType()); + UniqueFEIRExpr cvtExpr = FEIRBuilder::CreateExprCvtPrim(std::move(initFeirExpr), feirVar->GetType()->GetPrimType()); stmt = FEIRBuilder::CreateStmtDAssign(std::move(feirVar), std::move(cvtExpr)); } else { - stmt = FEIRBuilder::CreateStmtDAssign(std::move(feirVar), std::move(expr)); + stmt = FEIRBuilder::CreateStmtDAssign(std::move(feirVar), std::move(initFeirExpr)); } stmts.emplace_back(std::move(stmt)); } @@ -106,18 +151,8 @@ std::vector> ASTFunc::GenArgVarList() const { std::list ASTFunc::EmitASTStmtToFEIR() const { std::list stmts; - // fix int main() no return stmt. there are multiple branches, insert return at the end. - bool needRet = false; - UniqueFEIRExpr feExpr = std::make_unique(static_cast(0), PTY_i32); - UniqueFEIRStmt retStmt = std::make_unique(std::move(feExpr)); - if (name == "main" && typeDesc[1]->GetPrimType() == PTY_i32) { - needRet = true; - } const ASTStmt *astStmt = GetCompoundStmt(); if (astStmt == nullptr) { - if (needRet) { - stmts.emplace_back(std::move(retStmt)); - } return stmts; } const ASTCompoundStmt *astCpdStmt = static_cast(astStmt); @@ -129,8 +164,18 @@ std::list ASTFunc::EmitASTStmtToFEIR() const { stmts.emplace_back(std::move(stmt)); } } - if (needRet && (stmts.size() == 0 || stmts.back()->GetKind() != kStmtReturn)) { - stmts.emplace_back(std::move(retStmt)); + // fix int main() no return 0 and void func() no return. there are multiple branches, insert return at the end. + if (stmts.size() == 0 || stmts.back()->GetKind() != kStmtReturn) { + UniqueFEIRStmt retStmt = nullptr; + if (name == "main" && typeDesc[1]->GetPrimType() == PTY_i32) { + UniqueFEIRExpr retExpr = std::make_unique(static_cast(0), PTY_i32); + retStmt = std::make_unique(std::move(retExpr)); + } else if (typeDesc[1]->GetPrimType() == PTY_void) { + retStmt = std::make_unique(nullptr); + } + if (retStmt != nullptr) { + stmts.emplace_back(std::move(retStmt)); + } } return stmts; } diff --git a/src/mplfe/ast_input/src/ast_expr.cpp b/src/mplfe/ast_input/src/ast_expr.cpp index 85a0c67071e65341f235f035ebe650a314a2114e..c4e768b062e6ae542e5e447e8e72d2cf0c86bae4 100644 --- a/src/mplfe/ast_input/src/ast_expr.cpp +++ b/src/mplfe/ast_input/src/ast_expr.cpp @@ -146,11 +146,10 @@ UniqueFEIRExpr ASTDeclRefExpr::Emit2FEExprImpl(std::list &stmts) } else { UniqueFEIRVar feirVar = FEIRBuilder::CreateVarNameForC(refedDecl->GenerateUniqueVarName(), *mirType, refedDecl->IsGlobal(), false); - if (attrs.GetAttr(GENATTR_static) && !refedDecl->IsGlobal()) { - feirVar->SetAttrs(attrs); - if (static_cast(refedDecl)->GetInitExpr() != nullptr) { - feirVar->SetConst(refedDecl->Translate2MIRConst()); - } + feirVar->SetAttrs(attrs); + if (attrs.GetAttr(GENATTR_static) && !refedDecl->IsGlobal() && + static_cast(refedDecl)->GetInitExpr() != nullptr) { + feirVar->SetConst(refedDecl->Translate2MIRConst()); } if (mirType->GetKind() == kTypeArray) { feirRefExpr = FEIRBuilder::CreateExprAddrofVar(std::move(feirVar)); @@ -162,13 +161,6 @@ UniqueFEIRExpr ASTDeclRefExpr::Emit2FEExprImpl(std::list &stmts) } // ---------- ASTCallExpr ---------- -std::map ASTCallExpr::funcPtrMap = ASTCallExpr::InitFuncPtrMap(); - -std::map ASTCallExpr::InitFuncPtrMap() { - std::map ans; - return ans; -} - std::string ASTCallExpr::CvtBuiltInFuncName(std::string builtInName) const { #define BUILTIN_FUNC(funcName) \ {"__builtin_"#funcName, #funcName}, @@ -239,16 +231,17 @@ UniqueFEIRExpr ASTCallExpr::Emit2FEExprICall(std::list &stmts) c return nullptr; } +std::map ASTCallExpr::builtingFuncPtrMap = + ASTCallExpr::InitBuiltinFuncPtrMap(); + + UniqueFEIRExpr ASTCallExpr::Emit2FEExprImpl(std::list &stmts) const { if (isIcall) { return Emit2FEExprICall(stmts); } else { - if (calleeExpr != nullptr && calleeExpr->GetASTOp() == kASTOpCast && - static_cast(calleeExpr)->IsBuilinFunc()) { - auto ptrFunc = funcPtrMap.find(funcName); - if (ptrFunc != funcPtrMap.end()) { - return (this->*(ptrFunc->second))(stmts); - } + auto ptrFunc = builtingFuncPtrMap.find(funcName); + if (ptrFunc != builtingFuncPtrMap.end()) { + return EmitBuiltinFunc(stmts); } return Emit2FEExprCall(stmts); } @@ -263,6 +256,12 @@ MIRConst *ASTImplicitCastExpr::GenerateMIRConstImpl() const { if (isArrayToPointerDecay && child->GetASTOp() == kASTStringLiteral) { return FEManager::GetModule().GetMemPool()->New( GetConstantValue()->val.strIdx, *GlobalTables::GetTypeTable().GetPrimType(PTY_a64)); + } else if (isArrayToPointerDecay && child->GetASTOp() == kASTOpRef) { + auto astDecl = static_cast(child)->GetASTDecl(); + MIRSymbol *mirSymbol = FEManager::GetMIRBuilder().GetOrCreateGlobalDecl(astDecl->GenerateUniqueVarName(), + *(astDecl->GetTypeDesc().front())); + return FEManager::GetModule().GetMemPool()->New(mirSymbol->GetStIdx(), 0, + *(astDecl->GetTypeDesc().front())); } else if (isNeededCvt) { if (dst->GetPrimType() == PTY_f64) { return GenerateMIRDoubleConst(); @@ -331,10 +330,57 @@ MIRConst *ASTImplicitCastExpr::GenerateMIRIntConst() const { } } +UniqueFEIRExpr ASTImplicitCastExpr::Emit2FEExprForComplex(UniqueFEIRExpr subExpr, UniqueFEIRType srcType, + std::list &stmts) const { + std::string tmpName = FEUtils::GetSequentialName("Complex_"); + UniqueFEIRVar tmpVar = FEIRBuilder::CreateVarNameForC(tmpName, *complexType); + UniqueFEIRExpr dreadAgg; + if (imageZero) { + UniqueFEIRStmt realStmtNode = std::make_unique(tmpVar->Clone(), + subExpr->Clone(), kComplexRealID); + stmts.emplace_back(std::move(realStmtNode)); + UniqueFEIRExpr imagExpr = FEIRBuilder::CreateExprConstAnyScalar(src->GetPrimType(), 0); + UniqueFEIRStmt imagStmtNode = std::make_unique(tmpVar->Clone(), + imagExpr->Clone(), kComplexImagID); + stmts.emplace_back(std::move(imagStmtNode)); + dreadAgg = FEIRBuilder::CreateExprDRead(std::move(tmpVar)); + static_cast(dreadAgg.get())->SetFieldType(srcType->Clone()); + } else { + UniqueFEIRExpr realExpr; + UniqueFEIRExpr imagExpr; + FEIRNodeKind subNodeKind = subExpr->GetKind(); + UniqueFEIRExpr cloneSubExpr = subExpr->Clone(); + if (subNodeKind == kExprIRead) { + static_cast(subExpr.get())->SetFieldID(kComplexRealID); + static_cast(cloneSubExpr.get())->SetFieldID(kComplexImagID); + } else if (subNodeKind == kExprDRead) { + static_cast(subExpr.get())->SetFieldID(kComplexRealID); + static_cast(subExpr.get())->SetFieldType(srcType->Clone()); + static_cast(cloneSubExpr.get())->SetFieldID(kComplexImagID); + static_cast(cloneSubExpr.get())->SetFieldType(srcType->Clone()); + } + realExpr = FEIRBuilder::CreateExprCvtPrim(std::move(subExpr), dst->GetPrimType()); + imagExpr = FEIRBuilder::CreateExprCvtPrim(std::move(cloneSubExpr), dst->GetPrimType()); + UniqueFEIRStmt realStmt = std::make_unique(tmpVar->Clone(), std::move(realExpr), kComplexRealID); + stmts.emplace_back(std::move(realStmt)); + UniqueFEIRStmt imagStmt = std::make_unique(tmpVar->Clone(), std::move(imagExpr), kComplexImagID); + stmts.emplace_back(std::move(imagStmt)); + dreadAgg = FEIRBuilder::CreateExprDRead(std::move(tmpVar)); + } + return dreadAgg; +} + UniqueFEIRExpr ASTImplicitCastExpr::Emit2FEExprImpl(std::list &stmts) const { const ASTExpr *childExpr = child; UniqueFEIRType srcType = std::make_unique(*src); CHECK_FATAL(childExpr != nullptr, "childExpr is nullptr"); + if(isArrayToPointerDecay) { + if (child->GetASTOp() == kASTStringLiteral) { + static_cast(child)->SetIsArrayToPointerDecay(true); + } else if (child->GetASTOp() == kASTSubscriptExpr) { + static_cast(child)->SetAddrOfFlag(true); + } + } UniqueFEIRExpr subExpr = childExpr->Emit2FEExpr(stmts); if (complexType == nullptr) { if (IsNeededCvt(subExpr)) { @@ -344,42 +390,7 @@ UniqueFEIRExpr ASTImplicitCastExpr::Emit2FEExprImpl(std::list &s return FEIRBuilder::CreateExprCvtPrim(std::move(subExpr), dst->GetPrimType()); } } else { - std::string tmpName = FEUtils::GetSequentialName("Complex_"); - UniqueFEIRVar tmpVar = FEIRBuilder::CreateVarNameForC(tmpName, *complexType); - UniqueFEIRExpr dreadAgg; - if (imageZero) { - UniqueFEIRStmt realStmtNode = std::make_unique(tmpVar->Clone(), - subExpr->Clone(), kComplexRealID); - stmts.emplace_back(std::move(realStmtNode)); - UniqueFEIRExpr imagExpr = FEIRBuilder::CreateExprConstAnyScalar(src->GetPrimType(), 0); - UniqueFEIRStmt imagStmtNode = std::make_unique(tmpVar->Clone(), - imagExpr->Clone(), kComplexImagID); - stmts.emplace_back(std::move(imagStmtNode)); - dreadAgg = FEIRBuilder::CreateExprDRead(std::move(tmpVar)); - static_cast(dreadAgg.get())->SetFieldType(srcType->Clone()); - } else { - UniqueFEIRExpr realExpr; - UniqueFEIRExpr imagExpr; - FEIRNodeKind subNodeKind = subExpr->GetKind(); - UniqueFEIRExpr cloneSubExpr = subExpr->Clone(); - if (subNodeKind == kExprIRead) { - static_cast(subExpr.get())->SetFieldID(kComplexRealID); - static_cast(cloneSubExpr.get())->SetFieldID(kComplexImagID); - } else if (subNodeKind == kExprDRead) { - static_cast(subExpr.get())->SetFieldID(kComplexRealID); - static_cast(subExpr.get())->SetFieldType(srcType->Clone()); - static_cast(cloneSubExpr.get())->SetFieldID(kComplexImagID); - static_cast(cloneSubExpr.get())->SetFieldType(srcType->Clone()); - } - realExpr = FEIRBuilder::CreateExprCvtPrim(std::move(subExpr), dst->GetPrimType()); - imagExpr = FEIRBuilder::CreateExprCvtPrim(std::move(cloneSubExpr), dst->GetPrimType()); - UniqueFEIRStmt realStmt = std::make_unique(tmpVar->Clone(), std::move(realExpr), kComplexRealID); - stmts.emplace_back(std::move(realStmt)); - UniqueFEIRStmt imagStmt = std::make_unique(tmpVar->Clone(), std::move(imagExpr), kComplexImagID); - stmts.emplace_back(std::move(imagStmt)); - dreadAgg = FEIRBuilder::CreateExprDRead(std::move(tmpVar)); - } - return dreadAgg; + return Emit2FEExprForComplex(subExpr->Clone(), srcType->Clone(), stmts); } return subExpr; } @@ -450,7 +461,8 @@ UniqueFEIRExpr ASTUOPostIncExpr::Emit2FEExprImpl(std::list &stmt UniqueFEIRExpr childFEIRExpr = childExpr->Emit2FEExpr(stmts); UniqueFEIRExpr readSelfExpr; UniqueFEIRVar selfVar; - if (childExpr->GetASTOp() == kASTMemberExpr) { + if (childExpr->GetASTOp() == kASTMemberExpr || childExpr->GetASTOp() == kASTOpDeref || + childExpr->GetASTOp() == kASTSubscriptExpr) { readSelfExpr = childFEIRExpr->Clone(); } else { selfVar = FEIRBuilder::CreateVarNameForC(refedDecl->GenerateUniqueVarName(), *subType, isGlobal, false); @@ -465,10 +477,24 @@ UniqueFEIRExpr ASTUOPostIncExpr::Emit2FEExprImpl(std::list &stmt UniqueFEIRExpr selfAddExpr = FEIRBuilder::CreateExprMathBinary(OP_add, childFEIRExpr->Clone(), std::move(incIecExpr)); UniqueFEIRStmt selfAddStmt; - if (childExpr->GetASTOp() == kASTMemberExpr) { + if (childExpr->GetASTOp() == kASTMemberExpr || childExpr->GetASTOp() == kASTOpDeref) { auto ireadFEExpr = static_cast(childFEIRExpr.get()); selfAddStmt = std::make_unique(ireadFEExpr->GetClonedPtrType(), ireadFEExpr->GetClonedOpnd(), std::move(selfAddExpr), ireadFEExpr->GetFieldID()); + } else if (childExpr->GetASTOp() == kASTSubscriptExpr) { + auto ireadFEExpr = static_cast(childFEIRExpr.get()); + auto indexFEExpr = ireadFEExpr->GetExprIndexs().front()->Clone(); + MIRType *mirArrayType = ireadFEExpr->GetTypeArray().GenerateMIRTypeAuto(); + MIRType *elemType = static_cast(mirArrayType)->GetElemType(); + MIRType *ptrMIRElemType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*elemType, PTY_ptr); + auto ptrFEArrayType = std::make_unique(*ptrMIRElemType); + auto arrayExpr = FEIRBuilder::CreateExprAddrofArray(ireadFEExpr->GetUniqueTypeArray()->Clone(), + ireadFEExpr->GetUniqueExprArray()->Clone(), + ireadFEExpr->GetArrayName(), + ireadFEExpr->GetExprIndexs()); + selfAddStmt = std::make_unique(std::move(ptrFEArrayType), + std::move(arrayExpr), + std::move(selfAddExpr), 0); } else { selfAddStmt = FEIRBuilder::CreateStmtDAssign(std::move(selfVar), std::move(selfAddExpr)); } @@ -483,7 +509,8 @@ UniqueFEIRExpr ASTUOPostDecExpr::Emit2FEExprImpl(std::list &stmt UniqueFEIRExpr childFEIRExpr = childExpr->Emit2FEExpr(stmts); UniqueFEIRExpr readSelfExpr; UniqueFEIRVar selfVar; - if (childExpr->GetASTOp() == kASTMemberExpr) { + if (childExpr->GetASTOp() == kASTMemberExpr || childExpr->GetASTOp() == kASTOpDeref || + childExpr->GetASTOp() == kASTSubscriptExpr) { readSelfExpr = childFEIRExpr->Clone(); } else { selfVar = FEIRBuilder::CreateVarNameForC(refedDecl->GenerateUniqueVarName(), *subType, isGlobal, false); @@ -499,10 +526,24 @@ UniqueFEIRExpr ASTUOPostDecExpr::Emit2FEExprImpl(std::list &stmt UniqueFEIRExpr selfSubExpr = FEIRBuilder::CreateExprMathBinary(OP_sub, childFEIRExpr->Clone(), std::move(incDecExpr)); UniqueFEIRStmt selfSubStmt; - if (childExpr->GetASTOp() == kASTMemberExpr) { + if (childExpr->GetASTOp() == kASTMemberExpr || childExpr->GetASTOp() == kASTOpDeref) { auto ireadFEExpr = static_cast(childFEIRExpr.get()); selfSubStmt = std::make_unique(ireadFEExpr->GetClonedPtrType(), ireadFEExpr->GetClonedOpnd(), std::move(selfSubExpr), ireadFEExpr->GetFieldID()); + } else if (childExpr->GetASTOp() == kASTSubscriptExpr) { + auto ireadFEExpr = static_cast(childFEIRExpr.get()); + auto indexFEExpr = ireadFEExpr->GetExprIndexs().front()->Clone(); + MIRType *mirArrayType = ireadFEExpr->GetTypeArray().GenerateMIRTypeAuto(); + MIRType *elemType = static_cast(mirArrayType)->GetElemType(); + MIRType *ptrMIRElemType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*elemType, PTY_ptr); + auto ptrFEArrayType = std::make_unique(*ptrMIRElemType); + auto arrayExpr = FEIRBuilder::CreateExprAddrofArray(ireadFEExpr->GetUniqueTypeArray()->Clone(), + ireadFEExpr->GetUniqueExprArray()->Clone(), + ireadFEExpr->GetArrayName(), + ireadFEExpr->GetExprIndexs()); + selfSubStmt = std::make_unique(std::move(ptrFEArrayType), + std::move(arrayExpr), + std::move(selfSubExpr), 0); } else { selfSubStmt = FEIRBuilder::CreateStmtDAssign(std::move(selfVar), std::move(selfSubExpr)); } @@ -522,11 +563,26 @@ UniqueFEIRExpr ASTUOPreIncExpr::Emit2FEExprImpl(std::list &stmts std::move(incIecExpr)); UniqueFEIRStmt stmt; UniqueFEIRExpr retExpr; - if (childExpr->GetASTOp() == kASTMemberExpr) { + if (childExpr->GetASTOp() == kASTMemberExpr || childExpr->GetASTOp() == kASTOpDeref) { auto ireadFEExpr = static_cast(childFEIRExpr.get()); stmt = std::make_unique(ireadFEExpr->GetClonedPtrType(), ireadFEExpr->GetClonedOpnd(), std::move(astUOPreIncExpr), ireadFEExpr->GetFieldID()); retExpr = std::move(childFEIRExpr); + } else if (childExpr->GetASTOp() == kASTSubscriptExpr) { + auto ireadFEExpr = static_cast(childFEIRExpr.get()); + auto indexFEExpr = ireadFEExpr->GetExprIndexs().front()->Clone(); + MIRType *mirArrayType = ireadFEExpr->GetTypeArray().GenerateMIRTypeAuto(); + MIRType *elemType = static_cast(mirArrayType)->GetElemType(); + MIRType *ptrMIRElemType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*elemType, PTY_ptr); + auto ptrFEArrayType = std::make_unique(*ptrMIRElemType); + auto arrayExpr = FEIRBuilder::CreateExprAddrofArray(ireadFEExpr->GetUniqueTypeArray()->Clone(), + ireadFEExpr->GetUniqueExprArray()->Clone(), + ireadFEExpr->GetArrayName(), + ireadFEExpr->GetExprIndexs()); + stmt = std::make_unique(std::move(ptrFEArrayType), + std::move(arrayExpr), + std::move(astUOPreIncExpr), 0); + retExpr = std::move(childFEIRExpr); } else { UniqueFEIRVar selfVar = FEIRBuilder::CreateVarNameForC(refedDecl->GenerateUniqueVarName(), *subType, isGlobal, false); @@ -549,11 +605,26 @@ UniqueFEIRExpr ASTUOPreDecExpr::Emit2FEExprImpl(std::list &stmts std::move(incDecExpr)); UniqueFEIRStmt stmt; UniqueFEIRExpr retExpr; - if (childExpr->GetASTOp() == kASTMemberExpr) { + if (childExpr->GetASTOp() == kASTMemberExpr || childExpr->GetASTOp() == kASTOpDeref) { auto ireadFEExpr = static_cast(childFEIRExpr.get()); stmt = std::make_unique(ireadFEExpr->GetClonedPtrType(), ireadFEExpr->GetClonedOpnd(), std::move(astUOPreDecExpr), ireadFEExpr->GetFieldID()); retExpr = std::move(childFEIRExpr); + } else if (childExpr->GetASTOp() == kASTSubscriptExpr) { + auto ireadFEExpr = static_cast(childFEIRExpr.get()); + auto indexFEExpr = ireadFEExpr->GetExprIndexs().front()->Clone(); + MIRType *mirArrayType = ireadFEExpr->GetTypeArray().GenerateMIRTypeAuto(); + MIRType *elemType = static_cast(mirArrayType)->GetElemType(); + MIRType *ptrMIRElemType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*elemType, PTY_ptr); + auto ptrFEArrayType = std::make_unique(*ptrMIRElemType); + auto arrayExpr = FEIRBuilder::CreateExprAddrofArray(ireadFEExpr->GetUniqueTypeArray()->Clone(), + ireadFEExpr->GetUniqueExprArray()->Clone(), + ireadFEExpr->GetArrayName(), + ireadFEExpr->GetExprIndexs()); + stmt = std::make_unique(std::move(ptrFEArrayType), + std::move(arrayExpr), + std::move(astUOPreDecExpr), 0); + retExpr = std::move(childFEIRExpr); } else { UniqueFEIRVar selfVar = FEIRBuilder::CreateVarNameForC(refedDecl->GenerateUniqueVarName(), *subType, isGlobal, false); @@ -608,8 +679,15 @@ UniqueFEIRExpr ASTUOAddrOfExpr::Emit2FEExprImpl(std::list &stmts if (astOp == kASTOpRef) { ASTDecl *var = static_cast(childExpr)->GetASTDecl(); UniqueFEIRVar addrOfVar = FEIRBuilder::CreateVarNameForC(var->GenerateUniqueVarName(), - *(var->GetTypeDesc().front()), - var->IsGlobal(), false); + *(var->GetTypeDesc().front()), var->IsGlobal(), false); + if (refedDecl != nullptr) { + auto attrs = refedDecl->GetGenericAttrs(); + addrOfVar->SetAttrs(attrs); + if (attrs.GetAttr(GENATTR_static) && !refedDecl->IsGlobal() && + static_cast(refedDecl)->GetInitExpr() != nullptr) { + addrOfVar->SetConst(refedDecl->Translate2MIRConst()); + } + } addrOfExpr = FEIRBuilder::CreateExprAddrofVar(std::move(addrOfVar)); } else if (astOp == kASTMemberExpr) { ASTMemberExpr *memberExpr = static_cast(childExpr); @@ -669,6 +747,23 @@ UniqueFEIRExpr ASTUOAddrOfExpr::Emit2FEExprImpl(std::list &stmts return addrOfExpr; } +// ---------- ASTUOAddrOfLabelExpr --------- +MIRConst *ASTUOAddrOfLabelExpr::GenerateMIRConstImpl() const { +#ifndef USE_OPS + CHECK_FATAL(false, "Unsupported yet"); + return nullptr; +#else + return FEManager::GetMIRBuilder().GetCurrentFuncCodeMp()->New( + FEManager::GetMIRBuilder().GetOrCreateMIRLabel(labelName), + FEManager::GetMIRBuilder().GetCurrentFunction()->GetPuidx(), + *GlobalTables::GetTypeTable().GetVoidPtr()); +#endif +} + +UniqueFEIRExpr ASTUOAddrOfLabelExpr::Emit2FEExprImpl(std::list &stmts) const { + return FEIRBuilder::CreateExprAddrofLabel(labelName, std::make_unique(*uoType)); +} + UniqueFEIRExpr ASTUODerefExpr::Emit2FEExprImpl(std::list &stmts) const { ASTExpr *childExpr = expr; CHECK_FATAL(childExpr != nullptr, "childExpr is nullptr"); @@ -934,10 +1029,15 @@ MIRConst *ASTInitListExpr::GenerateMIRConstForStruct() const { } UniqueFEIRExpr ASTInitListExpr::Emit2FEExprImpl(std::list &stmts) const { - if (!initListType->IsStructType()) { + if (initListType->GetKind() == MIRTypeKind::kTypeArray) { Emit2FEExprForArray(stmts); - } else { + } else if (initListType->IsStructType()) { Emit2FEExprForStruct(stmts); + } else if (isTransparent) { + CHECK_FATAL(fillers.size() == 1, "Transparent init list size must be 1"); + return fillers[0]->Emit2FEExpr(stmts); + } else { + CHECK_FATAL(true, "Unsupported init list type"); } return nullptr; } @@ -967,11 +1067,64 @@ void ASTInitListExpr::Emit2FEExprForArrayForNest(UniqueFEIRType typeNative, Uniq } } +void ASTInitListExpr::Emit2FEExprForStringLiteral(UniqueFEIRVar feirVar, std::list &stmts) const { +#ifdef USE_OPS + auto fill0 = fillers.front(); + auto fillType = std::make_unique(*fill0->GetType()); + MIRType *mirArrayType = fillType->GenerateMIRTypeAuto(); + if (mirArrayType->GetKind() != kTypeArray) { + return; + } + auto allSize = static_cast(mirArrayType)->GetSize(); + auto elemSize = static_cast(mirArrayType)->GetElemType()->GetSize(); + CHECK_FATAL(elemSize != 0, "elemSize should not 0"); + auto allElemCnt = allSize / elemSize; + + for (int i = 0; i < fillers.size(); i++) { + auto fillExpr = fillers[i]->Emit2FEExpr(stmts); + std::unique_ptr> argExprList = std::make_unique>(); + UniqueFEIRExpr dstExpr = FEIRBuilder::CreateExprAddrofVar(feirVar->Clone()); + uint32 stringLiteralSize = static_cast(fillExpr.get())->GetStringLiteralSize(); + auto uSrcExpr = fillExpr->Clone(); + auto addExpr = FEIRBuilder::CreateExprBinary(OP_add, dstExpr->Clone(), + FEIRBuilder::CreateExprConstI32(allElemCnt * i)); + argExprList->emplace_back(std::move(addExpr)); + argExprList->emplace_back(std::move(uSrcExpr)); // src + if (stringLiteralSize > allElemCnt) { + stringLiteralSize = allElemCnt; // StringLiteral can be longer than allElemCnt + } + argExprList->emplace_back(FEIRBuilder::CreateExprConstI32(stringLiteralSize)); + std::unique_ptr memcpyStmt = std::make_unique( + INTRN_C_memcpy, nullptr, nullptr, std::move(argExprList)); + stmts.emplace_back(std::move(memcpyStmt)); + + int32 needInitFurtherCnt = allElemCnt - stringLiteralSize; + if (needInitFurtherCnt > 0) { + std::unique_ptr> argExprList = std::make_unique>(); + auto addExpr = FEIRBuilder::CreateExprBinary(OP_add, std::move(dstExpr), + FEIRBuilder::CreateExprConstI32(allElemCnt * i + stringLiteralSize)); + argExprList->emplace_back(std::move(addExpr)); + argExprList->emplace_back(FEIRBuilder::CreateExprConstI32(0)); + argExprList->emplace_back(FEIRBuilder::CreateExprConstI32(needInitFurtherCnt)); + std::unique_ptr memsetStmt = std::make_unique( + INTRN_C_memset, nullptr, nullptr, std::move(argExprList)); + stmts.emplace_back(std::move(memsetStmt)); + } + } + return; +#endif +} + void ASTInitListExpr::Emit2FEExprForArray(std::list &stmts) const { UniqueFEIRVar feirVar = FEIRBuilder::CreateVarNameForC(varName, *initListType); UniqueFEIRVar feirVarTmp = feirVar->Clone(); UniqueFEIRType typeNative = FEIRTypeHelper::CreateTypeNative(*initListType); UniqueFEIRExpr arrayExpr = FEIRBuilder::CreateExprAddrofVar(std::move(feirVarTmp)); + + if (fillers[0]->GetASTOp() == kASTStringLiteral) { + return Emit2FEExprForStringLiteral(feirVar->Clone(), stmts); + } + if (fillers[0]->GetASTOp() == kASTOpInitListExpr) { Emit2FEExprForArrayForNest(typeNative->Clone(), arrayExpr->Clone(), stmts); } else { @@ -1052,8 +1205,8 @@ void ASTInitListExpr::Emit2FEExprForStruct(std::list &stmts) con continue; // skip anonymous field } uint32 fieldID = 0; - if (fillers[i]->GetASTOp() == kASTOpInitListExpr) { - if (initListType->GetKind() == kTypeStruct) { + if (fillers[i]->GetASTOp() == kASTOpInitListExpr && !static_cast(fillers[i])->IsTransparent()) { + if (initListType->GetKind() == kTypeStruct || initListType->GetKind() == kTypeUnion) { MIRType *mirType = static_cast(fillers[i])->GetInitListType(); std::string tmpName = FEUtils::GetSequentialName("subInitListVar_"); UniqueFEIRVar tmpVar = FEIRBuilder::CreateVarNameForC(tmpName, *mirType); @@ -1115,18 +1268,18 @@ UniqueFEIRExpr ASTImplicitValueInitExpr::Emit2FEExprImpl(std::listNew(FEManager::GetModule(), *arrayTypeWithSize); for (uint32 i = 0; i < codeUnits.size(); ++i) { - MIRConst *cst = FEManager::GetModule().GetMemPool()->New(codeUnits[i], *elemType); + MIRConst *cst = FEManager::GetModule().GetMemPool()->New(codeUnits[i], *type); val->PushBack(cst); } return val; } UniqueFEIRExpr ASTStringLiteral::Emit2FEExprImpl(std::list &stmts) const { - UniqueFEIRExpr expr = std::make_unique(codeUnits); + MIRType *elemType = static_cast(type)->GetElemType(); + UniqueFEIRExpr expr = std::make_unique(codeUnits, elemType); CHECK_NULL_FATAL(expr); return expr; } @@ -1248,10 +1401,15 @@ UniqueFEIRExpr ASTMemberExpr::Emit2FEExprImpl(std::list &stmts) } else { if (baseExpr->GetASTOp() != kASTSubscriptExpr) { CHECK_FATAL(baseType->IsStructType(), "basetype must be StructType"); - UniqueFEIRVar tmpVar = static_cast(baseFEExpr.get())->GetVar()->Clone(); MIRStructType *structType = static_cast(baseType); FieldID fieldID = FEUtils::GetStructFieldID(structType, fieldName); UniqueFEIRType memberFEType = std::make_unique(*memberType); + if (baseFEExpr->GetKind() == FEIRNodeKind::kExprIRead) { + static_cast(baseFEExpr.get())->SetFieldID(fieldID); + baseFEExpr->SetType(std::move(memberFEType)); + return baseFEExpr; + } + UniqueFEIRVar tmpVar = static_cast(baseFEExpr.get())->GetVar()->Clone(); if (memberFEType->IsArray()) { auto addrofExpr = std::make_unique(std::move(tmpVar)); addrofExpr->SetFieldID(fieldID); @@ -1516,6 +1674,7 @@ UniqueFEIRExpr ASTConditionalOperator::Emit2FEExprImpl(std::list return FEIRBuilder::CreateExprTernary(OP_select, std::move(type), std::move(condFEIRExpr), std::move(trueFEIRExpr), std::move(falseFEIRExpr)); } + // when subExpr is void if (trueFEIRExpr == nullptr || falseFEIRExpr == nullptr) { UniqueFEIRStmt stmtIf = FEIRBuilder::CreateStmtIf(std::move(condFEIRExpr), trueStmts, falseStmts); stmts.emplace_back(std::move(stmtIf)); @@ -1568,15 +1727,13 @@ UniqueFEIRExpr ASTImaginaryLiteral::Emit2FEExprImpl(std::list &s UniqueFEIRExpr ASTVAArgExpr::Emit2FEExprImpl(std::list &stmts) const { CHECK_NULL_FATAL(mirType); VaArgInfo info = ProcessValistArgInfo(*mirType); - UniqueFEIRExpr dreadVaList = child->Emit2FEExpr(stmts); - CHECK_FATAL(dreadVaList->GetKind() == kExprDRead, "expr must be kExprDRead, %u", dreadVaList->GetKind()); - UniqueFEIRVar vaListVar = static_cast(dreadVaList.get())->GetVar()->Clone(); + UniqueFEIRExpr readVaList = child->Emit2FEExpr(stmts); // The va_arg_offset temp var is created and assigned from __gr_offs or __vr_offs of va_list MIRType *int32Type = GlobalTables::GetTypeTable().GetInt32(); UniqueFEIRType int32FETRType = std::make_unique(*int32Type); UniqueFEIRVar offsetVar = FEIRBuilder::CreateVarNameForC(FEUtils::GetSequentialName("va_arg_offs_"), *int32Type); - UniqueFEIRExpr dreadVaListOffset = FEIRBuilder::CreateExprDReadAggField( - vaListVar->Clone(), info.isGPReg ? 4 : 5, int32FETRType->Clone()); + UniqueFEIRExpr dreadVaListOffset = FEIRBuilder::ReadExprField( + readVaList->Clone(), info.isGPReg ? 4 : 5, int32FETRType->Clone()); UniqueFEIRStmt dassignOffsetVar = FEIRBuilder::CreateStmtDAssign(offsetVar->Clone(), dreadVaListOffset->Clone()); stmts.emplace_back(std::move(dassignOffsetVar)); UniqueFEIRExpr dreadOffsetVar = FEIRBuilder::CreateExprDRead(offsetVar->Clone()); @@ -1588,8 +1745,8 @@ UniqueFEIRExpr ASTVAArgExpr::Emit2FEExprImpl(std::list &stmts) c UniqueFEIRType uint64FEIRType = std::make_unique(*uint64Type); MIRType *ptrType = GlobalTables::GetTypeTable().GetOrCreatePointerType((!info.isCopyedMem ? *mirType : *uint64Type)); UniqueFEIRVar vaArgVar = FEIRBuilder::CreateVarNameForC(FEUtils::GetSequentialName("va_arg"), *ptrType); - UniqueFEIRExpr dreadVaArgTop = FEIRBuilder::CreateExprDReadAggField( - vaListVar->Clone(), info.isGPReg ? 2 : 3, uint64FEIRType->Clone()); + UniqueFEIRExpr dreadVaArgTop = FEIRBuilder::ReadExprField( + readVaList->Clone(), info.isGPReg ? 2 : 3, uint64FEIRType->Clone()); UniqueFEIRExpr cvtOffset = FEIRBuilder::CreateExprCvtPrim(dreadOffsetVar->Clone(), PTY_u64); UniqueFEIRExpr addTopAndOffs = FEIRBuilder::CreateExprBinary(OP_add, std::move(dreadVaArgTop), std::move(cvtOffset)); UniqueFEIRStmt dassignVaArgFromReg = FEIRBuilder::CreateStmtDAssign(vaArgVar->Clone(), std::move(addTopAndOffs)); @@ -1603,23 +1760,24 @@ UniqueFEIRExpr ASTVAArgExpr::Emit2FEExprImpl(std::list &stmts) c std::list trueStmtsInUpper; std::list falseStmtsInLower; // The va_arg will be got from GP or FP/SIMD arg reg and set next reg setoff - UniqueFEIRStmt dassignArgNextOffs = FEIRBuilder::CreateStmtDAssignAggField( - vaListVar->Clone(), std::move(ArgAUnitOffs), info.isGPReg ? 4 : 5); + UniqueFEIRStmt dassignArgNextOffs = FEIRBuilder::AssginStmtField( + readVaList->Clone(), std::move(ArgAUnitOffs), info.isGPReg ? 4 : 5); trueStmtsInUpper.emplace_back(std::move(dassignVaArgFromReg)); - if (info.isHFA && !info.isCopyedMem) { + if (info.HFAType != nullptr && !info.isCopyedMem) { UniqueFEIRVar copyedVar = FEIRBuilder::CreateVarNameForC(FEUtils::GetSequentialName("va_arg_struct"), *mirType); - CvtHFA2Struct(*static_cast(mirType), vaArgVar->Clone(), std::move(copyedVar), trueStmtsInUpper); + CvtHFA2Struct(*static_cast(mirType), *info.HFAType, + vaArgVar->Clone(), std::move(copyedVar), trueStmtsInUpper); } UniqueFEIRStmt stmtIfCondUpper = FEIRBuilder::CreateStmtIfWithoutElse(std::move(condUpper), trueStmtsInUpper); trueStmtsInLower.emplace_back(std::move(dassignArgNextOffs)); trueStmtsInLower.emplace_back(std::move(stmtIfCondUpper)); // Otherwise, the va_arg will be got from stack and set next stack setoff - UniqueFEIRExpr dreadStackTop = FEIRBuilder::CreateExprDReadAggField(vaListVar->Clone(), 1, uint64FEIRType->Clone()); + UniqueFEIRExpr dreadStackTop = FEIRBuilder::ReadExprField(readVaList->Clone(), 1, uint64FEIRType->Clone()); UniqueFEIRStmt dassignVaArgFromStack = FEIRBuilder::CreateStmtDAssign(vaArgVar->Clone(), dreadStackTop->Clone()); UniqueFEIRExpr stackAUnitOffs = FEIRBuilder::CreateExprBinary( OP_add, dreadStackTop->Clone(), FEIRBuilder::CreateExprConstU64(info.stackOffset)); - UniqueFEIRStmt dassignStackNextOffs = FEIRBuilder::CreateStmtDAssignAggField( - vaListVar->Clone(), std::move(stackAUnitOffs), 1); + UniqueFEIRStmt dassignStackNextOffs = FEIRBuilder::AssginStmtField( + readVaList->Clone(), std::move(stackAUnitOffs), 1); falseStmtsInLower.emplace_back(std::move(dassignVaArgFromStack)); falseStmtsInLower.emplace_back(std::move(dassignStackNextOffs)); UniqueFEIRStmt stmtIfCondLower = FEIRBuilder::CreateStmtIf(std::move(condLower), trueStmtsInLower, falseStmtsInLower); @@ -1646,31 +1804,34 @@ VaArgInfo ASTVAArgExpr::ProcessValistArgInfo(MIRType &type) const { case PTY_f32: // float is automatically promoted to double when passed to va_arg WARN(kLncWarn, "error: float is promoted to double when passed to va_arg"); case PTY_f64: // double - info = { false, 16, 8, false, false }; + info = { false, 16, 8, false, nullptr }; break; case PTY_i32: case PTY_i64: - info = { true, 8, 8, false, false }; + info = { true, 8, 8, false, nullptr }; break; default: // bool, char, short, and unscoped enumerations are converted to int or wider integer types WARN(kLncWarn, "error: bool, char, short, and unscoped enumerations are promoted to int or "\ "wider integer types when passed to va_arg"); - info = { true, 8, 8, false, false }; + info = { true, 8, 8, false, nullptr }; break; } } else if (type.IsMIRPtrType()) { - info = { true, 8, 8, false, false }; + info = { true, 8, 8, false, nullptr }; } else if (type.IsStructType()) { MIRStructType structType = static_cast(type); size_t size = structType.GetSize(); size = (size + 7) & -8; // size round up 8 if (size > 16) { - info = { true, 8, 8, true, false }; - } else if (IsHFAType(structType)) { - int fieldsSize = static_cast(structType.GetFieldsSize()); - info = { false, fieldsSize * 16, static_cast(size), false, true }; + info = { true, 8, 8, true, nullptr }; } else { - info = { true, static_cast(size), static_cast(size), false, false }; + MIRType *hfa = IsHFAType(structType); + if (hfa != nullptr) { + int fieldsNum = structType.GetSize() / hfa->GetSize(); + info = { false, fieldsNum * 16, static_cast(size), false, hfa }; + } else { + info = { true, static_cast(size), static_cast(size), false, nullptr }; + } } } else { CHECK_FATAL(false, "unsupport mirtype"); @@ -1679,39 +1840,44 @@ VaArgInfo ASTVAArgExpr::ProcessValistArgInfo(MIRType &type) const { } // Homogeneous Floating-point Aggregate: -// A data type with 2 to 4 identical floating-point members, either floats or doubles. (including 1 members here) -bool ASTVAArgExpr::IsHFAType(MIRStructType &type) const { +// A data type with 2 to 4 identical floating-point members, either floats or doubles. +// (including 1 members here, struct nested array) +MIRType *ASTVAArgExpr::IsHFAType(MIRStructType &type) const { size_t size = type.GetFieldsSize(); if (size < 1 || size > 4) { - return false; + return nullptr; } - PrimType firstFieldPrimType; + MIRType *firstType = nullptr; for (size_t i = 0; i < size; ++i) { MIRType *fieldType = type.GetElemType(i); - if (fieldType->GetPrimType() != PTY_f32 && fieldType->GetPrimType() != PTY_f64) { - return false; - } - if (i == 0) { - firstFieldPrimType = fieldType->GetPrimType(); - } else { - if (fieldType->GetPrimType() != firstFieldPrimType) { - return false; + if (fieldType->GetKind() == kTypeArray) { + MIRArrayType *arrayType = static_cast(fieldType); + MIRType *elemType = arrayType->GetElemType(); + if (elemType->GetPrimType() != PTY_f32 && elemType->GetPrimType() != PTY_f64) { + return nullptr; } + fieldType = elemType; + } else if (fieldType->GetPrimType() != PTY_f32 && fieldType->GetPrimType() != PTY_f64) { + return nullptr; + } + if (firstType == nullptr) { + firstType = fieldType; + } else if (fieldType != firstType) { + return nullptr; } } - return true; + return firstType; } // When va_arg is HFA struct, // if it is passed as parameter in register then each uniquely addressable field goes in its own register. // So its fields in FP/SIMD arg reg are still 128 bit and should be converted float or double type fields. -void ASTVAArgExpr::CvtHFA2Struct(MIRStructType &structType, UniqueFEIRVar vaArgVar, UniqueFEIRVar copyedVar, - std::list &stmts) const { - int size = static_cast(structType.GetFieldsSize()); - MIRType *fieldType = structType.GetElemType(0); - MIRType *ptrMirType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*fieldType); - UniqueFEIRType baseType = std::make_unique(*fieldType); +void ASTVAArgExpr::CvtHFA2Struct(MIRStructType &type, MIRType &fieldType, UniqueFEIRVar vaArgVar, + UniqueFEIRVar copyedVar, std::list &stmts) const { + MIRType *ptrMirType = GlobalTables::GetTypeTable().GetOrCreatePointerType(fieldType); + UniqueFEIRType baseType = std::make_unique(fieldType); UniqueFEIRType ptrType = std::make_unique(*ptrMirType); + int size = type.GetSize() / fieldType.GetSize(); // fieldType must be nonzero for (int i = 0; i < size; ++i) { UniqueFEIRExpr dreadVaArg = FEIRBuilder::CreateExprDRead(vaArgVar->Clone()); if (i != 0) { @@ -1719,9 +1885,16 @@ void ASTVAArgExpr::CvtHFA2Struct(MIRStructType &structType, UniqueFEIRVar vaArgV OP_add, std::move(dreadVaArg), FEIRBuilder::CreateExprConstU64(16 * i)); } UniqueFEIRExpr ireadVaArg = FEIRBuilder::CreateExprIRead(baseType->Clone(), ptrType->Clone(), dreadVaArg->Clone()); - UniqueFEIRStmt dassignCopyedVar = FEIRBuilder::CreateStmtDAssignAggField( - copyedVar->Clone(), std::move(ireadVaArg), (i + 1)); - stmts.emplace_back(std::move(dassignCopyedVar)); + UniqueFEIRExpr addrofVar = FEIRBuilder::CreateExprAddrofVar(copyedVar->Clone()); + if(i != 0) { + addrofVar = FEIRBuilder::CreateExprBinary( + OP_add, std::move(addrofVar), FEIRBuilder::CreateExprConstU64(fieldType.GetSize() * i)); + } + MIRType *ptrType = GlobalTables::GetTypeTable().GetOrCreatePointerType(fieldType); + UniqueFEIRType fieldFEIRType = std::make_unique(*ptrType); + UniqueFEIRStmt iassignCopyedVar = FEIRBuilder::CreateStmtIAssign( + std::move(fieldFEIRType), std::move(addrofVar), std::move(ireadVaArg)); + stmts.emplace_back(std::move(iassignCopyedVar)); } UniqueFEIRExpr addrofCopyedVar = FEIRBuilder::CreateExprAddrofVar(copyedVar->Clone()); UniqueFEIRStmt assignVar = FEIRBuilder::CreateStmtDAssign(vaArgVar->Clone(), std::move(addrofCopyedVar)); @@ -1747,6 +1920,10 @@ UniqueFEIRExpr ASTCStyleCastExpr::Emit2FEExprImpl(std::list &stm return feirCStyleCastExpr; } +MIRConst *ASTCStyleCastExpr::GenerateMIRConstImpl() const { + return child->GenerateMIRConst(); +} + // ---------- ASTArrayInitLoopExpr ---------- UniqueFEIRExpr ASTArrayInitLoopExpr::Emit2FEExprImpl(std::list &stmts) const { CHECK_FATAL(false, "NIY"); @@ -1815,6 +1992,6 @@ UniqueFEIRExpr ASTExprStmtExpr::Emit2FEExprImpl(std::list &stmts } CHECK_FATAL(cpdStmt->GetASTStmtOp() == kASTStmtCompound, "Invalid in ASTExprStmtExpr"); stmts0.clear(); - return static_cast(cpdStmt)->GetASTStmtList().back()->GetExprs().back()->Emit2FEExpr(stmts); + return static_cast(cpdStmt)->GetASTStmtList().back()->GetExprs().back()->Emit2FEExpr(stmts0); } } diff --git a/src/mplfe/ast_input/src/ast_parser.cpp b/src/mplfe/ast_input/src/ast_parser.cpp index 98981af67f7fd0f0a54cd57abdffebefd9aa57df..b52cedff64cf2bcfc7b0d51f8e92745caee9db2f 100644 --- a/src/mplfe/ast_input/src/ast_parser.cpp +++ b/src/mplfe/ast_input/src/ast_parser.cpp @@ -114,6 +114,7 @@ ASTStmt *ASTParser::ProcessStmt(MapleAllocator &allocator, const clang::Stmt &st STMT_CASE(LabelStmt); STMT_CASE(ContinueStmt); STMT_CASE(GotoStmt); + STMT_CASE(IndirectGotoStmt); STMT_CASE(SwitchStmt); STMT_CASE(CaseStmt); STMT_CASE(DefaultStmt); @@ -369,6 +370,13 @@ ASTStmt *ASTParser::ProcessStmtGotoStmt(MapleAllocator &allocator, const clang:: return astStmt; } +ASTStmt *ASTParser::ProcessStmtIndirectGotoStmt(MapleAllocator &allocator, const clang::IndirectGotoStmt &iGotoStmt) { + ASTIndirectGotoStmt *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); + CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); + astStmt->SetASTExpr(ProcessExpr(allocator, iGotoStmt.getTarget())); + return astStmt; +} + ASTStmt *ASTParser::ProcessStmtGCCAsmStmt(MapleAllocator &allocator, const clang::GCCAsmStmt &asmStmt) { ASTGCCAsmStmt *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); @@ -565,6 +573,12 @@ ASTValue *ASTParser::TranslateLValue2ASTValue(MapleAllocator &allocator, const c const clang::APValue::LValueBase &lvBase = result.Val.getLValueBase(); if (lvBase.is()) { const clang::Expr *lvExpr = lvBase.get(); + if (lvExpr == nullptr && expr->getStmtClass() == clang::Stmt::MemberExprClass) { + // meaningless, just for Initialization + astValue->pty = PTY_i32; + astValue->val.i32 = 0; + return astValue; + } astValue->pty = PTY_a64; switch (lvExpr->getStmtClass()) { case clang::Stmt::StringLiteralClass: { @@ -623,6 +637,7 @@ ASTExpr *ASTParser::ProcessExpr(MapleAllocator &allocator, const clang::Expr *ex } switch (expr->getStmtClass()) { EXPR_CASE(UnaryOperator); + EXPR_CASE(AddrLabelExpr); EXPR_CASE(NoInitExpr); EXPR_CASE(PredefinedExpr); EXPR_CASE(OpaqueValueExpr); @@ -775,6 +790,15 @@ ASTExpr *ASTParser::ProcessExprUnaryOperator(MapleAllocator &allocator, const cl return astUOExpr; } +ASTExpr *ASTParser::ProcessExprAddrLabelExpr(MapleAllocator &allocator, const clang::AddrLabelExpr &expr) { + ASTUOAddrOfLabelExpr *astAddrOfLabelExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + const clang::LabelDecl *lbDecl = expr.getLabel(); + std::string labelName = lbDecl->getName().str(); + astAddrOfLabelExpr->SetLabelName(labelName); + astAddrOfLabelExpr->SetUOType(GlobalTables::GetTypeTable().GetPrimType(PTY_ptr)); + return astAddrOfLabelExpr; +} + ASTExpr *ASTParser::ProcessExprNoInitExpr(MapleAllocator &allocator, const clang::NoInitExpr &expr) { ASTNoInitExpr *astNoInitExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astNoInitExpr != nullptr, "astNoInitExpr is nullptr"); @@ -884,6 +908,9 @@ ASTExpr *ASTParser::ProcessExprInitListExpr(MapleAllocator &allocator, const cla if (expr.hasArrayFiller()) { astInitListExpr->SetHasArrayFiller(true); } + if (expr.isTransparent()) { + astInitListExpr->SetTransparent(true); + } for (uint32 i = 0; i < n; ++i) { const clang::Expr *eExpr = le[i]; ASTExpr *astExpr = ProcessExpr(allocator, eExpr); @@ -1046,25 +1073,40 @@ uint32_t ASTParser::GetAlignOfExpr(const clang::Expr &expr, clang::UnaryExprOrTy return static_cast(alignInCharUnits.getQuantity()); } +ASTExpr *ASTParser::BuildExprToComputeSizeFromVLA(MapleAllocator &allocator, const clang::QualType &qualType) { + if (llvm::isa(qualType)) { + ASTExpr *lhs = BuildExprToComputeSizeFromVLA(allocator, llvm::cast(qualType)->getElementType()); + ASTExpr *rhs = nullptr; + CHECK_FATAL(llvm::isa(qualType), "the type must be vla type"); + clang::Expr *sizeExpr = llvm::cast(qualType)->getSizeExpr(); + rhs = ProcessExpr(allocator, sizeExpr); + CHECK_FATAL(sizeExpr->getType()->isIntegerType(), "the type should be integer"); + auto *astBOExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + astBOExpr->SetRetType(GlobalTables::GetTypeTable().GetPrimType(PTY_u64)); + astBOExpr->SetOpcode(OP_mul); + astBOExpr->SetLeftExpr(lhs); + astBOExpr->SetRightExpr(rhs); + return astBOExpr; + } + uint32 size = GetSizeFromQualType(qualType); + auto integerExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + integerExpr->SetType(PTY_u64); + integerExpr->SetVal(size); + return integerExpr; +} + ASTExpr *ASTParser::ProcessExprUnaryExprOrTypeTraitExpr(MapleAllocator &allocator, const clang::UnaryExprOrTypeTraitExpr &expr) { auto *astExprUnaryExprOrTypeTraitExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astExprUnaryExprOrTypeTraitExpr != nullptr, "astExprUnaryExprOrTypeTraitExpr is nullptr"); switch (expr.getKind()) { case clang::UETT_SizeOf: { - uint32 size = 0; - if (expr.isArgumentType()) { - size = GetSizeFromQualType(expr.getArgumentType()); - } else { - const clang::Expr *argex = expr.getArgumentExpr(); - if (llvm::isa(argex->getType())) { - // C99 VLA - CHECK_FATAL(false, "NIY"); - break; - } else { - size = GetSizeFromQualType(argex->getType()); - } + clang::QualType qualType = expr.isArgumentType() ? expr.getArgumentType().getCanonicalType() + : expr.getArgumentExpr()->getType().getCanonicalType(); + if (llvm::isa(qualType)) { + return BuildExprToComputeSizeFromVLA(allocator, qualType); } + uint32 size = GetSizeFromQualType(qualType); auto integerExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); integerExpr->SetType(PTY_u64); integerExpr->SetVal(size); @@ -1223,7 +1265,9 @@ ASTExpr *ASTParser::ProcessExprImaginaryLiteral(MapleAllocator &allocator, const return astImaginaryLiteral; } -std::map ASTParser::builtingFuncPtrMap = ASTParser::InitFuncPtrMap(); + +std::map ASTParser::builtingFuncPtrMap = + ASTParser::InitBuiltinFuncPtrMap(); ASTExpr *ASTParser::ProcessExprCallExpr(MapleAllocator &allocator, const clang::CallExpr &expr) { ASTCallExpr *astCallExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); @@ -1242,6 +1286,7 @@ ASTExpr *ASTParser::ProcessExprCallExpr(MapleAllocator &allocator, const clang:: for (uint32_t i = 0; i < expr.getNumArgs(); ++i) { const clang::Expr *subExpr = expr.getArg(i); ASTExpr *arg = ProcessExpr(allocator, subExpr); + arg->SetType(astFile->CvtType(subExpr->getType())); args.push_back(arg); } astCallExpr->SetArgs(args); @@ -1253,10 +1298,17 @@ ASTExpr *ASTParser::ProcessExprCallExpr(MapleAllocator &allocator, const clang:: if (!ASTUtil::IsValidName(funcName)) { ASTUtil::AdjustName(funcName); } - auto ptrFunc = builtingFuncPtrMap.find(funcName); - if (ptrFunc != builtingFuncPtrMap.end()) { - return (this->*(ptrFunc->second))(allocator, expr); + + if (builtingFuncPtrMap.find(funcName) != builtingFuncPtrMap.end()) { + std::stringstream ss; + ss << funcName; + ASTExpr *builtinFuncExpr = ParseBuiltinFunc(allocator, expr, ss); + if (builtinFuncExpr != nullptr) { + return builtinFuncExpr; + } + funcName = ss.str(); } + astCallExpr->SetFuncName(funcName); GenericAttrs attrs; astFile->CollectFuncAttrs(*funcDecl, attrs, kPublic); @@ -1264,6 +1316,7 @@ ASTExpr *ASTParser::ProcessExprCallExpr(MapleAllocator &allocator, const clang:: } else { astCallExpr->SetIcall(true); } + astCallExpr->SetType(astFile->CvtType(expr.getType())); return astCallExpr; } @@ -1480,41 +1533,52 @@ ASTExpr *ASTParser::ProcessExprBinaryOperatorComplex(MapleAllocator &allocator, ASTExpr *ASTParser::ProcessExprBinaryOperator(MapleAllocator &allocator, const clang::BinaryOperator &bo) { ASTBinaryOperatorExpr *astBinOpExpr = AllocBinaryOperatorExpr(allocator, bo); CHECK_FATAL(astBinOpExpr != nullptr, "astBinOpExpr is nullptr"); - clang::QualType qualType = bo.getType(); + auto boType = bo.getType().getCanonicalType(); + auto lhsType = bo.getLHS()->getType().getCanonicalType(); + auto rhsType = bo.getRHS()->getType().getCanonicalType(); + auto leftMirType = astFile->CvtType(lhsType); + auto rightMirType = astFile->CvtType(rhsType); auto clangOpCode = bo.getOpcode(); + astBinOpExpr->SetRetType(astFile->CvtType(boType)); if (bo.isCompoundAssignmentOp()) { - clangOpCode = clang::BinaryOperator::getOpForCompoundAssignment(bo.getOpcode()); + clangOpCode = clang::BinaryOperator::getOpForCompoundAssignment(clangOpCode); } - if ((qualType->isAnyComplexType() && + if ((boType->isAnyComplexType() && (clang::BinaryOperator::isAdditiveOp(clangOpCode) || clang::BinaryOperator::isMultiplicativeOp(clangOpCode))) || - (clang::BinaryOperator::isEqualityOp(clangOpCode) && bo.getRHS()->getType()->isAnyComplexType() && - bo.getLHS()->getType()->isAnyComplexType())) { + (clang::BinaryOperator::isEqualityOp(clangOpCode) && lhsType->isAnyComplexType() && + rhsType->isAnyComplexType())) { return ProcessExprBinaryOperatorComplex(allocator, bo); } - astBinOpExpr->SetRetType(astFile->CvtType(qualType)); ASTExpr *astRExpr = ProcessExpr(allocator, bo.getRHS()); ASTExpr *astLExpr = ProcessExpr(allocator, bo.getLHS()); - auto leftMirType = astFile->CvtType(bo.getLHS()->getType()); - auto rightMirType = astFile->CvtType(bo.getRHS()->getType()); + if (clangOpCode == clang::BO_Div) { + if (astBinOpExpr->GetRetType()->GetPrimType() == PTY_u16 || astBinOpExpr->GetRetType()->GetPrimType() == PTY_u8) { + astBinOpExpr->SetRetType(GlobalTables::GetTypeTable().GetPrimType(PTY_u32)); + } + if (astBinOpExpr->GetRetType()->GetPrimType() == PTY_i16 || astBinOpExpr->GetRetType()->GetPrimType() == PTY_i8) { + astBinOpExpr->SetRetType(GlobalTables::GetTypeTable().GetPrimType(PTY_i32)); + } + } if ((leftMirType->GetPrimType() != astBinOpExpr->GetRetType()->GetPrimType() || rightMirType->GetPrimType() != astBinOpExpr->GetRetType()->GetPrimType()) && (clang::BinaryOperator::isAdditiveOp(clangOpCode) || clang::BinaryOperator::isMultiplicativeOp(clangOpCode)) - && !bo.getType()->isPointerType() && !bo.getLHS()->getType()->isPointerType() && - !bo.getRHS()->getType()->isPointerType()) { + && !boType->isPointerType() && !lhsType->isPointerType() && !rhsType->isPointerType()) { astBinOpExpr->SetCvtNeeded(true); } - if (bo.getType()->isPointerType() && clang::BinaryOperator::isAdditiveOp(clangOpCode)) { + // ptr +/- + if (boType->isPointerType() && clang::BinaryOperator::isAdditiveOp(clangOpCode) && lhsType->isPointerType() && + rhsType->isIntegerType()) { auto ptrSizeExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); ptrSizeExpr->SetType(PTY_i32); - ptrSizeExpr->SetVal(GetSizeFromQualType(bo.getType()->getPointeeType())); - if (bo.getLHS()->getType()->isPointerType()) { + ptrSizeExpr->SetVal(GetSizeFromQualType(boType->getPointeeType())); + if (lhsType->isPointerType()) { auto rhs = ASTDeclsBuilder::ASTExprBuilder(allocator); rhs->SetLeftExpr(astRExpr); rhs->SetRightExpr(ptrSizeExpr); rhs->SetOpcode(OP_mul); rhs->SetRetType(GlobalTables::GetTypeTable().GetPrimType(PTY_i32)); astRExpr = rhs; - } else if (bo.getRHS()->getType()->isPointerType()) { + } else if (rhsType->isPointerType()) { auto lhs = ASTDeclsBuilder::ASTExprBuilder(allocator); lhs->SetLeftExpr(astLExpr); lhs->SetRightExpr(ptrSizeExpr); @@ -1525,11 +1589,11 @@ ASTExpr *ASTParser::ProcessExprBinaryOperator(MapleAllocator &allocator, const c } astBinOpExpr->SetLeftExpr(astLExpr); astBinOpExpr->SetRightExpr(astRExpr); - if (clangOpCode == clang::BO_Sub && bo.getRHS()->getType()->isPointerType() && - bo.getLHS()->getType()->isPointerType()) { + // ptr - ptr + if (clangOpCode == clang::BO_Sub && rhsType->isPointerType() && lhsType->isPointerType()) { auto ptrSizeExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); ptrSizeExpr->SetType(astBinOpExpr->GetRetType()->GetPrimType()); - ptrSizeExpr->SetVal(GetSizeFromQualType(bo.getRHS()->getType()->getPointeeType())); + ptrSizeExpr->SetVal(GetSizeFromQualType(rhsType->getPointeeType())); auto retASTExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); retASTExpr->SetLeftExpr(astBinOpExpr); retASTExpr->SetRightExpr(ptrSizeExpr); @@ -1541,7 +1605,7 @@ ASTExpr *ASTParser::ProcessExprBinaryOperator(MapleAllocator &allocator, const c auto assignExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); assignExpr->SetLeftExpr(astLExpr); assignExpr->SetRightExpr(astBinOpExpr); - assignExpr->SetRetType(astFile->CvtType(bo.getType())); + assignExpr->SetRetType(astBinOpExpr->GetRetType()); assignExpr->SetIsCompoundAssign(true); return assignExpr; } @@ -1755,10 +1819,15 @@ bool ASTParser::PreProcessAST() { if (astDecl != nullptr) { \ astDecl->SetDeclPos(astFile->GetDeclPosInfo(decl)); \ astDecl->SetGlobal(decl.isDefinedOutsideFunctionOrMethod()); \ + astDecl->SetAlign(astFile->GetMaxAlign(decl)); \ } \ return astDecl; \ } ASTDecl *ASTParser::ProcessDecl(MapleAllocator &allocator, const clang::Decl &decl) { + ASTDecl *astDecl = ASTDeclsBuilder::GetASTDecl(decl.getID()); + if (astDecl != nullptr) { + return astDecl; + } switch (decl.getKind()) { DECL_CASE(Function); DECL_CASE(Field); @@ -1811,7 +1880,7 @@ ASTDecl *ASTParser::ProcessDeclRecordDecl(MapleAllocator &allocator, const clang auto *fieldDecl = llvm::dyn_cast(loadDecl); if (llvm::isa(loadDecl)) { clang::RecordDecl *subRecordDecl = llvm::cast(loadDecl->getCanonicalDecl()); - ASTStruct *sub = static_cast(ProcessDeclRecordDecl(allocator, *subRecordDecl)); + ASTStruct *sub = static_cast(ProcessDecl(allocator, *subRecordDecl)); if (sub == nullptr) { return nullptr; } @@ -1819,7 +1888,7 @@ ASTDecl *ASTParser::ProcessDeclRecordDecl(MapleAllocator &allocator, const clang } if (llvm::isa(loadDecl)) { - ASTField *af = static_cast(ProcessDeclFieldDecl(allocator, *fieldDecl)); + ASTField *af = static_cast(ProcessDecl(allocator, *fieldDecl)); if (af == nullptr) { return nullptr; } @@ -1859,7 +1928,7 @@ ASTDecl *ASTParser::ProcessDeclFunctionDecl(MapleAllocator &allocator, const cla unsigned int numParam = funcDecl.getNumParams(); for (uint32_t i = 0; i < numParam; ++i) { const clang::ParmVarDecl *parmDecl = funcDecl.getParamDecl(i); - ASTDecl *parmVarDecl = ProcessDeclParmVarDecl(allocator, *parmDecl); + ASTDecl *parmVarDecl = ProcessDecl(allocator, *parmDecl); parmNamesIn.emplace_back(parmVarDecl->GetName()); typeDescIn.push_back(parmVarDecl->GetTypeDesc().front()); } diff --git a/src/mplfe/ast_input/src/ast_parser_builting_func.cpp b/src/mplfe/ast_input/src/ast_parser_builting_func.cpp index f6654b4ae14bffdb39417d6406a6557246f65358..8e0b35559a3788725e71a05d45bd9ef95410afbf 100644 --- a/src/mplfe/ast_input/src/ast_parser_builting_func.cpp +++ b/src/mplfe/ast_input/src/ast_parser_builting_func.cpp @@ -12,68 +12,154 @@ * FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v2 for more details. */ -#include "ast_parser.h" -#include "mpl_logging.h" -#include "mir_module.h" -#include "mpl_logging.h" -#include "ast_decl_builder.h" -#include "ast_interface.h" +#include "ast_expr.h" #include "ast_decl.h" #include "ast_macros.h" +#include "ast_decl_builder.h" +#include "ast_interface.h" #include "ast_util.h" #include "ast_input.h" +#include "ast_stmt.h" +#include "ast_parser.h" +#include "feir_stmt.h" +#include "feir_builder.h" +#include "fe_utils_ast.h" +#include "feir_type_helper.h" #include "fe_manager.h" +#include "mir_module.h" +#include "mpl_logging.h" namespace maple { -std::map ASTParser::InitFuncPtrMap() { - std::map ans; - ans["__builtin_classify_type"] = &ASTParser::ParseBuiltingClassifyType; - ans["__builtin_ctz"] = &ASTParser::ParseBuiltingCtz; - ans["__builtin_clz"] = &ASTParser::ParseBuiltingClz; - ans["__builtin_alloca"] = &ASTParser::ParseBuiltingAlloca; - ans["__builtin_constant_p"] = &ASTParser::ParseBuiltingConstantP; - ans["__builtin_expect"] = &ASTParser::ParseBuiltingExpect; - ans["__builtin_signbit"] = &ASTParser::ParseBuiltingSignbit; - ans["__builtin_isinf_sign"] = &ASTParser::ParseBuiltingIsinfSign; +std::map ASTCallExpr::InitBuiltinFuncPtrMap() { + std::map ans; + ans["alloca"] = &ASTCallExpr::EmitBuiltinAlloca; + ans["__builtin_ctz"] = &ASTCallExpr::EmitBuiltinCtz; + ans["__builtin_clz"] = &ASTCallExpr::EmitBuiltinClz; + ans["__builtin_alloca"] = &ASTCallExpr::EmitBuiltinAlloca; + ans["__builtin_expect"] = &ASTCallExpr::EmitBuiltinExpect; return ans; } -ASTExpr *ASTParser::ParseBuiltingClassifyType(MapleAllocator &allocator, const clang::CallExpr &expr) const { - clang::Expr::EvalResult res; - bool success = expr.EvaluateAsInt(res, *(astFile->GetContext())); - CHECK_FATAL(success, "Failed to evaluate __builtin_classify_type"); - llvm::APSInt apVal = res.Val.getInt(); - ASTIntegerLiteral *astIntegerLiteral = ASTDeclsBuilder::ASTExprBuilder(allocator); - astIntegerLiteral->SetVal(static_cast(apVal.getExtValue())); - astIntegerLiteral->SetType(PTY_i32); - return astIntegerLiteral; +UniqueFEIRExpr ASTCallExpr::EmitBuiltinFunc(std::list &stmts) const { + return (this->*(builtingFuncPtrMap[funcName]))(stmts); } -ASTExpr *ASTParser::ParseBuiltingCtz(MapleAllocator &allocator, const clang::CallExpr &expr) const { +UniqueFEIRExpr ASTCallExpr::EmitBuiltinCtz(std::list &stmts) const { + auto feTy = std::make_unique(*mirType); + std::vector> argOpnds; + for (auto arg : args) { + argOpnds.push_back(arg->Emit2FEExpr(stmts)); + } +#ifndef USE_OPS + CHECK_FATAL(false, "implemention in ops branch"); return nullptr; +#else + if (mirType->GetSize() == 4) { + // 32 bit + return std::make_unique(std::move(feTy), INTRN_C_ctz32, argOpnds); + } + return std::make_unique(std::move(feTy), INTRN_C_ctz32, argOpnds); +#endif } -ASTExpr *ASTParser::ParseBuiltingClz(MapleAllocator &allocator, const clang::CallExpr &expr) const { +UniqueFEIRExpr ASTCallExpr::EmitBuiltinClz(std::list &stmts) const { + auto feTy = std::make_unique(*mirType); + std::vector> argOpnds; + for (auto arg : args) { + argOpnds.push_back(arg->Emit2FEExpr(stmts)); + } +#ifndef USE_OPS + CHECK_FATAL(false, "implemention in ops branch"); return nullptr; +#else + if (mirType->GetSize() == 4) { + // 32 bit + return std::make_unique(std::move(feTy), INTRN_C_clz32, argOpnds); + } + return std::make_unique(std::move(feTy), INTRN_C_clz64, argOpnds); +#endif } -ASTExpr *ASTParser::ParseBuiltingAlloca(MapleAllocator &allocator, const clang::CallExpr &expr) const { - return nullptr; +UniqueFEIRExpr ASTCallExpr::EmitBuiltinAlloca(std::list &stmts) const { + auto arg = args[0]->Emit2FEExpr(stmts); + auto alloca = std::make_unique(OP_alloca, mirType, std::move(arg)); + return alloca; } -ASTExpr *ASTParser::ParseBuiltingConstantP(MapleAllocator &allocator, const clang::CallExpr &expr) const { - return nullptr; +UniqueFEIRExpr ASTCallExpr::EmitBuiltinExpect(std::list &stmts) const { + ASSERT(args.size() == 2, "__builtin_expect requires two arguments"); + auto arg1Expr = args[1]->Emit2FEExpr(stmts); + std::list> argExprsIn; + argExprsIn.push_back(std::move(arg1Expr)); + auto stmt = std::make_unique(OP_eval, std::move(argExprsIn)); + return args[0]->Emit2FEExpr(stmts); } -ASTExpr *ASTParser::ParseBuiltingExpect(MapleAllocator &allocator, const clang::CallExpr &expr) const { - return nullptr; +std::map ASTParser::InitBuiltinFuncPtrMap() { + std::map ans; + ans["__builtin_classify_type"] = &ASTParser::ParseBuiltinClassifyType; + ans["__builtin_constant_p"] = &ASTParser::ParseBuiltinConstantP; + ans["__builtin_signbit"] = &ASTParser::ParseBuiltinSignbit; + ans["__builtin_isinf_sign"] = &ASTParser::ParseBuiltinIsinfsign; + return ans; +} + +ASTExpr *ASTParser::ParseBuiltinFunc(MapleAllocator &allocator, const clang::CallExpr &expr, + std::stringstream &ss) const { + return (this->*(builtingFuncPtrMap[ss.str()]))(allocator, expr, ss); +} + +ASTExpr *ASTParser::ParseBuiltinClassifyType(MapleAllocator &allocator, const clang::CallExpr &expr, + std::stringstream &ss) const { + (void)ss; + clang::Expr::EvalResult res; + bool success = expr.EvaluateAsInt(res, *(astFile->GetContext())); + CHECK_FATAL(success, "Failed to evaluate __builtin_classify_type"); + llvm::APSInt apVal = res.Val.getInt(); + ASTIntegerLiteral *astIntegerLiteral = ASTDeclsBuilder::ASTExprBuilder(allocator); + astIntegerLiteral->SetVal(static_cast(apVal.getExtValue())); + astIntegerLiteral->SetType(PTY_i32); + return astIntegerLiteral; +} + +ASTExpr *ASTParser::ParseBuiltinConstantP(MapleAllocator &allocator, const clang::CallExpr &expr, + std::stringstream &ss) const { + (void)ss; + int constP = expr.getArg(0)->isConstantInitializer(*astFile->GetNonConstAstContext(), false) ? 1 : 0; + // Pointers are not considered constant + if (expr.getArg(0)->getType()->isPointerType() && + !llvm::isa(expr.getArg(0)->IgnoreParenCasts())) { + constP = 0; + } + ASTIntegerLiteral *astIntegerLiteral = ASTDeclsBuilder::ASTExprBuilder(allocator); + astIntegerLiteral->SetVal(static_cast(constP)); + astIntegerLiteral->SetType(astFile->CvtType(expr.getType())->GetPrimType()); + return astIntegerLiteral; } -ASTExpr *ASTParser::ParseBuiltingSignbit(MapleAllocator &allocator, const clang::CallExpr &expr) const { +ASTExpr *ASTParser::ParseBuiltinSignbit(MapleAllocator &allocator, const clang::CallExpr &expr, + std::stringstream &ss) const { + (void)allocator; + (void)expr; + ss.clear(); + ss.str(std::string()); + ss << "__signbit"; return nullptr; } -ASTExpr *ASTParser::ParseBuiltingIsinfSign(MapleAllocator &allocator, const clang::CallExpr &expr) const { +ASTExpr *ASTParser::ParseBuiltinIsinfsign(MapleAllocator &allocator, const clang::CallExpr &expr, + std::stringstream &ss) const { + (void)allocator; + (void)expr; + ss.clear(); + ss.str(std::string()); + if (astFile->CvtType(expr.getArg(0)->getType())->GetPrimType() == PTY_f64) { + ss << "__isinf"; + } else if (astFile->CvtType(expr.getArg(0)->getType())->GetPrimType() == PTY_f32) { + ss << "__isinff"; + } else { + ASSERT(false, "Unsupported type passed to isinf"); + } return nullptr; } } // namespace maple \ No newline at end of file diff --git a/src/mplfe/ast_input/src/ast_stmt.cpp b/src/mplfe/ast_input/src/ast_stmt.cpp index 2ae654e53d68428a61e54db6f2206bd983bbd531..385742f7ef5b89e0f34aa9b93786b4980fb803d8 100644 --- a/src/mplfe/ast_input/src/ast_stmt.cpp +++ b/src/mplfe/ast_input/src/ast_stmt.cpp @@ -192,8 +192,13 @@ std::list ASTContinueStmt::Emit2FEStmtImpl() const { // ---------- ASTUnaryOperatorStmt ---------- std::list ASTUnaryOperatorStmt::Emit2FEStmtImpl() const { std::list stmts; - auto astExpr = exprs.front(); - astExpr->Emit2FEExpr(stmts); + std::list feExprs; + auto feExpr = exprs.front()->Emit2FEExpr(stmts); + if (feExpr != nullptr){ + feExprs.emplace_back(std::move(feExpr)); + auto stmt = std::make_unique(OP_eval, std::move(feExprs)); + stmts.emplace_back(std::move(stmt)); + } return stmts; } @@ -206,6 +211,14 @@ std::list ASTGotoStmt::Emit2FEStmtImpl() const { return stmts; } +// ---------- ASTIndirectGotoStmt ---------- +std::list ASTIndirectGotoStmt::Emit2FEStmtImpl() const { + std::list stmts; + UniqueFEIRExpr targetExpr = exprs.front()->Emit2FEExpr(stmts); + stmts.emplace_back(FEIRBuilder::CreateStmtIGoto(std::move(targetExpr))); + return stmts; +} + // ---------- ASTSwitchStmt ---------- std::list ASTSwitchStmt::Emit2FEStmtImpl() const { std::list stmts; @@ -268,6 +281,7 @@ std::map ASTCallExprStmt::Init std::map ans; ans["__builtin_va_start"] = &ASTCallExprStmt::ProcessBuiltinVaStart; ans["__builtin_va_end"] = &ASTCallExprStmt::ProcessBuiltinVaEnd; + ans["__builtin_va_copy"] = &ASTCallExprStmt::ProcessBuiltinVaCopy; return ans; } @@ -351,13 +365,10 @@ std::list ASTCallExprStmt::ProcessBuiltinVaStart() const { auto exprArgList = std::make_unique>(); for (int32 i = argsExprs.size() - 1; i >= 0; --i) { UniqueFEIRExpr expr = argsExprs[i]->Emit2FEExpr(stmts); - // addrof va_list instead of dread va_list - if (i == 0 && expr->GetKind() == kExprDRead) { - UniqueFEIRVar var = static_cast(expr.get())->GetVar()->Clone(); - expr = FEIRBuilder::CreateExprAddrofVar(std::move(var)); - } exprArgList->push_front(std::move(expr)); } + // addrof va_list instead of dread va_list + exprArgList->front()->SetAddrof(true); #ifndef USE_OPS CHECK_FATAL(false, "implemention in ops branch"); #else @@ -374,14 +385,12 @@ std::list ASTCallExprStmt::ProcessBuiltinVaEnd() const { ASTCallExpr *callExpr = static_cast(exprs.front()); // args std::vector argsExprs = callExpr->GetArgsExpr(); + ASSERT(argsExprs.size() == 1, "va_end expects 2 arguments"); std::list exprArgList; for (int32 i = argsExprs.size() - 1; i >= 0; --i) { UniqueFEIRExpr expr = argsExprs[i]->Emit2FEExpr(stmts); // addrof va_list instead of dread va_list - if (i == 0 && expr->GetKind() == kExprDRead) { - UniqueFEIRVar var = static_cast(expr.get())->GetVar()->Clone(); - expr = FEIRBuilder::CreateExprAddrofVar(std::move(var)); - } + expr->SetAddrof(true); exprArgList.push_front(std::move(expr)); } auto stmt = std::make_unique(OP_eval, std::move(exprArgList)); @@ -390,6 +399,34 @@ std::list ASTCallExprStmt::ProcessBuiltinVaEnd() const { return stmts; } +std::list ASTCallExprStmt::ProcessBuiltinVaCopy() const { + std::list stmts; + ASTCallExpr *callExpr = static_cast(exprs.front()); + // args + std::vector argsExprs = callExpr->GetArgsExpr(); + auto exprArgList = std::make_unique>(); + UniqueFEIRType vaListType; + for (int32 i = argsExprs.size() - 1; i >= 0; --i) { + UniqueFEIRExpr expr = argsExprs[i]->Emit2FEExpr(stmts); + // addrof va_list instead of dread va_list + expr->SetAddrof(true); + vaListType = expr->GetType()->Clone(); + exprArgList->push_front(std::move(expr)); + } + // Add the size of the va_list structure as the size to memcpy. + UniqueFEIRExpr sizeExpr = FEIRBuilder::CreateExprConstI32(vaListType->GenerateMIRTypeAuto()->GetSize()); + exprArgList->emplace_back(std::move(sizeExpr)); +#ifndef USE_OPS + CHECK_FATAL(false, "implemention in ops branch"); +#else + std::unique_ptr stmt = std::make_unique( + INTRN_C_memcpy, nullptr /* type */, nullptr /* retVar */, std::move(exprArgList)); + stmt->SetSrcFileInfo(GetSrcFileIdx(), GetSrcFileLineNum()); + stmts.emplace_back(std::move(stmt)); +#endif + return stmts; +} + // ---------- ASTImplicitCastExprStmt ---------- std::list ASTImplicitCastExprStmt::Emit2FEStmtImpl() const { CHECK_FATAL(exprs.size() == 1, "Only one sub expr supported!"); @@ -427,14 +464,20 @@ std::list ASTIntegerLiteralStmt::Emit2FEStmtImpl() const { // ---------- ASTVAArgExprStmt ---------- std::list ASTVAArgExprStmt::Emit2FEStmtImpl() const { std::list stmts; + exprs.front()->Emit2FEExpr(stmts); return stmts; } // ---------- ASTConditionalOperatorStmt ---------- std::list ASTConditionalOperatorStmt::Emit2FEStmtImpl() const { std::list stmts; - auto astExpr = exprs.front(); - astExpr->Emit2FEExpr(stmts); + std::list feExprs; + auto feExpr = exprs.front()->Emit2FEExpr(stmts); + if (feExpr != nullptr) { + feExprs.emplace_back(std::move(feExpr)); + auto stmt = std::make_unique(OP_eval, std::move(feExprs)); + stmts.emplace_back(std::move(stmt)); + } return stmts; } @@ -454,7 +497,13 @@ std::list ASTStmtExprStmt::Emit2FEStmtImpl() const { std::list ASTCStyleCastExprStmt::Emit2FEStmtImpl() const { CHECK_FATAL(exprs.front() != nullptr, "child expr must not be nullptr!"); std::list stmts; - exprs.front()->Emit2FEExpr(stmts); + std::list feExprs; + auto feExpr = exprs.front()->Emit2FEExpr(stmts); + if (feExpr != nullptr) { + feExprs.emplace_back(std::move(feExpr)); + auto stmt = std::make_unique(OP_eval, std::move(feExprs)); + stmts.emplace_back(std::move(stmt)); + } return stmts; } diff --git a/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp b/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp index 5cf50446bf08bd83d25b7320735eff4a670a99da..f2694adfda96fe4bc673439cf6c9544fc20b0e29 100644 --- a/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp +++ b/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp @@ -126,6 +126,7 @@ bool ASTStructField2FEHelper::ProcessDeclWithContainerImpl(MapleAllocator &alloc std::string fieldName = field.GetName(); GStrIdx idx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fieldName); FieldAttrs attrs = field.GetGenericAttrs().ConvertToFieldAttrs(); + attrs.SetAlign(field.GetAlign()); MIRType *fieldType = field.GetTypeDesc().front(); ASSERT(fieldType != nullptr, "nullptr check for fieldType"); mirFieldPair.first = idx; diff --git a/src/mplfe/common/include/feir_builder.h b/src/mplfe/common/include/feir_builder.h index 7b7a206a841530d3160786999ae7a6f9d985ac1a..9ed9d424c012b336fb9d428a4765348f36f493a6 100644 --- a/src/mplfe/common/include/feir_builder.h +++ b/src/mplfe/common/include/feir_builder.h @@ -41,11 +41,13 @@ class FEIRBuilder { bool withType = false); static UniqueFEIRVar CreateVarNameForC(const std::string &name, MIRType &mirType, bool isGlobal = false, bool withType = false); + static UniqueFEIRVar CreateVarNameForC(const std::string &name, UniqueFEIRType type, + bool isGlobal = false, bool withType = false); // Expr static UniqueFEIRExpr CreateExprSizeOfType(UniqueFEIRType ty); static UniqueFEIRExpr CreateExprDRead(UniqueFEIRVar srcVar); static UniqueFEIRExpr CreateExprDReadAggField(UniqueFEIRVar srcVar, FieldID fieldID, UniqueFEIRType fieldType); - static UniqueFEIRExpr CreateExprAddrof(const std::vector &array); + static UniqueFEIRExpr CreateExprAddrofLabel(const std::string &lbName, UniqueFEIRType exprTy); static UniqueFEIRExpr CreateExprAddrofVar(UniqueFEIRVar srcVar); static UniqueFEIRExpr CreateExprAddrofFunc(const std::string &addr); static UniqueFEIRExpr CreateExprAddrofArray(UniqueFEIRType argTypeNativeArray, @@ -65,7 +67,7 @@ class FEIRBuilder { static UniqueFEIRExpr CreateExprConstU64(uint64 val); static UniqueFEIRExpr CreateExprConstF32(float val); static UniqueFEIRExpr CreateExprConstF64(double val); - static UniqueFEIRExpr CreateExprConstAnyScalar(PrimType primType, int8 val); + static UniqueFEIRExpr CreateExprConstAnyScalar(PrimType primType, int64 val); static UniqueFEIRExpr CreateExprMathUnary(Opcode op, UniqueFEIRVar var0); static UniqueFEIRExpr CreateExprMathUnary(Opcode op, UniqueFEIRExpr expr); static UniqueFEIRExpr CreateExprMathBinary(Opcode op, UniqueFEIRVar var0, UniqueFEIRVar var1); @@ -101,8 +103,11 @@ class FEIRBuilder { // Stmt static UniqueFEIRStmt CreateStmtDAssign(UniqueFEIRVar dstVar, UniqueFEIRExpr srcExpr, bool hasException = false); static UniqueFEIRStmt CreateStmtDAssignAggField(UniqueFEIRVar dstVar, UniqueFEIRExpr srcExpr, FieldID fieldID); + static UniqueFEIRStmt CreateStmtIAssign(UniqueFEIRType dstType, UniqueFEIRExpr dstExpr, + UniqueFEIRExpr srcExpr, FieldID fieldID = 0); static UniqueFEIRStmt CreateStmtGoto(uint32 targetLabelIdx); static UniqueFEIRStmt CreateStmtGoto(const std::string &labelName); + static UniqueFEIRStmt CreateStmtIGoto(UniqueFEIRExpr targetExpr); static UniqueFEIRStmt CreateStmtCondGoto(uint32 targetLabelIdx, Opcode op, UniqueFEIRExpr expr); static UniqueFEIRStmt CreateStmtSwitch(UniqueFEIRExpr expr); static UniqueFEIRStmt CreateStmtIfWithoutElse(UniqueFEIRExpr cond, std::list &thenStmts); @@ -143,6 +148,8 @@ class FEIRBuilder { MIRStructType *structType, FieldID fieldID); static UniqueFEIRStmt CreateStmtRetype(UniqueFEIRVar varDst, const UniqueFEIRVar &varSrc); static UniqueFEIRStmt CreateStmtComment(const std::string &comment); + static UniqueFEIRExpr ReadExprField(UniqueFEIRExpr expr, FieldID fieldID, UniqueFEIRType fieldType); + static UniqueFEIRStmt AssginStmtField(UniqueFEIRExpr addrExpr, UniqueFEIRExpr srcExpr, FieldID fieldID); }; // class FEIRBuilder } // namespace maple #endif // MPLFE_INCLUDE_COMMON_FEIR_BUILDER_H diff --git a/src/mplfe/common/include/feir_node_kind.def b/src/mplfe/common/include/feir_node_kind.def index 516007003bf114765f76106a6b14f189cd70aa68..7231cfd70a5c1792687e7780bd7325b89ef77bbc 100644 --- a/src/mplfe/common/include/feir_node_kind.def +++ b/src/mplfe/common/include/feir_node_kind.def @@ -18,6 +18,7 @@ FEIR_NODE_KIND(StmtUseOnly, "StmtUseOnly") FEIR_NODE_KIND(StmtReturn, "StmtReturn") FEIR_NODE_KIND(StmtBranch, "StmtBranch") FEIR_NODE_KIND(StmtGoto, "StmtGoto") +FEIR_NODE_KIND(StmtIGoto, "StmtIGoto") FEIR_NODE_KIND(StmtCondGoto, "StmtCondGoto") FEIR_NODE_KIND(StmtSwitch, "StmtSwitch") FEIR_NODE_KIND(StmtArrayStore, "StmtArrayStore") @@ -43,6 +44,7 @@ FEIR_NODE_KIND(ExprTernary, "ExprTernary") FEIR_NODE_KIND(ExprNary, "ExprNary") FEIR_NODE_KIND(ExprArray, "ExprArray") FEIR_NODE_KIND(ExprAddrof, "ExprAddrof") +FEIR_NODE_KIND(ExprAddrofLabel, "ExprAddrofLabel") FEIR_NODE_KIND(ExprIAddrof, "ExprIAddrof") FEIR_NODE_KIND(ExprAddrofVar, "ExprAddrofVar") FEIR_NODE_KIND(ExprAddrofFunc, "ExprAddrofFunc") diff --git a/src/mplfe/common/include/feir_stmt.h b/src/mplfe/common/include/feir_stmt.h index 5fcfe43a43e245f65e675bae5a4f4e2a926ccf3f..3c7230bf5741694c19b36c14c96e74051ad26947 100644 --- a/src/mplfe/common/include/feir_stmt.h +++ b/src/mplfe/common/include/feir_stmt.h @@ -156,6 +156,7 @@ class FEIRStmt : public GeneralStmt { bool IsStmtInstComment() const; bool ShouldHaveLOC() const; + BaseNode *ReplaceAddrOfNode(BaseNode *node) const; void SetSrcFileInfo(uint32 srcFileIdxIn, uint32 srcFileLineNumIn) { srcFileIndex = srcFileIdxIn; srcFileLineNum = srcFileLineNumIn; @@ -283,6 +284,10 @@ class FEIRExpr { return IsAddrofImpl(); } + void SetAddrof(bool flag) { + isAddrof = flag; + } + bool HasException() const { return HasExceptionImpl(); } @@ -308,6 +313,18 @@ class FEIRExpr { return GetPrimTypeImpl(); } + FieldID GetFieldID() const { + return GetFieldIDImpl(); + } + + void SetFieldID(FieldID fieldID) { + return SetFieldIDImpl(fieldID); + } + + void SetFieldType(std::unique_ptr fieldType) { + return SetFieldTypeImpl(std::move(fieldType)); + } + void RegisterDFGNodes2CheckPoint(FEIRStmtCheckPoint &checkPoint) { RegisterDFGNodes2CheckPointImpl(checkPoint); } @@ -339,6 +356,18 @@ class FEIRExpr { return *GetTypeImpl(); } + virtual FieldID GetFieldIDImpl() const { + CHECK_FATAL(false, "unsupported in base class"); + } + + virtual void SetFieldIDImpl(FieldID fieldID) { + CHECK_FATAL(false, "unsupported in base class"); + } + + virtual void SetFieldTypeImpl(std::unique_ptr fieldType) { + CHECK_FATAL(false, "unsupported in base class"); + } + virtual bool IsNestableImpl() const; virtual bool IsAddrofImpl() const; virtual bool HasExceptionImpl() const; @@ -432,26 +461,14 @@ class FEIRExprDRead : public FEIRExpr { return trans; } - FieldID GetFieldID() const { - return fieldID; - } - UniqueFEIRVar &GetVar() { return varSrc; } - void SetFieldType(std::unique_ptr type) { - fieldType = std::move(type); - } - std::unique_ptr GetFieldType() const { return fieldType->Clone(); } - void SetFieldID(FieldID argFieldID) { - fieldID = argFieldID; - } - protected: std::unique_ptr CloneImpl() const override; void RegisterDFGNodes2CheckPointImpl(FEIRStmtCheckPoint &checkPoint) override; @@ -462,6 +479,18 @@ class FEIRExprDRead : public FEIRExpr { FEIRType *GetTypeImpl() const override; const FEIRType &GetTypeRefImpl() const override; + FieldID GetFieldIDImpl() const override { + return fieldID; + } + + void SetFieldTypeImpl(std::unique_ptr type) override { + fieldType = std::move(type); + } + + void SetFieldIDImpl(FieldID argFieldID) override { + fieldID = argFieldID; + } + private: std::unique_ptr varSrc; FieldID fieldID = 0; @@ -482,14 +511,18 @@ class FEIRExprRegRead : public FEIRExpr { int32 regNum; }; -// ---------- FEIRExprAddrof ---------- -class FEIRExprAddrof : public FEIRExpr { +// ---------- FEIRExprAddrofConstArray ---------- +class FEIRExprAddrofConstArray : public FEIRExpr { public: - explicit FEIRExprAddrof(const std::vector &arrayIn) + explicit FEIRExprAddrofConstArray(const std::vector &arrayIn, MIRType *typeIn) : FEIRExpr(FEIRNodeKind::kExprAddrof, FEIRTypeHelper::CreateTypeNative(*GlobalTables::GetTypeTable().GetPtrType())), - array(arrayIn) {} - ~FEIRExprAddrof() = default; + array(arrayIn), type(typeIn) {} + ~FEIRExprAddrofConstArray() = default; + + uint32 GetStringLiteralSize() const { + return array.size(); + } protected: std::unique_ptr CloneImpl() const override; @@ -497,6 +530,22 @@ class FEIRExprAddrof : public FEIRExpr { private: std::vector array; + MIRType *type; +}; + +// ---------- FEIRExprAddrOfLabel ---------- +class FEIRExprAddrOfLabel : public FEIRExpr { + public: + FEIRExprAddrOfLabel(const std::string &lbName, UniqueFEIRType exprType) + : FEIRExpr(FEIRNodeKind::kExprAddrofLabel, std::move(exprType)), labelName(lbName) {} + ~FEIRExprAddrOfLabel() = default; + + protected: + std::unique_ptr CloneImpl() const override; + BaseNode *GenMIRNodeImpl(MIRBuilder &mirBuilder) const override; + + private: + std::string labelName; }; // ---------- FEIRExprAddrofVar ---------- @@ -508,10 +557,6 @@ class FEIRExprAddrofVar : public FEIRExpr { varSrc(std::move(argVarSrc)) {} ~FEIRExprAddrofVar() = default; - void SetFieldID(FieldID id) { - fieldID = id; - } - void SetVarValue(MIRConst *val) { cst = val; } @@ -525,6 +570,14 @@ class FEIRExprAddrofVar : public FEIRExpr { BaseNode *GenMIRNodeImpl(MIRBuilder &mirBuilder) const override; std::vector GetVarUsesImpl() const override; + FieldID GetFieldIDImpl() const override { + return fieldID; + } + + void SetFieldIDImpl(FieldID id) override { + fieldID = id; + } + private: std::unique_ptr varSrc; FieldID fieldID = 0; @@ -542,14 +595,6 @@ class FEIRExprIAddrof : public FEIRExpr { subExpr(std::move(expr)) {} ~FEIRExprIAddrof() = default; - void SetFieldID(FieldID argFieldID) { - fieldID = argFieldID; - } - - FieldID GetFieldID() const { - return fieldID; - } - UniqueFEIRType GetClonedRetType() const { return type->Clone(); } @@ -566,6 +611,14 @@ class FEIRExprIAddrof : public FEIRExpr { std::unique_ptr CloneImpl() const override; BaseNode *GenMIRNodeImpl(MIRBuilder &mirBuilder) const override; + FieldID GetFieldIDImpl() const override { + return fieldID; + } + + void SetFieldIDImpl(FieldID argFieldID) override { + fieldID = argFieldID; + } + private: UniqueFEIRType ptrType; FieldID fieldID = 0; @@ -722,14 +775,6 @@ class FEIRExprIRead : public FEIRExpr { subExpr(std::move(expr)) {} ~FEIRExprIRead() override = default; - void SetFieldID(FieldID argFieldID) { - fieldID = argFieldID; - } - - FieldID GetFieldID() const { - return fieldID; - } - UniqueFEIRType GetClonedRetType() const { return type->Clone(); } @@ -746,6 +791,18 @@ class FEIRExprIRead : public FEIRExpr { std::unique_ptr CloneImpl() const override; BaseNode *GenMIRNodeImpl(MIRBuilder &mirBuilder) const override; + FieldID GetFieldIDImpl() const override { + return fieldID; + } + + void SetFieldIDImpl(FieldID argFieldID) override { + fieldID = argFieldID; + } + + void SetFieldTypeImpl(UniqueFEIRType argFieldType) override { + type = std::move(argFieldType); + } + private: UniqueFEIRType ptrType = nullptr; FieldID fieldID = 0; @@ -983,6 +1040,10 @@ class FEIRExprArrayStoreForC : public FEIRExpr { return *exprArray.get(); } + const UniqueFEIRExpr &GetUniqueExprArray() const { + return exprArray; + } + std::list &GetExprIndexs() const { ASSERT(!exprIndexs.empty(), "exprIndex is nullptr"); return exprIndexs; @@ -1006,6 +1067,10 @@ class FEIRExprArrayStoreForC : public FEIRExpr { return *typeNative.get(); } + const UniqueFEIRType &GetUniqueTypeArray() const { + return typeNative; + } + FEIRType &GetTypeSruct() const { ASSERT(typeNativeStruct != nullptr, "typeNativeStruct is nullptr"); return *typeNativeStruct.get(); @@ -1030,12 +1095,26 @@ class FEIRExprArrayStoreForC : public FEIRExpr { FEIRType *GetTypeImpl() const override; const FEIRType &GetTypeRefImpl() const override; + FieldID GetFieldIDImpl() const override { + return fieldID; + } + + void SetFieldIDImpl(FieldID argFeildID) override { + fieldID = argFeildID; + } + + void SetFieldTypeImpl(std::unique_ptr argFieldType) override { + fieldType = std::move(argFieldType); + } + private: UniqueFEIRExpr exprArray; mutable std::list exprIndexs; UniqueFEIRType elemType = nullptr; - UniqueFEIRType typeNative = nullptr; + UniqueFEIRType typeNative; bool isAddrOf = false; + FieldID fieldID = 0; + UniqueFEIRType fieldType = nullptr; UniqueFEIRType ptrType = FEIRTypeHelper::CreateTypeNative(*GlobalTables::GetTypeTable().GetPtrType()); // for array in struct @@ -1569,6 +1648,26 @@ class FEIRStmtGotoForC : public FEIRStmt { std::string labelName; }; +// ---------- FEIRStmtIGoto ---------- +class FEIRStmtIGoto : public FEIRStmt { + public: + explicit FEIRStmtIGoto(UniqueFEIRExpr expr); + virtual ~FEIRStmtIGoto() = default; + + protected: + bool IsFallThroughImpl() const override { + return false; + } + + bool IsBranchImpl() const override { + return true; + } + + std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + + UniqueFEIRExpr targetExpr; +}; + // ---------- FEIRStmtCondGotoForC ---------- class FEIRStmtCondGotoForC : public FEIRStmt { public: @@ -2113,6 +2212,7 @@ class FEIRStmtIntrinsicCallAssign : public FEIRStmtAssign { private: void ConstructArgsForInvokePolyMorphic(MIRBuilder &mirBuilder, MapleVector &intrnCallargs) const; std::list GenMIRStmtsForInvokePolyMorphic(MIRBuilder &mirBuilder) const; + MIRIntrinsicID intrinsicId; UniqueFEIRType type; std::unique_ptr> exprList; diff --git a/src/mplfe/common/include/feir_var.h b/src/mplfe/common/include/feir_var.h index 62b77f77d2b95a5a8aee97c7068ad25c0147f282..a699784a1139b08c5458f127aeb033725f5efdc0 100644 --- a/src/mplfe/common/include/feir_var.h +++ b/src/mplfe/common/include/feir_var.h @@ -165,7 +165,7 @@ class FEIRVar { UniqueFEIRType type; UniqueFEIRVarTrans trans; GenericAttrs genAttrs; - MIRConst *mirConst; + MIRConst *mirConst = nullptr; }; using UniqueFEIRVar = std::unique_ptr; diff --git a/src/mplfe/common/src/feir_builder.cpp b/src/mplfe/common/src/feir_builder.cpp index 82b4b1ec0ca61a02638e8d71e6e3839dc43dba56..d2e836647d3df004c616b135c016e323382a82c1 100644 --- a/src/mplfe/common/src/feir_builder.cpp +++ b/src/mplfe/common/src/feir_builder.cpp @@ -90,6 +90,14 @@ UniqueFEIRVar FEIRBuilder::CreateVarNameForC(const std::string &name, MIRType &m return CreateVarNameForC(nameIdx, mirType, isGlobal, withType); } +UniqueFEIRVar FEIRBuilder::CreateVarNameForC(const std::string &name, UniqueFEIRType type, + bool isGlobal, bool withType) { + GStrIdx nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name); + UniqueFEIRVar var = std::make_unique(nameIdx, std::move(type), withType); + var->SetGlobal(isGlobal); + return var; +} + UniqueFEIRExpr FEIRBuilder::CreateExprSizeOfType(UniqueFEIRType ty) { UniqueFEIRExpr expr = std::make_unique(std::move(ty)); return expr; @@ -104,7 +112,7 @@ UniqueFEIRExpr FEIRBuilder::CreateExprDRead(UniqueFEIRVar srcVar) { UniqueFEIRExpr FEIRBuilder::CreateExprDReadAggField(UniqueFEIRVar srcVar, FieldID fieldID, UniqueFEIRType fieldType) { CHECK_FATAL(srcVar != nullptr && srcVar->GetType()->GetPrimType() == PTY_agg, "var type must be struct type, %u", srcVar->GetType()->GetPrimType()); - std::unique_ptr expr = std::make_unique(std::move(srcVar)); + UniqueFEIRExpr expr = std::make_unique(std::move(srcVar)); expr->SetFieldID(fieldID); expr->SetFieldType(std::move(fieldType)); return expr; @@ -117,8 +125,8 @@ UniqueFEIRExpr FEIRBuilder::CreateExprIRead(UniqueFEIRType returnType, UniqueFEI return feirExpr; } -UniqueFEIRExpr FEIRBuilder::CreateExprAddrof(const std::vector &array) { - UniqueFEIRExpr expr = std::make_unique(array); +UniqueFEIRExpr FEIRBuilder::CreateExprAddrofLabel(const std::string &lbName, UniqueFEIRType exprTy) { + UniqueFEIRExpr expr = std::make_unique(lbName, std::move(exprTy)); CHECK_NULL_FATAL(expr); return expr; } @@ -190,7 +198,7 @@ UniqueFEIRExpr FEIRBuilder::CreateExprConstF64(double val) { // Create a const expr of specified prime type with fixed value. // Note that loss of precision, byte value is only supported. -UniqueFEIRExpr FEIRBuilder::CreateExprConstAnyScalar(PrimType primType, int8 val) { +UniqueFEIRExpr FEIRBuilder::CreateExprConstAnyScalar(PrimType primType, int64 val) { switch (primType) { case PTY_u8: case PTY_u16: @@ -200,7 +208,7 @@ UniqueFEIRExpr FEIRBuilder::CreateExprConstAnyScalar(PrimType primType, int8 val case PTY_i16: case PTY_i32: case PTY_i64: - return std::make_unique(static_cast(val), primType); + return std::make_unique(val, primType); case PTY_f128: // Not Implemented CHECK_FATAL(false, "Not Implemented"); @@ -361,6 +369,13 @@ UniqueFEIRStmt FEIRBuilder::CreateStmtDAssignAggField(UniqueFEIRVar dstVar, Uniq return stmt; } +UniqueFEIRStmt FEIRBuilder::CreateStmtIAssign(UniqueFEIRType dstType, UniqueFEIRExpr dstExpr, + UniqueFEIRExpr srcExpr, FieldID fieldID /* optional parameters */) { + UniqueFEIRStmt stmt = std::make_unique( + std::move(dstType), std::move(dstExpr), std::move(srcExpr), fieldID); + return stmt; +} + UniqueFEIRStmt FEIRBuilder::CreateStmtGoto(uint32 targetLabelIdx) { UniqueFEIRStmt stmt = std::make_unique(targetLabelIdx); CHECK_NULL_FATAL(stmt); @@ -373,6 +388,12 @@ UniqueFEIRStmt FEIRBuilder::CreateStmtGoto(const std::string &labelName) { return stmt; } +UniqueFEIRStmt FEIRBuilder::CreateStmtIGoto(UniqueFEIRExpr targetExpr) { + UniqueFEIRStmt stmt = std::make_unique(std::move(targetExpr)); + 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); @@ -582,4 +603,33 @@ UniqueFEIRStmt FEIRBuilder::CreateStmtComment(const std::string &comment) { UniqueFEIRStmt stmt = std::make_unique(comment); return stmt; } + +UniqueFEIRExpr FEIRBuilder::ReadExprField(UniqueFEIRExpr expr, FieldID fieldID, UniqueFEIRType fieldType) { + FieldID baseID = expr->GetFieldID(); + expr->SetFieldID(baseID + fieldID); + expr->SetFieldType(std::move(fieldType)); + return expr; +} + +UniqueFEIRStmt FEIRBuilder::AssginStmtField(UniqueFEIRExpr addrExpr, UniqueFEIRExpr srcExpr, FieldID fieldID) { + UniqueFEIRStmt stmt; + FieldID baseID = addrExpr->GetFieldID(); + UniqueFEIRType addrType = addrExpr->GetType()->Clone(); + UniqueFEIRType ptrType = FEIRTypeHelper::CreateTypeNative( + *GlobalTables::GetTypeTable().GetOrCreatePointerType(*addrType->GenerateMIRTypeAuto(), PTY_ptr)); + if (addrExpr->GetKind() == kExprDRead) { + stmt = CreateStmtDAssignAggField( + static_cast(addrExpr.get())->GetVar()->Clone(), std::move(srcExpr), baseID + fieldID); + } else if (addrExpr->GetKind() == kExprArrayStoreForC) { + auto arrayExpr = static_cast(addrExpr.get()); + arrayExpr->SetAddrOfFlag(true); // retrun addr + stmt = CreateStmtIAssign(std::move(ptrType), std::move(addrExpr), std::move(srcExpr), baseID + fieldID); + } else if (addrExpr->GetKind() == kExprIRead) { + auto ireadExpr = static_cast(addrExpr.get()); + stmt = CreateStmtIAssign(std::move(ptrType), ireadExpr->GetClonedOpnd(), std::move(srcExpr), baseID + fieldID); + } else { + CHECK_FATAL(false, "unsupported expr in AssginStmtField"); + } + return stmt; +} } // namespace maple diff --git a/src/mplfe/common/src/feir_stmt.cpp b/src/mplfe/common/src/feir_stmt.cpp index a1d7574f149217978d5896c02d0a850dd8a0f24e..4566322b293edbbbbce5824ba1d423e5c7168d3c 100644 --- a/src/mplfe/common/src/feir_stmt.cpp +++ b/src/mplfe/common/src/feir_stmt.cpp @@ -84,6 +84,21 @@ bool FEIRStmt::ShouldHaveLOC() const { return (IsStmtInstImpl() || IsStmtInstComment()); } +BaseNode *FEIRStmt::ReplaceAddrOfNode(BaseNode *node) const { + switch (node->GetOpCode()) { + case OP_dread: + node->SetOpCode(OP_addrof); + node->SetPrimType(PTY_ptr); + return node; + case OP_iread: + node->SetOpCode(OP_iaddrof); + node->SetPrimType(PTY_ptr); + return node; + default: + return node; + } +} + std::string FEIRStmt::DumpDotStringImpl() const { std::stringstream ss; ss << " " << id << ": " << GetFEIRNodeKindDescription(kind); @@ -217,6 +232,9 @@ std::list FEIRStmtNary::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const stmt = mirBuilder.CreateStmtNary(op, std::move(args)); } else if (argExprs.size() == 1) { BaseNode *node = argExprs.front()->GenMIRNode(mirBuilder); + if (op == OP_eval && argExprs.front()->IsAddrof()) { + node = ReplaceAddrOfNode(node); // addrof va_list + } stmt = mirBuilder.CreateStmtNary(op, node); } else { CHECK_FATAL(false, "Invalid arg size for MIR StmtNary"); @@ -787,6 +805,20 @@ std::string FEIRStmtGotoForC::DumpDotStringImpl() const { return ss.str(); } +// ---------- FEIRStmtIGoto ---------- +FEIRStmtIGoto::FEIRStmtIGoto(UniqueFEIRExpr expr) : FEIRStmt(kStmtIGoto), targetExpr(std::move(expr)) {} + +std::list FEIRStmtIGoto::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { + std::list stmts; +#ifndef USE_OPS + CHECK_FATAL(false, "Unsupported yet"); + return stmts; +#else + stmts.emplace_back(mirBuilder.CreateStmtUnary(OP_igoto, targetExpr->GenMIRNode(mirBuilder))); + return stmts; +#endif +} + // ---------- FEIRStmtCondGotoForC ---------- std::list FEIRStmtCondGotoForC::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { std::list ans; @@ -1962,15 +1994,18 @@ std::list FEIRStmtIntrinsicCallAssign::GenMIRStmtsImpl(MIRBuilder &mi return GenMIRStmtsForInvokePolyMorphic(mirBuilder); } #ifdef USE_OPS - else if (intrinsicId == INTRN_C_va_start) { + else if (intrinsicId == INTRN_C_va_start || intrinsicId == INTRN_C_memcpy) { MapleVector args(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter()); if (exprList != nullptr) { for (const auto &expr : *exprList) { BaseNode *node = expr->GenMIRNode(mirBuilder); + if (expr->IsAddrof()) { + node = ReplaceAddrOfNode(node); // addrof va_list + } args.push_back(node); } } - stmtCall = mirBuilder.CreateStmtIntrinsicCall(INTRN_C_va_start, std::move(args), TyIdx(0)); + stmtCall = mirBuilder.CreateStmtIntrinsicCall(intrinsicId, std::move(args), TyIdx(0)); } else if (intrinsicId == INTRN_C_memset) { MapleVector args(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter()); if (exprList != nullptr) { @@ -2225,7 +2260,7 @@ FEIRExprDRead::FEIRExprDRead(std::unique_ptr argType, std::unique_ptr< } std::unique_ptr FEIRExprDRead::CloneImpl() const { - std::unique_ptr expr = std::make_unique(type->Clone(), varSrc->Clone()); + UniqueFEIRExpr expr = std::make_unique(type->Clone(), varSrc->Clone()); if (fieldType != nullptr) { expr->SetFieldType(fieldType->Clone()); } @@ -2301,23 +2336,22 @@ BaseNode *FEIRExprIRead::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { return mirBuilder.CreateExprIread(*returnType, *mirPtrType, fieldID, node); } -// ---------- FEIRExprAddrof ---------- -std::unique_ptr FEIRExprAddrof::CloneImpl() const { - std::unique_ptr expr = std::make_unique(array); +// ---------- FEIRExprAddrofConstArray ---------- +std::unique_ptr FEIRExprAddrofConstArray::CloneImpl() const { + std::unique_ptr expr = std::make_unique(array, type); return expr; } -BaseNode *FEIRExprAddrof::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { +BaseNode *FEIRExprAddrofConstArray::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { std::string arrayName = FEUtils::GetSequentialName("const_array_"); - MIRType *elemType = GlobalTables::GetTypeTable().GetPrimType(PTY_u8); - MIRType *arrayTypeWithSize = GlobalTables::GetTypeTable().GetOrCreateArrayType(*elemType, array.size()); + MIRType *arrayTypeWithSize = GlobalTables::GetTypeTable().GetOrCreateArrayType(*type, array.size()); MIRSymbol *arrayVar = mirBuilder.GetOrCreateGlobalDecl(arrayName, *arrayTypeWithSize); arrayVar->SetAttr(ATTR_readonly); arrayVar->SetStorageClass(kScFstatic); MIRModule &module = mirBuilder.GetMirModule(); MIRAggConst *val = module.GetMemPool()->New(module, *arrayTypeWithSize); for (uint32 i = 0; i < array.size(); ++i) { - MIRConst *cst = module.GetMemPool()->New(array[i], *elemType); + MIRConst *cst = module.GetMemPool()->New(array[i], *type); val->PushBack(cst); } arrayVar->SetKonst(val); @@ -2325,6 +2359,19 @@ BaseNode *FEIRExprAddrof::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { return nodeAddrof; } +// ---------- FEIRExprAddrOfLabel --------- +std::unique_ptr FEIRExprAddrOfLabel::CloneImpl() const { + std::unique_ptr expr = std::make_unique(labelName, type->Clone()); + return expr; +} + +BaseNode *FEIRExprAddrOfLabel::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { + LabelIdx lbIdx = mirBuilder.GetOrCreateMIRLabel(labelName); + BaseNode *mirNode = mirBuilder.GetCurrentFuncCodeMp()->New(static_cast(lbIdx)); + mirNode->SetPrimType(PTY_ptr); + return mirNode; +} + // ---------- FEIRExprIAddrof ---------- std::unique_ptr FEIRExprIAddrof::CloneImpl() const { return std::make_unique(ptrType->Clone(), fieldID, subExpr->Clone()); @@ -2347,7 +2394,7 @@ BaseNode *FEIRExprIAddrof::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { // ---------- FEIRExprAddrofVar ---------- std::unique_ptr FEIRExprAddrofVar::CloneImpl() const { - std::unique_ptr expr = std::make_unique(varSrc->Clone()); + UniqueFEIRExpr expr = std::make_unique(varSrc->Clone()); expr->SetFieldID(fieldID); return expr; } @@ -2409,9 +2456,13 @@ BaseNode *FEIRExprAddrofArray::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { MIRType *ptrMIRArrayType = typeNativeArray->GenerateMIRType(false); std::unique_ptr tmpVar = std::make_unique(arrayName, typeNativeArray->Clone()); std::vector nds; - uint32 fieldID = 0; MIRSymbol *mirSymbol = tmpVar->GenerateLocalMIRSymbol(mirBuilder); - BaseNode *nodeAddrof = mirBuilder.CreateExprAddrof(fieldID, *mirSymbol); + BaseNode *nodeAddrof = nullptr; + if (ptrMIRArrayType->GetKind() == kTypeArray) { + nodeAddrof = mirBuilder.CreateExprAddrof(0, *mirSymbol); + } else { + nodeAddrof = mirBuilder.CreateDread(*mirSymbol, PTY_ptr); + } nds.push_back(nodeAddrof); for (auto &e : exprIndexs) { BaseNode *no = e->GenMIRNode(mirBuilder); @@ -2903,7 +2954,8 @@ void FEIRExprBinary::SetExprTypeByOp() { void FEIRExprBinary::SetExprTypeByOpNormal() { PrimType primTypeOpnd0 = opnd0->GetPrimType(); PrimType primTypeOpnd1 = opnd1->GetPrimType(); - if (primTypeOpnd0 == PTY_ptr || primTypeOpnd1 == PTY_ptr) { + // primTypeOpnd0 == PTY_void for addrof add + if (primTypeOpnd0 == PTY_ptr || primTypeOpnd1 == PTY_ptr || primTypeOpnd0 == PTY_void) { type->SetPrimType(PTY_ptr); return; } @@ -3354,9 +3406,9 @@ FEIRExprArrayStoreForC::FEIRExprArrayStoreForC(UniqueFEIRExpr argExprArray, std: BaseNode *FEIRExprArrayStoreForC::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { MIRType *ptrMIRArrayType = typeNative->GenerateMIRTypeAuto(); std::vector nds; - uint32 fieldID = 0; + uint32 tmpFieldID = 0; if (IsMember()) { - fieldID = static_cast(exprArray.get())->GetFieldID(); + tmpFieldID = static_cast(exprArray.get())->GetFieldID(); MIRType *ptrMIRStructType = typeNativeStruct->GenerateMIRTypeAuto(); MIRStructType* mirStructType = static_cast(ptrMIRStructType); // for no init, create the struct symbol @@ -3379,7 +3431,7 @@ BaseNode *FEIRExprArrayStoreForC::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { if (mirSymbol->GetKonst() == nullptr && exprArray->GetKind() == kExprAddrofVar) { mirSymbol->SetKonst(static_cast(exprArray.get())->GetVarValue()); } - nodeAddrof = mirBuilder.CreateExprAddrof(fieldID, *mirSymbol); + nodeAddrof = mirBuilder.CreateExprAddrof(tmpFieldID, *mirSymbol); } } nds.push_back(nodeAddrof); @@ -3391,26 +3443,33 @@ BaseNode *FEIRExprArrayStoreForC::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { if (isAddrOf) { return arrayExpr; } - UniqueFEIRType typeElem = - std::make_unique(*static_cast(ptrMIRArrayType)->GetElemType()); - MIRType *mirElemType = typeElem->GenerateMIRType(true); + MIRType *mirElemType = elemType->GenerateMIRTypeAuto(); + if (fieldID != 0) { + CHECK_FATAL((mirElemType->GetKind() == MIRTypeKind::kTypeStruct || + mirElemType->GetKind() == MIRTypeKind::kTypeUnion), + "If fieldID is not 0, then the elemType must be a structure"); + CHECK_NULL_FATAL(fieldType); + mirElemType = fieldType->GenerateMIRTypeAuto(); + } MIRType *ptrMIRElemType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*mirElemType, PTY_ptr); - BaseNode *elemBn = mirBuilder.CreateExprIread(*mirElemType, *ptrMIRElemType, 0, arrayExpr); + BaseNode *elemBn = mirBuilder.CreateExprIread(*mirElemType, *ptrMIRElemType, fieldID, arrayExpr); return elemBn; } std::unique_ptr FEIRExprArrayStoreForC::CloneImpl() const { + std::unique_ptr expr; if (exprStruct != nullptr) { - auto feirExprArrayStoreForC = std::make_unique(exprArray->Clone(), exprIndexs, + expr = std::make_unique(exprArray->Clone(), exprIndexs, typeNative->Clone(), exprStruct->Clone(), typeNativeStruct->Clone(), arrayName); - feirExprArrayStoreForC->SetIndexsExprs(exprIndexs); - return feirExprArrayStoreForC; } else { - auto feirExprArrayStoreForC = std::make_unique(exprArray->Clone(), exprIndexs, - typeNative->Clone(), arrayName); - feirExprArrayStoreForC->SetIndexsExprs(exprIndexs); - return feirExprArrayStoreForC; + expr = std::make_unique(exprArray->Clone(), exprIndexs, typeNative->Clone(), arrayName); } + expr->SetIndexsExprs(exprIndexs); + expr->SetFieldID(fieldID); + if (fieldType != nullptr) { + expr->SetFieldType(fieldType->Clone()); + } + return expr; } PrimType FEIRExprArrayStoreForC::GetPrimTypeImpl() const { @@ -3418,6 +3477,8 @@ PrimType FEIRExprArrayStoreForC::GetPrimTypeImpl() const { MIRType *ptrMIRArrayType = typeNative->GenerateMIRTypeAuto(); if (isAddrOf) { return PTY_ptr; + } else if (fieldType != nullptr) { + return fieldType->GetPrimType(); } else { return static_cast(ptrMIRArrayType)->GetElemType()->GetPrimType(); } @@ -3427,6 +3488,8 @@ FEIRType *FEIRExprArrayStoreForC::GetTypeImpl() const { CHECK_NULL_FATAL(typeNative); if (isAddrOf) { return ptrType.get(); + } else if (fieldType != nullptr) { + return fieldType.get(); } else { return elemType.get(); } diff --git a/src/mplfe/common/src/feir_type.cpp b/src/mplfe/common/src/feir_type.cpp index 2726357ec381a7f5fb74ffc4e0b229e70bf9cbeb..804d7e1befbf48d8c5d61c508004596c49564079 100644 --- a/src/mplfe/common/src/feir_type.cpp +++ b/src/mplfe/common/src/feir_type.cpp @@ -474,9 +474,6 @@ std::unique_ptr FEIRTypeNative::CloneImpl() const { } 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; } diff --git a/src/mplfe/common/src/feir_var_name.cpp b/src/mplfe/common/src/feir_var_name.cpp index 9b2b8e8683ecc2dd20fa694b11b9fc48e7298af9..f5c232811fdf8808b99695bfff4c8be32d20c056 100644 --- a/src/mplfe/common/src/feir_var_name.cpp +++ b/src/mplfe/common/src/feir_var_name.cpp @@ -39,6 +39,9 @@ std::string FEIRVarName::GetNameRawImpl() const { std::unique_ptr FEIRVarName::CloneImpl() const { std::unique_ptr var = std::make_unique(nameIdx, type->Clone(), withType); var->SetGlobal(isGlobal); + GenericAttrs attrs = genAttrs; + var->SetAttrs(attrs); + var->SetConst(mirConst); return var; }