diff --git a/src/mapleall/maple_be/include/be/becommon.h b/src/mapleall/maple_be/include/be/becommon.h index ccfd4c59a4d0bafc7659f320e6292dce23caaa77..83e5cfff1bacd5b9c1699980effc156ff215f11c 100644 --- a/src/mapleall/maple_be/include/be/becommon.h +++ b/src/mapleall/maple_be/include/be/becommon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -125,7 +125,7 @@ class BECommon { return LOWERED_PTR_TYPE; } - /* update typeSizeTable and tableAlignTable when new type is created */ + /* update typeSizeTable and typeAlignTable when new type is created */ void UpdateTypeTable(MIRType &ty) { if (!TyIsInSizeAlignTable(ty)) { AddAndComputeSizeAlign(ty); @@ -166,26 +166,32 @@ class BECommon { void AddTypeSizeAndAlign(const TyIdx tyIdx, uint64 value) { if (typeSizeTable.size() == tyIdx) { typeSizeTable.emplace_back(value); - tableAlignTable.emplace_back(value); + typeAlignTable.emplace_back(value); } else { CHECK_FATAL(typeSizeTable.size() > tyIdx, "there are some types haven't set type size and align, %d"); } } uint8 GetTypeAlign(uint32 idx) const { - return tableAlignTable.at(idx); + return typeAlignTable.at(idx); } uint32 GetSizeOfTypeAlignTable() const { - return tableAlignTable.size(); + return typeAlignTable.size(); } bool IsEmptyOfTypeAlignTable() const { - return tableAlignTable.empty(); + return typeAlignTable.empty(); } void SetTypeAlign(uint32 idx, uint8 value) { - tableAlignTable.at(idx) = value; + typeAlignTable.at(idx) = value; } void AddTypeAlign(uint8 value) { - tableAlignTable.emplace_back(value); + typeAlignTable.emplace_back(value); + } + bool GetHasFlexibleArray(uint32 idx) const { + return typeAlignTable.at(idx); + } + void SetHasFlexibleArray(uint32 idx, bool value) { + typeAlignTable.at(idx) = value; } FieldID GetStructFieldCount(uint32 idx) const { @@ -211,7 +217,8 @@ class BECommon { MIRModule &mirModule; MapleVector typeSizeTable; /* index is TyIdx */ - MapleVector tableAlignTable; /* index is TyIdx */ + MapleVector typeAlignTable; /* index is TyIdx */ + MapleVector typeHasFlexibleArray; /* struct with flexible array */ /* * gives number of fields inside * each struct inclusive of nested structs, for speeding up diff --git a/src/mapleall/maple_be/include/be/common_utils.h b/src/mapleall/maple_be/include/be/common_utils.h index f5492755517fc1837c45896b1ad0c549ce12e935..d96503f4eb20eb635e153676d62fd4ffb2bc3470 100644 --- a/src/mapleall/maple_be/include/be/common_utils.h +++ b/src/mapleall/maple_be/include/be/common_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -53,6 +53,9 @@ constexpr uint32 k4BitShift = 2; /* 4 is 1 << 2; */ constexpr uint32 k8BitShift = 3; /* 8 is 1 << 3; */ constexpr uint32 k16BitShift = 4; /* 16 is 1 << 4 */ +constexpr uint32 k4ByteFloatSize = 4; +constexpr uint32 k8ByteDoubleSize = 8; + /* Storage location of operands in one insn */ constexpr int32 kInsnFirstOpnd = 0; constexpr int32 kInsnSecondOpnd = 1; diff --git a/src/mapleall/maple_be/include/cg/emit.h b/src/mapleall/maple_be/include/cg/emit.h index b00d8274f94329ff8660e44a141fd967dccf6fc9..6b0540b44858cfa39b594d0f0555bfd5ff0a4754 100644 --- a/src/mapleall/maple_be/include/cg/emit.h +++ b/src/mapleall/maple_be/include/cg/emit.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -261,6 +261,8 @@ class Emitter { Emitter(CG &cg, const std::string &fileName) : cg(&cg), rangeIdx2PrefixStr(cg.GetMIRModule()->GetMPAllocator().Adapter()), + arraySize(0), + isFlexibleArray(false), hugeSoTargets(cg.GetMIRModule()->GetMPAllocator().Adapter()) { outStream.open(fileName, std::ios::trunc); MIRModule &mirModule = *cg.GetMIRModule(); @@ -282,6 +284,8 @@ class Emitter { const AsmInfo *asmInfo; std::ofstream outStream; MemPool *memPool; + uint16 arraySize; + bool isFlexibleArray; #if 1/* REQUIRE TO SEPERATE TARGAARCH64 TARGARM32 */ /* Following code is under TARGAARCH64 condition */ uint64 javaInsnCount = 0; diff --git a/src/mapleall/maple_be/src/be/becommon.cpp b/src/mapleall/maple_be/src/be/becommon.cpp index 29c08e359c29b75f8948cb4cc0ff05f03139fa7f..7514e94f1b5484e68ac2c1f743a806d9f49f6165 100644 --- a/src/mapleall/maple_be/src/be/becommon.cpp +++ b/src/mapleall/maple_be/src/be/becommon.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -26,8 +26,9 @@ using namespace maple; BECommon::BECommon(MIRModule &mod) : mirModule(mod), typeSizeTable(GlobalTables::GetTypeTable().GetTypeTable().size(), 0, mirModule.GetMPAllocator().Adapter()), - tableAlignTable(GlobalTables::GetTypeTable().GetTypeTable().size(), static_cast(mirModule.IsCModule()), + typeAlignTable(GlobalTables::GetTypeTable().GetTypeTable().size(), static_cast(mirModule.IsCModule()), mirModule.GetMPAllocator().Adapter()), + typeHasFlexibleArray(GlobalTables::GetTypeTable().GetTypeTable().size(), 0, mirModule.GetMPAllocator().Adapter()), structFieldCountTable(GlobalTables::GetTypeTable().GetTypeTable().size(), 0, mirModule.GetMPAllocator().Adapter()), jClassLayoutTable(mirModule.GetMPAllocator().Adapter()) { @@ -154,6 +155,15 @@ void BECommon::ComputeStructTypeSizesAligns(MIRType &ty, const TyIdx &tyIdx) { allocedSize = std::max(allocedSize, static_cast(fieldTypeSize)); } SetTypeAlign(tyIdx, std::max(GetTypeAlign(tyIdx), fieldAlign)); + /* C99 + * Last struct element of a struct with more than one member + * is a flexible array if it is an array of size 0. + */ + if ((j != 0) && ((j+1) == fields.size()) && + (fieldType->GetKind() == kTypeArray) && + (GetTypeSize(fieldTyIdx.GetIdx()) == 0)) { + SetHasFlexibleArray(tyIdx.GetIdx(), true); + } } SetTypeSize(tyIdx, RoundUp(allocedSize, GetTypeAlign(tyIdx.GetIdx()))); } @@ -579,7 +589,7 @@ std::pair BECommon::GetFieldOffset(MIRStructType &structType, Fiel } bool BECommon::TyIsInSizeAlignTable(const MIRType &ty) const { - if (typeSizeTable.size() != tableAlignTable.size()) { + if (typeSizeTable.size() != typeAlignTable.size()) { return false; } return ty.GetTypeIndex() < typeSizeTable.size(); @@ -587,7 +597,7 @@ bool BECommon::TyIsInSizeAlignTable(const MIRType &ty) const { void BECommon::AddAndComputeSizeAlign(MIRType &ty) { CHECK_FATAL(ty.GetTypeIndex() == typeSizeTable.size(), "make sure the ty idx is exactly the table size"); - tableAlignTable.emplace_back(mirModule.IsCModule()); + typeAlignTable.emplace_back(mirModule.IsCModule()); typeSizeTable.emplace_back(0); ComputeTypeSizesAligns(ty); } diff --git a/src/mapleall/maple_be/src/cg/emit.cpp b/src/mapleall/maple_be/src/cg/emit.cpp index 8d63b169f254f2fcbad6d609044bd6f23fae5e9b..c9134b6735035d04cfb6244bbef8c3f3fcc9e39e 100644 --- a/src/mapleall/maple_be/src/cg/emit.cpp +++ b/src/mapleall/maple_be/src/cg/emit.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -237,15 +237,6 @@ void Emitter::EmitAsmLabel(const MIRSymbol &mirSymbol, AsmLabel label) { if (Globals::GetInstance()->GetBECommon()->IsEmptyOfTypeAlignTable()) { ASSERT(false, "container empty check"); } -#if TARGARM32 || TARGAARCH64 - std::string align = std::to_string( - static_cast(log2(Globals::GetInstance()->GetBECommon()->GetTypeAlign(mirType->GetTypeIndex())))); -#else - std::string align = std::to_string( - static_cast(log2(Globals::GetInstance()->GetBECommon()->GetTypeAlign(mirType->GetTypeIndex())))); -#endif - std::string size = std::to_string( - Globals::GetInstance()->GetBECommon()->GetTypeSize(mirType->GetTypeIndex())); switch (label) { case kAsmGlbl: { Emit(asmInfo->GetGlobal()); @@ -272,12 +263,20 @@ void Emitter::EmitAsmLabel(const MIRSymbol &mirSymbol, AsmLabel label) { return; } case kAsmComm: { + std::string size; + if (isFlexibleArray) { + size = std::to_string(Globals::GetInstance()->GetBECommon()->GetTypeSize(mirType->GetTypeIndex()) + arraySize); + } else { + size = std::to_string(Globals::GetInstance()->GetBECommon()->GetTypeSize(mirType->GetTypeIndex())); + } Emit(asmInfo->GetComm()); Emit(symName); Emit(", "); Emit(size); Emit(", "); #if PECOFF + std::string align = std::to_string( + static_cast(log2(Globals::GetInstance()->GetBECommon()->GetTypeAlign(mirType->GetTypeIndex())))); emit(align); #else /* ELF */ /* output align, symbol name begin with "classInitProtectRegion" align is 4096 */ @@ -291,6 +290,8 @@ void Emitter::EmitAsmLabel(const MIRSymbol &mirSymbol, AsmLabel label) { return; } case kAsmAlign: { + std::string align = std::to_string( + static_cast(log2(Globals::GetInstance()->GetBECommon()->GetTypeAlign(mirType->GetTypeIndex())))); Emit(asmInfo->GetAlign()); Emit(align); Emit("\n"); @@ -302,6 +303,12 @@ void Emitter::EmitAsmLabel(const MIRSymbol &mirSymbol, AsmLabel label) { return; } case kAsmSize: { + std::string size; + if (isFlexibleArray) { + size = std::to_string(Globals::GetInstance()->GetBECommon()->GetTypeSize(mirType->GetTypeIndex()) + arraySize); + } else { + size = std::to_string(Globals::GetInstance()->GetBECommon()->GetTypeSize(mirType->GetTypeIndex())); + } Emit(asmInfo->GetSize()); Emit(symName); Emit(", "); @@ -390,6 +397,9 @@ void Emitter::EmitStrConstant(const MIRStrConst &mirStrConst) { * convert all \s to \\s in std::string for storing in .string */ const char *str = GlobalTables::GetUStrTable().GetStringFromStrIdx(mirStrConst.GetValue()).c_str(); + if (isFlexibleArray) { + arraySize += strlen(str) + k1ByteSize; + } constexpr int bufSize = 6; while (*str) { char buf[bufSize]; @@ -464,18 +474,27 @@ void Emitter::EmitScalarConstant(MIRConst &mirConst, bool newLine, bool flag32) EmitAsmLabel(asmName); } Emit(intCt.GetValue()); + if (isFlexibleArray) { + arraySize += (sizeInBits / kBitsPerByte); + } break; } case kConstFloatConst: { MIRFloatConst &floatCt = static_cast(mirConst); EmitAsmLabel(asmName); Emit(std::to_string(floatCt.GetIntValue())); + if (isFlexibleArray) { + arraySize += k4ByteFloatSize; + } break; } case kConstDoubleConst: { MIRDoubleConst &doubleCt = static_cast(mirConst); EmitAsmLabel(asmName); Emit(std::to_string(doubleCt.GetIntValue())); + if (isFlexibleArray) { + arraySize += k8ByteDoubleSize; + } break; } case kConstStrConst: { @@ -1380,6 +1399,10 @@ void Emitter::EmitStructConstant(MIRConst &mirConst) { uint32 size = Globals::GetInstance()->GetBECommon()->GetTypeSize(structType.GetTypeIndex()); uint32 fieldIdx = 1; for (uint32 i = 0; i < num; ++i) { + if (((i + 1) == num) && cg->GetMIRModule()->GetSrcLang() == kSrcLangC) { + isFlexibleArray = Globals::GetInstance()->GetBECommon()->GetHasFlexibleArray(mirType.GetTypeIndex().GetIdx()); + arraySize = 0; + } MIRConst *elemConst = structCt.GetAggConstElement(fieldIdx); MIRType &elemType = *structType.GetElemType(i); MIRType *nextElemType = nullptr;