mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
!9089 delete unuse code of MIRStructType
Merge pull request !9089 from huangyan/delete_struct_hy
This commit is contained in:
commit
6cd45ab9ab
@ -43,10 +43,6 @@ public:
|
||||
|
||||
void ComputeTypeSizesAligns(MIRType &type, uint8 align = 0);
|
||||
|
||||
std::pair<int32, int32> GetFieldOffset(MIRStructType &structType, FieldID fieldID);
|
||||
|
||||
bool IsRefField(MIRStructType &structType, FieldID fieldID) const;
|
||||
|
||||
void AddNewTypeAfterBecommon(uint32 oldTypeTableSize, uint32 newTypeTableSize);
|
||||
|
||||
bool HasFuncReturnType(MIRFunction &func) const
|
||||
@ -86,13 +82,6 @@ public:
|
||||
|
||||
uint32 GetFieldIdxIncrement(const MIRType &ty) const
|
||||
{
|
||||
if (ty.GetKind() == kTypeClass) {
|
||||
/* number of fields + 2 */
|
||||
return static_cast<const MIRClassType &>(ty).GetFieldsSize() + 2;
|
||||
} else if (ty.GetKind() == kTypeStruct) {
|
||||
/* number of fields + 1 */
|
||||
return static_cast<const MIRStructType &>(ty).GetFieldsSize() + 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -182,7 +171,6 @@ public:
|
||||
private:
|
||||
bool TyIsInSizeAlignTable(const MIRType &) const;
|
||||
void AddAndComputeSizeAlign(MIRType &);
|
||||
void ComputeStructTypeSizesAligns(MIRType &ty, const TyIdx &tyIdx);
|
||||
|
||||
MIRModule &mirModule;
|
||||
MapleVector<uint64> typeSizeTable; /* index is TyIdx */
|
||||
|
@ -92,7 +92,8 @@ public:
|
||||
if (iread.GetPrimType() == PTY_u1) {
|
||||
iread.SetPrimType(PTY_u8);
|
||||
}
|
||||
return (iread.GetFieldID() == 0 ? &iread : LowerIreadBitfield(iread));
|
||||
CHECK_FATAL(iread.GetFieldID() == 0, "fieldID must be 0");
|
||||
return &iread;
|
||||
}
|
||||
|
||||
BaseNode *LowerCastExpr(BaseNode &expr);
|
||||
@ -107,8 +108,6 @@ public:
|
||||
|
||||
void LowerRegassign(RegassignNode ®Assign, BlockNode &block);
|
||||
|
||||
StmtNode *LowerIntrinsicopDassign(const DassignNode &dassign, IntrinsicopNode &intrinsic, BlockNode &block);
|
||||
|
||||
BaseNode *LowerAddrof(AddrofNode &addrof) const
|
||||
{
|
||||
return &addrof;
|
||||
@ -126,11 +125,6 @@ public:
|
||||
* To be able to handle them in a unified manner, we lower intrinsiccall to Intrinsicsicop.
|
||||
*/
|
||||
BlockNode *LowerIntrinsiccallToIntrinsicop(StmtNode &stmt);
|
||||
bool LowerStructReturnInRegs(BlockNode &newBlk, StmtNode &stmt, const MIRSymbol &retSym);
|
||||
void LowerStructReturnInGpRegs(BlockNode &newBlk, const StmtNode &stmt, const MIRSymbol &symbol);
|
||||
void LowerStructReturnInFpRegs(BlockNode &newBlk, const StmtNode &stmt, const MIRSymbol &symbol, PrimType primType,
|
||||
size_t elemNum);
|
||||
bool LowerStructReturn(BlockNode &newBlk, StmtNode &stmt, bool &lvar);
|
||||
|
||||
void LowerStmt(StmtNode &stmt, BlockNode &block);
|
||||
|
||||
@ -156,10 +150,6 @@ public:
|
||||
BaseNode *baseAddr, BaseNode *rhs, BlockNode *block);
|
||||
BaseNode *ReadBitField(const std::pair<int32, int32> &byteBitOffsets, const MIRBitFieldType *fieldType,
|
||||
BaseNode *baseAddr);
|
||||
BaseNode *LowerDreadBitfield(DreadNode &dread);
|
||||
BaseNode *LowerIreadBitfield(IreadNode &iread);
|
||||
StmtNode *LowerDassignBitfield(DassignNode &dassign, BlockNode &block);
|
||||
StmtNode *LowerIassignBitfield(IassignNode &iassign, BlockNode &block);
|
||||
|
||||
void LowerAsmStmt(AsmNode *asmNode, BlockNode *blk);
|
||||
|
||||
|
@ -60,8 +60,6 @@ public:
|
||||
return cyclePatternMap;
|
||||
}
|
||||
|
||||
void GenerateObjectMaps(BECommon &beCommon) override;
|
||||
|
||||
bool IsExclusiveFunc(MIRFunction &) override;
|
||||
|
||||
void EmitGCTIBLabel(GCTIBKey *key, const std::string &gcTIBName, std::vector<uint64> &bitmapWords, uint32 rcHeader);
|
||||
|
@ -89,7 +89,6 @@ public:
|
||||
void MergeReturn() override;
|
||||
void SelectDassign(DassignNode &stmt, Operand &opnd0) override;
|
||||
void SelectRegassign(RegassignNode &stmt, Operand &opnd0) override;
|
||||
MemOperand *GenFormalMemOpndWithSymbol(const MIRSymbol &sym, int64 offset);
|
||||
void SelectIassign(IassignNode &stmt) override;
|
||||
void SelectReturn(Operand *opnd0) override;
|
||||
bool DoCallerEnsureValidParm(RegOperand &destOpnd, RegOperand &srcOpnd, PrimType formalPType);
|
||||
|
@ -112,8 +112,7 @@ struct CCLocInfo {
|
||||
class LmbcFormalParamInfo {
|
||||
public:
|
||||
LmbcFormalParamInfo(PrimType pType, uint32 ofst, uint32 sz)
|
||||
: type(nullptr),
|
||||
primType(pType),
|
||||
: primType(pType),
|
||||
offset(ofst),
|
||||
onStackOffset(0),
|
||||
size(sz),
|
||||
@ -130,14 +129,6 @@ public:
|
||||
|
||||
~LmbcFormalParamInfo() = default;
|
||||
|
||||
MIRStructType *GetType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
void SetType(MIRStructType *ty)
|
||||
{
|
||||
type = ty;
|
||||
}
|
||||
PrimType GetPrimType() const
|
||||
{
|
||||
return primType;
|
||||
@ -240,7 +231,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
MIRStructType *type;
|
||||
PrimType primType;
|
||||
uint32 offset;
|
||||
uint32 onStackOffset; /* stack location if isOnStack */
|
||||
|
@ -212,9 +212,6 @@ public:
|
||||
|
||||
virtual bool IsExclusiveFunc(MIRFunction &mirFunc) = 0;
|
||||
|
||||
/* NOTE: Consider making be_common a field of CG. */
|
||||
virtual void GenerateObjectMaps(BECommon &beCommon) = 0;
|
||||
|
||||
/* Used for GCTIB pattern merging */
|
||||
virtual std::string FindGCTIBPatternName(const std::string &name) const = 0;
|
||||
|
||||
|
@ -292,16 +292,6 @@ public:
|
||||
asmEmitterEnable = flag;
|
||||
}
|
||||
|
||||
bool IsGenerateObjectMap() const
|
||||
{
|
||||
return generateObjectMap;
|
||||
}
|
||||
|
||||
void SetGenerateObjectMap(bool flag)
|
||||
{
|
||||
generateObjectMap = flag;
|
||||
}
|
||||
|
||||
void SetParserOption(uint32 option)
|
||||
{
|
||||
parserOption |= option;
|
||||
@ -888,7 +878,6 @@ private:
|
||||
|
||||
bool runCGFlag = true;
|
||||
bool asmEmitterEnable = false;
|
||||
bool generateObjectMap = true;
|
||||
uint32 parserOption = 0;
|
||||
int32 optimizeLevel = 0;
|
||||
|
||||
|
@ -30,7 +30,6 @@ extern maplecl::Option<bool> cg;
|
||||
extern maplecl::Option<bool> generalRegOnly;
|
||||
extern maplecl::Option<bool> lazyBinding;
|
||||
extern maplecl::Option<bool> hotFix;
|
||||
extern maplecl::Option<bool> objmap;
|
||||
extern maplecl::Option<bool> yieldpoint;
|
||||
extern maplecl::Option<bool> localRc;
|
||||
extern maplecl::Option<bool> debug;
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "cfi.h"
|
||||
#include "cg_cfg.h"
|
||||
#include "cg_irbuilder.h"
|
||||
#include "call_conv.h"
|
||||
/* MapleIR headers. */
|
||||
#include "mir_function.h"
|
||||
|
||||
@ -1175,16 +1174,6 @@ protected:
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* See if the symbol is a structure parameter that requires a copy. */
|
||||
bool IsParamStructCopy(const MIRSymbol &symbol) const
|
||||
{
|
||||
auto *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(symbol.GetTyIdx());
|
||||
if (symbol.GetStorageClass() == kScFormal && IsParamStructCopyToMemory(*mirType)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
PrimType GetPrimTypeFromSize(uint32 byteSize, PrimType defaultType) const
|
||||
{
|
||||
constexpr uint32 oneByte = 1;
|
||||
|
@ -223,8 +223,6 @@ public:
|
||||
void EmitMethodDeclaringClass(const MIRSymbol &mirSymbol, const std::string §ionName);
|
||||
void MarkVtabOrItabEndFlag(const std::vector<MIRSymbol *> &mirSymbolVec);
|
||||
void EmitArrayConstant(MIRConst &mirConst);
|
||||
void EmitStructConstant(MIRConst &mirConst);
|
||||
void EmitStructConstant(MIRConst &mirConst, uint32 &subStructFieldCounts);
|
||||
void EmitLocalVariable(const CGFunc &cgFunc);
|
||||
void EmitUninitializedSymbolsWithPrefixSection(const MIRSymbol &symbol, const std::string §ionName);
|
||||
void EmitGlobalVariable();
|
||||
|
@ -84,9 +84,6 @@ public:
|
||||
|
||||
bool IsExclusiveFunc(MIRFunction &mirFunc) override;
|
||||
|
||||
/* NOTE: Consider making be_common a field of CG. */
|
||||
void GenerateObjectMaps(BECommon &beCommon) override;
|
||||
|
||||
void DoNothing()
|
||||
{
|
||||
(void)ehExclusiveNameVec;
|
||||
|
@ -46,9 +46,6 @@ public:
|
||||
uint64 GetSymbolSize(maple::TyIdx typeIndex);
|
||||
void EmitLocalVariable(maplebe::CGFunc &cgFunc);
|
||||
void EmitGlobalVariable(maplebe::CG &cg);
|
||||
uint64 EmitStructure(maple::MIRConst &mirConst, maplebe::CG &cg, bool belongsToDataSec = true);
|
||||
uint64 EmitStructure(maple::MIRConst &mirConst, maplebe::CG &cg, uint32 &subStructFieldCounts,
|
||||
bool belongsToDataSec = true);
|
||||
uint64 EmitVector(maple::MIRConst &mirConst, bool belongsToDataSec = true);
|
||||
uint64 EmitArray(maple::MIRConst &mirConst, maplebe::CG &cg, bool belongsToDataSec = true);
|
||||
void EmitAddrofElement(MIRConst &mirConst, bool belongsToDataSec);
|
||||
|
@ -48,7 +48,6 @@ class MIRBuilder; // currently we just delegate MIRBuilder
|
||||
class MIRModule;
|
||||
class MIRFunction;
|
||||
class MIRType;
|
||||
class MIRStructType;
|
||||
class MIRArrayType;
|
||||
class MIRFuncType;
|
||||
class MIRConst;
|
||||
@ -70,7 +69,6 @@ using Function = MIRFunction;
|
||||
|
||||
// Note: Type is base class of all other Types
|
||||
using Type = MIRType; // base class of all Types
|
||||
using StructType = MIRStructType; // |__ StructType
|
||||
using ArrayType = MIRArrayType;
|
||||
using Const = MIRConst;
|
||||
using StructConst = MIRAggConst;
|
||||
@ -270,14 +268,6 @@ public:
|
||||
|
||||
bool IsHeapPointerType(Type *mirType) const;
|
||||
|
||||
/* using StructTypeBuilder interface for StructType creation
|
||||
auto structType = CreateStructType("mystruct")
|
||||
.Field("field1", i32Type)
|
||||
.Field("field2", i64Type)
|
||||
.Done();
|
||||
*/
|
||||
Type *GetStructType(const String &name); // query for existing struct type
|
||||
|
||||
// for function pointer
|
||||
Type *CreateFuncType(std::vector<Type *> params, Type *retType, bool isVarg);
|
||||
|
||||
@ -331,14 +321,6 @@ public:
|
||||
Const &CreateDoubleConst(double val);
|
||||
Const *GetConstFromExpr(const Expr &expr);
|
||||
|
||||
// In MIR, the const for struct & array are the same. But we separate it here.
|
||||
/* using StructConstBuilder interface for StructConst creation:
|
||||
auto structConst = CreateStructConst(structType)
|
||||
.Field(1, CreateIntConst(i32Type, 0))
|
||||
.Filed(2, CreateIntConst(i64Type, 0))
|
||||
.Done();
|
||||
*/
|
||||
|
||||
/* using ArrayConstBuilder interface for ArrayConst creation:
|
||||
Note: the elements should be added consequentially, and match the dim size.
|
||||
auto arrayConst = CreateArrayConst(arrayType)
|
||||
@ -422,7 +404,6 @@ public:
|
||||
return Dread(*var);
|
||||
}
|
||||
|
||||
Expr DreadWithField(Var &var, FieldId id);
|
||||
Expr IntrinsicOp(IntrinsicId id, Type *type, Args &args_);
|
||||
Expr Iread(Type *type, Expr addr, Type *baseType, FieldId fieldId = 0);
|
||||
PregIdx CreatePreg(Type *mtype);
|
||||
@ -502,61 +483,6 @@ public:
|
||||
return SwitchBuilder(*this, type, cond, defaultBB);
|
||||
}
|
||||
|
||||
class StructTypeBuilder {
|
||||
public:
|
||||
StructTypeBuilder(LMIRBuilder &builder_, const String &name_) : builder(builder_), name(name_) {}
|
||||
|
||||
StructTypeBuilder &Field(std::string_view fieldName, Type *fieldType)
|
||||
{
|
||||
// field type attribute?
|
||||
fields.push_back(std::make_pair(fieldName, fieldType));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Type *Done()
|
||||
{
|
||||
return builder.CreateStructTypeInternal(name, fields);
|
||||
}
|
||||
|
||||
private:
|
||||
LMIRBuilder &builder;
|
||||
const String &name;
|
||||
std::vector<std::pair<std::string_view, Type *>> fields;
|
||||
};
|
||||
|
||||
StructTypeBuilder CreateStructType(const String &name)
|
||||
{
|
||||
return StructTypeBuilder(*this, name);
|
||||
}
|
||||
|
||||
class StructConstBuilder {
|
||||
public:
|
||||
StructConstBuilder(LMIRBuilder &builder_, StructType *type_) : builder(builder_)
|
||||
{
|
||||
structConst = &builder_.CreateStructConstInternal(type_);
|
||||
}
|
||||
|
||||
StructConstBuilder &Field(FieldId fieldId, Const &field)
|
||||
{
|
||||
builder.AddConstItemInternal(*structConst, fieldId, field);
|
||||
return *this;
|
||||
}
|
||||
|
||||
StructConst &Done()
|
||||
{
|
||||
return *structConst;
|
||||
}
|
||||
|
||||
private:
|
||||
LMIRBuilder &builder;
|
||||
StructConst *structConst;
|
||||
};
|
||||
|
||||
StructConstBuilder CreateStructConst(StructType *type)
|
||||
{
|
||||
return StructConstBuilder(*this, type);
|
||||
}
|
||||
|
||||
class ArrayConstBuilder {
|
||||
public:
|
||||
ArrayConstBuilder(LMIRBuilder &builder_, ArrayType *type_) : builder(builder_)
|
||||
@ -699,8 +625,6 @@ public:
|
||||
|
||||
private:
|
||||
Stmt &CreateSwitchInternal(Type *type, Expr cond, BB &defaultBB, std::vector<std::pair<int64_t, BB *>> &cases);
|
||||
Type *CreateStructTypeInternal(const String &name, std::vector<std::pair<std::string_view, Type *>> &fields);
|
||||
StructConst &CreateStructConstInternal(StructType *type);
|
||||
void AddConstItemInternal(StructConst &structConst, FieldId fieldId, Const &field);
|
||||
void AddConstItemInternal(ArrayConst &structConst, Const &element);
|
||||
ArrayConst &CreateArrayConstInternal(ArrayType *type);
|
||||
|
@ -53,96 +53,6 @@ void BECommon::AddNewTypeAfterBecommon(uint32 oldTypeTableSize, uint32 newTypeTa
|
||||
}
|
||||
}
|
||||
|
||||
void BECommon::ComputeStructTypeSizesAligns(MIRType &ty, const TyIdx &tyIdx)
|
||||
{
|
||||
auto &structType = static_cast<MIRStructType &>(ty);
|
||||
const FieldVector &fields = structType.GetFields();
|
||||
uint64 allocedSize = 0;
|
||||
uint64 allocedSizeInBits = 0;
|
||||
SetStructFieldCount(structType.GetTypeIndex(), fields.size());
|
||||
if (fields.size() == 0) {
|
||||
if (structType.IsCPlusPlus()) {
|
||||
SetTypeSize(tyIdx.GetIdx(), 1); /* empty struct in C++ has size 1 */
|
||||
SetTypeAlign(tyIdx.GetIdx(), 1);
|
||||
} else {
|
||||
SetTypeSize(tyIdx.GetIdx(), 0);
|
||||
SetTypeAlign(tyIdx.GetIdx(), k8ByteSize);
|
||||
}
|
||||
return;
|
||||
}
|
||||
auto structAttr = structType.GetTypeAttrs();
|
||||
auto structPack = static_cast<uint8>(structAttr.GetPack());
|
||||
for (uint32 j = 0; j < fields.size(); ++j) {
|
||||
TyIdx fieldTyIdx = fields[j].second.first;
|
||||
auto fieldAttr = fields[j].second.second;
|
||||
MIRType *fieldType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldTyIdx);
|
||||
uint32 fieldTypeSize = GetTypeSize(fieldTyIdx);
|
||||
if (fieldTypeSize == 0) {
|
||||
ComputeTypeSizesAligns(*fieldType);
|
||||
fieldTypeSize = GetTypeSize(fieldTyIdx);
|
||||
}
|
||||
uint64 fieldSizeBits = fieldTypeSize * kBitsPerByte;
|
||||
auto attrAlign = static_cast<uint8>(fieldAttr.GetAlign());
|
||||
auto originAlign = std::max(attrAlign, GetTypeAlign(fieldTyIdx));
|
||||
uint8 fieldAlign = fieldAttr.IsPacked() ? 1 : std::min(originAlign, structPack);
|
||||
uint64 fieldAlignBits = fieldAlign * kBitsPerByte;
|
||||
CHECK_FATAL(fieldAlign != 0, "expect fieldAlign not equal 0");
|
||||
MIRStructType *subStructType = fieldType->EmbeddedStructType();
|
||||
if (subStructType != nullptr) {
|
||||
AppendStructFieldCount(structType.GetTypeIndex(), GetStructFieldCount(subStructType->GetTypeIndex()));
|
||||
}
|
||||
if (structType.GetKind() != kTypeUnion) {
|
||||
if (fieldType->GetKind() == kTypeBitField) {
|
||||
uint32 fieldSize = static_cast<MIRBitFieldType *>(fieldType)->GetFieldSize();
|
||||
/* is this field is crossing the align boundary of its base type? */
|
||||
if ((!structAttr.IsPacked() &&
|
||||
((allocedSizeInBits / fieldSizeBits) != ((allocedSizeInBits + fieldSize - 1u) / fieldSizeBits))) ||
|
||||
fieldSize == 0) {
|
||||
allocedSizeInBits = RoundUp(allocedSizeInBits, fieldSizeBits);
|
||||
}
|
||||
/* allocate the bitfield */
|
||||
allocedSizeInBits += fieldSize;
|
||||
allocedSize = std::max(allocedSize, RoundUp(allocedSizeInBits, fieldAlignBits) / kBitsPerByte);
|
||||
} else {
|
||||
bool leftoverbits = false;
|
||||
|
||||
if (allocedSizeInBits == allocedSize * kBitsPerByte) {
|
||||
allocedSize = RoundUp(allocedSize, fieldAlign);
|
||||
} else {
|
||||
/* still some leftover bits on allocated words, we calculate things based on bits then. */
|
||||
if (allocedSizeInBits / fieldAlignBits !=
|
||||
(allocedSizeInBits + fieldSizeBits - 1) / fieldAlignBits) {
|
||||
/* the field is crossing the align boundary of its base type */
|
||||
allocedSizeInBits = RoundUp(allocedSizeInBits, fieldAlignBits);
|
||||
}
|
||||
leftoverbits = true;
|
||||
}
|
||||
if (leftoverbits) {
|
||||
allocedSizeInBits += fieldSizeBits;
|
||||
allocedSize = std::max(allocedSize, RoundUp(allocedSizeInBits, fieldAlignBits) / kBitsPerByte);
|
||||
} else {
|
||||
/* pad alloced_size according to the field alignment */
|
||||
allocedSize = RoundUp(allocedSize, fieldAlign);
|
||||
allocedSize += fieldTypeSize;
|
||||
allocedSizeInBits = allocedSize * kBitsPerByte;
|
||||
}
|
||||
}
|
||||
} else { /* for unions, bitfields are treated as non-bitfields */
|
||||
allocedSize = std::max(allocedSize, static_cast<uint64>(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())));
|
||||
}
|
||||
|
||||
void BECommon::ComputeTypeSizesAligns(MIRType &ty, uint8 align)
|
||||
{
|
||||
TyIdx tyIdx = ty.GetTypeIndex();
|
||||
@ -162,16 +72,10 @@ void BECommon::ComputeTypeSizesAligns(MIRType &ty, uint8 align)
|
||||
SetTypeSize(tyIdx, GetPrimTypeSize(ty.GetPrimType()));
|
||||
SetTypeAlign(tyIdx, GetTypeSize(tyIdx));
|
||||
break;
|
||||
case kTypeUnion:
|
||||
case kTypeStruct: {
|
||||
ComputeStructTypeSizesAligns(ty, tyIdx);
|
||||
break;
|
||||
}
|
||||
case kTypeArray:
|
||||
case kTypeFArray:
|
||||
case kTypeJArray:
|
||||
case kTypeInterface:
|
||||
case kTypeClass: { /* cannot have union or bitfields */
|
||||
case kTypeInterface: { /* cannot have union or bitfields */
|
||||
CHECK_FATAL(false, "unsupported type");
|
||||
break;
|
||||
}
|
||||
@ -185,138 +89,6 @@ void BECommon::ComputeTypeSizesAligns(MIRType &ty, uint8 align)
|
||||
SetTypeAlign(tyIdx, std::max(GetTypeAlign(tyIdx), align));
|
||||
}
|
||||
|
||||
bool BECommon::IsRefField(MIRStructType &structType, FieldID fieldID) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* compute the offset of the field given by fieldID within the structure type
|
||||
* structy; it returns the answer in the pair (byteoffset, bitoffset) such that
|
||||
* if it is a bitfield, byteoffset gives the offset of the container for
|
||||
* extracting the bitfield and bitoffset is with respect to the container
|
||||
*/
|
||||
std::pair<int32, int32> BECommon::GetFieldOffset(MIRStructType &structType, FieldID fieldID)
|
||||
{
|
||||
CHECK_FATAL(fieldID <= GetStructFieldCount(structType.GetTypeIndex()), "GetFieldOFfset: fieldID too large");
|
||||
uint64 allocedSize = 0;
|
||||
uint64 allocedSizeInBits = 0;
|
||||
FieldID curFieldID = 1;
|
||||
if (fieldID == 0) {
|
||||
return std::pair<int32, int32>(0, 0);
|
||||
}
|
||||
DEBUG_ASSERT(structType.GetKind() != kTypeClass, "unsupported kTypeClass type");
|
||||
|
||||
/* process the struct fields */
|
||||
FieldVector fields = structType.GetFields();
|
||||
auto structPack = static_cast<uint8>(structType.GetTypeAttrs().GetPack());
|
||||
for (uint32 j = 0; j < fields.size(); ++j) {
|
||||
TyIdx fieldTyIdx = fields[j].second.first;
|
||||
auto fieldAttr = fields[j].second.second;
|
||||
MIRType *fieldType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldTyIdx);
|
||||
uint32 fieldTypeSize = GetTypeSize(fieldTyIdx);
|
||||
uint64 fieldSizeBits = fieldTypeSize * kBitsPerByte;
|
||||
auto originAlign = GetTypeAlign(fieldTyIdx);
|
||||
auto fieldAlign = fieldAttr.IsPacked() ? 1 : std::min(originAlign, structPack);
|
||||
uint64 fieldAlignBits = static_cast<uint64>(fieldAlign * kBitsPerByte);
|
||||
CHECK_FATAL(fieldAlign != 0, "fieldAlign should not equal 0");
|
||||
if (structType.GetKind() != kTypeUnion) {
|
||||
if (fieldType->GetKind() == kTypeBitField) {
|
||||
uint32 fieldSize = static_cast<MIRBitFieldType *>(fieldType)->GetFieldSize();
|
||||
/*
|
||||
* Is this field is crossing the align boundary of its base type? Or,
|
||||
* is field a zero-with bit field?
|
||||
* Refer to C99 standard (§6.7.2.1) :
|
||||
* > As a special case, a bit-field structure member with a width of 0 indicates that no further
|
||||
* > bit-field is to be packed into the unit in which the previous bit-field, if any, was placed.
|
||||
*
|
||||
* We know that A zero-width bit field can cause the next field to be aligned on the next container
|
||||
* boundary where the container is the same size as the underlying type of the bit field.
|
||||
*/
|
||||
CHECK_FATAL(allocedSizeInBits <= UINT64_MAX - fieldSize, "must not be zero");
|
||||
DEBUG_ASSERT(allocedSizeInBits + fieldSize >= 1, "allocedSizeInBits + fieldSize - 1u must be unsigned");
|
||||
if ((!structType.GetTypeAttrs().IsPacked() &&
|
||||
((allocedSizeInBits / fieldSizeBits) != ((allocedSizeInBits + fieldSize - 1u) / fieldSizeBits))) ||
|
||||
fieldSize == 0) {
|
||||
/*
|
||||
* the field is crossing the align boundary of its base type;
|
||||
* align alloced_size_in_bits to fieldAlign
|
||||
*/
|
||||
allocedSizeInBits = RoundUp(allocedSizeInBits, fieldSizeBits);
|
||||
}
|
||||
/* allocate the bitfield */
|
||||
if (curFieldID == fieldID) {
|
||||
return std::pair<int32, int32>((allocedSizeInBits / fieldAlignBits) * fieldAlign,
|
||||
allocedSizeInBits % fieldAlignBits);
|
||||
} else {
|
||||
++curFieldID;
|
||||
}
|
||||
allocedSizeInBits += fieldSize;
|
||||
allocedSize = std::max(allocedSize, RoundUp(allocedSizeInBits, fieldAlignBits) / kBitsPerByte);
|
||||
} else {
|
||||
bool leftOverBits = false;
|
||||
uint64 offset = 0;
|
||||
|
||||
if (allocedSizeInBits == allocedSize * k8BitSize) {
|
||||
allocedSize = RoundUp(allocedSize, fieldAlign);
|
||||
offset = allocedSize;
|
||||
} else {
|
||||
/* still some leftover bits on allocated words, we calculate things based on bits then. */
|
||||
if (allocedSizeInBits / fieldAlignBits !=
|
||||
(allocedSizeInBits + fieldSizeBits - k1BitSize) / fieldAlignBits) {
|
||||
/* the field is crossing the align boundary of its base type */
|
||||
allocedSizeInBits = RoundUp(allocedSizeInBits, fieldAlignBits);
|
||||
}
|
||||
allocedSize = RoundUp(allocedSize, fieldAlign);
|
||||
offset = static_cast<uint64>((allocedSizeInBits / fieldAlignBits) * fieldAlign);
|
||||
leftOverBits = true;
|
||||
}
|
||||
|
||||
if (curFieldID == fieldID) {
|
||||
return std::pair<int32, int32>(offset, 0);
|
||||
} else {
|
||||
MIRStructType *subStructType = fieldType->EmbeddedStructType();
|
||||
if (subStructType == nullptr) {
|
||||
++curFieldID;
|
||||
} else {
|
||||
if ((curFieldID + GetStructFieldCount(subStructType->GetTypeIndex())) < fieldID) {
|
||||
curFieldID += GetStructFieldCount(subStructType->GetTypeIndex()) + 1;
|
||||
} else {
|
||||
std::pair<int32, int32> result = GetFieldOffset(*subStructType, fieldID - curFieldID);
|
||||
return std::pair<int32, int32>(result.first + allocedSize, result.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (leftOverBits) {
|
||||
allocedSizeInBits += fieldSizeBits;
|
||||
allocedSize = std::max(allocedSize, RoundUp(allocedSizeInBits, fieldAlignBits) / kBitsPerByte);
|
||||
} else {
|
||||
allocedSize += fieldTypeSize;
|
||||
allocedSizeInBits = allocedSize * kBitsPerByte;
|
||||
}
|
||||
}
|
||||
} else { /* for unions, bitfields are treated as non-bitfields */
|
||||
if (curFieldID == fieldID) {
|
||||
return std::pair<int32, int32>(0, 0);
|
||||
} else {
|
||||
MIRStructType *subStructType = fieldType->EmbeddedStructType();
|
||||
if (subStructType == nullptr) {
|
||||
curFieldID++;
|
||||
} else {
|
||||
if ((curFieldID + GetStructFieldCount(subStructType->GetTypeIndex())) < fieldID) {
|
||||
curFieldID += GetStructFieldCount(subStructType->GetTypeIndex()) + 1;
|
||||
} else {
|
||||
return GetFieldOffset(*subStructType, fieldID - curFieldID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CHECK_FATAL(false, "GetFieldOffset() fails to find field");
|
||||
return std::pair<int32, int32>(0, 0);
|
||||
}
|
||||
|
||||
bool BECommon::TyIsInSizeAlignTable(const MIRType &ty) const
|
||||
{
|
||||
if (typeSizeTable.size() != typeAlignTable.size()) {
|
||||
@ -385,19 +157,8 @@ BaseNode *BECommon::GetAddressOfNode(const BaseNode &node)
|
||||
}
|
||||
case OP_iread: {
|
||||
const IreadNode &iNode = static_cast<const IreadNode &>(node);
|
||||
if (iNode.GetFieldID() == 0) {
|
||||
return iNode.Opnd(0);
|
||||
}
|
||||
|
||||
uint32 index = static_cast<MIRPtrType *>(GlobalTables::GetTypeTable().GetTypeTable().at(iNode.GetTyIdx()))
|
||||
->GetPointedTyIdx();
|
||||
MIRType *pointedType = GlobalTables::GetTypeTable().GetTypeTable().at(index);
|
||||
std::pair<int32, int32> byteBitOffset =
|
||||
GetFieldOffset(static_cast<MIRStructType &>(*pointedType), iNode.GetFieldID());
|
||||
return mirModule.GetMIRBuilder()->CreateExprBinary(
|
||||
OP_add, *GlobalTables::GetTypeTable().GetPrimType(GetAddressPrimType()),
|
||||
static_cast<BaseNode *>(iNode.Opnd(0)),
|
||||
mirModule.GetMIRBuilder()->CreateIntConst(byteBitOffset.first, PTY_u32));
|
||||
CHECK_FATAL(iNode.GetFieldID() == 0, "fieldId must be 0");
|
||||
return iNode.Opnd(0);
|
||||
}
|
||||
default:
|
||||
return nullptr;
|
||||
|
@ -36,30 +36,8 @@ using namespace maple;
|
||||
|
||||
BaseNode *CGLowerer::LowerIaddrof(const IreadNode &iaddrof)
|
||||
{
|
||||
if (iaddrof.GetFieldID() == 0) {
|
||||
return iaddrof.Opnd(0);
|
||||
}
|
||||
MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iaddrof.GetTyIdx());
|
||||
MIRPtrType *pointerTy = static_cast<MIRPtrType *>(type);
|
||||
CHECK_FATAL(pointerTy != nullptr, "LowerIaddrof: expect a pointer type at iaddrof node");
|
||||
MIRStructType *structTy =
|
||||
static_cast<MIRStructType *>(GlobalTables::GetTypeTable().GetTypeFromTyIdx(pointerTy->GetPointedTyIdx()));
|
||||
CHECK_FATAL(structTy != nullptr, "LowerIaddrof: non-zero fieldID for non-structure");
|
||||
int32 offset = beCommon.GetFieldOffset(*structTy, iaddrof.GetFieldID()).first;
|
||||
if (offset == 0) {
|
||||
return iaddrof.Opnd(0);
|
||||
}
|
||||
uint32 loweredPtrType = static_cast<uint32>(GetLoweredPtrType());
|
||||
MIRIntConst *offsetConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(
|
||||
offset, *GlobalTables::GetTypeTable().GetTypeTable().at(loweredPtrType));
|
||||
BaseNode *offsetNode = mirModule.CurFuncCodeMemPool()->New<ConstvalNode>(offsetConst);
|
||||
offsetNode->SetPrimType(GetLoweredPtrType());
|
||||
|
||||
BinaryNode *addNode = mirModule.CurFuncCodeMemPool()->New<BinaryNode>(OP_add);
|
||||
addNode->SetPrimType(GetLoweredPtrType());
|
||||
addNode->SetBOpnd(iaddrof.Opnd(0), 0);
|
||||
addNode->SetBOpnd(offsetNode, 1);
|
||||
return addNode;
|
||||
CHECK_FATAL(iaddrof.GetFieldID() == 0, "fieldID must be 0");
|
||||
return iaddrof.Opnd(0);
|
||||
}
|
||||
|
||||
StmtNode *CGLowerer::WriteBitField(const std::pair<int32, int32> &byteBitOffsets, const MIRBitFieldType *fieldType,
|
||||
@ -136,44 +114,6 @@ BaseNode *CGLowerer::ReadBitField(const std::pair<int32, int32> &byteBitOffsets,
|
||||
return result;
|
||||
}
|
||||
|
||||
BaseNode *CGLowerer::LowerDreadBitfield(DreadNode &dread)
|
||||
{
|
||||
DEBUG_ASSERT(mirModule.CurFunction() != nullptr, "CurFunction should not be nullptr");
|
||||
auto *symbol = mirModule.CurFunction()->GetLocalOrGlobalSymbol(dread.GetStIdx());
|
||||
DEBUG_ASSERT(symbol != nullptr, "symbol should not be nullptr");
|
||||
auto *structTy = static_cast<MIRStructType *>(symbol->GetType());
|
||||
auto fTyIdx = structTy->GetFieldTyIdx(dread.GetFieldID());
|
||||
auto *fType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(fTyIdx));
|
||||
if (fType->GetKind() != kTypeBitField) {
|
||||
return &dread;
|
||||
}
|
||||
auto *builder = mirModule.GetMIRBuilder();
|
||||
auto *baseAddr = builder->CreateExprAddrof(0, dread.GetStIdx());
|
||||
auto byteBitOffsets = beCommon.GetFieldOffset(*structTy, dread.GetFieldID());
|
||||
return ReadBitField(byteBitOffsets, static_cast<MIRBitFieldType *>(fType), baseAddr);
|
||||
}
|
||||
|
||||
BaseNode *CGLowerer::LowerIreadBitfield(IreadNode &iread)
|
||||
{
|
||||
uint32 index = iread.GetTyIdx();
|
||||
MIRPtrType *pointerTy = static_cast<MIRPtrType *>(GlobalTables::GetTypeTable().GetTypeFromTyIdx(index));
|
||||
MIRType *pointedTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(pointerTy->GetPointedTyIdx());
|
||||
/* Here pointed type can be Struct or JArray */
|
||||
MIRStructType *structTy = nullptr;
|
||||
if (pointedTy->GetKind() != kTypeJArray) {
|
||||
structTy = static_cast<MIRStructType *>(pointedTy);
|
||||
} else {
|
||||
structTy = static_cast<MIRJarrayType *>(pointedTy)->GetParentType();
|
||||
}
|
||||
TyIdx fTyIdx = structTy->GetFieldTyIdx(iread.GetFieldID());
|
||||
MIRType *fType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(fTyIdx));
|
||||
if (fType->GetKind() != kTypeBitField) {
|
||||
return &iread;
|
||||
}
|
||||
auto byteBitOffsets = beCommon.GetFieldOffset(*structTy, iread.GetFieldID());
|
||||
return ReadBitField(byteBitOffsets, static_cast<MIRBitFieldType *>(fType), iread.Opnd(0));
|
||||
}
|
||||
|
||||
// input node must be cvt, retype, zext or sext
|
||||
BaseNode *CGLowerer::LowerCastExpr(BaseNode &expr)
|
||||
{
|
||||
@ -242,67 +182,12 @@ BlockNode *CGLowerer::LowerReturn(NaryStmtNode &retNode)
|
||||
return blk;
|
||||
}
|
||||
|
||||
StmtNode *CGLowerer::LowerDassignBitfield(DassignNode &dassign, BlockNode &newBlk)
|
||||
{
|
||||
dassign.SetRHS(LowerExpr(dassign, *dassign.GetRHS(), newBlk));
|
||||
DEBUG_ASSERT(mirModule.CurFunction() != nullptr, "CurFunction should not be nullptr");
|
||||
MIRSymbol *symbol = mirModule.CurFunction()->GetLocalOrGlobalSymbol(dassign.GetStIdx());
|
||||
MIRStructType *structTy = static_cast<MIRStructType *>(symbol->GetType());
|
||||
CHECK_FATAL(structTy != nullptr, "LowerDassignBitfield: non-zero fieldID for non-structure");
|
||||
TyIdx fTyIdx = structTy->GetFieldTyIdx(dassign.GetFieldID());
|
||||
CHECK_FATAL(fTyIdx != 0u, "LowerDassignBitField: field id out of range for the structure");
|
||||
MIRType *fType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(fTyIdx));
|
||||
if (fType->GetKind() != kTypeBitField) {
|
||||
return &dassign;
|
||||
}
|
||||
auto *builder = mirModule.GetMIRBuilder();
|
||||
auto *baseAddr = builder->CreateExprAddrof(0, dassign.GetStIdx());
|
||||
auto byteBitOffsets = beCommon.GetFieldOffset(*structTy, dassign.GetFieldID());
|
||||
return WriteBitField(byteBitOffsets, static_cast<MIRBitFieldType *>(fType), baseAddr, dassign.GetRHS(), &newBlk);
|
||||
}
|
||||
|
||||
StmtNode *CGLowerer::LowerIassignBitfield(IassignNode &iassign, BlockNode &newBlk)
|
||||
{
|
||||
DEBUG_ASSERT(iassign.Opnd(0) != nullptr, "iassign.Opnd(0) should not be nullptr");
|
||||
iassign.SetOpnd(LowerExpr(iassign, *iassign.Opnd(0), newBlk), 0);
|
||||
iassign.SetRHS(LowerExpr(iassign, *iassign.GetRHS(), newBlk));
|
||||
|
||||
CHECK_FATAL(iassign.GetTyIdx() < GlobalTables::GetTypeTable().GetTypeTable().size(),
|
||||
"LowerIassignBitField: subscript out of range");
|
||||
uint32 index = iassign.GetTyIdx();
|
||||
MIRPtrType *pointerTy = static_cast<MIRPtrType *>(GlobalTables::GetTypeTable().GetTypeFromTyIdx(index));
|
||||
CHECK_FATAL(pointerTy != nullptr, "LowerIassignBitField: type in iassign should be pointer type");
|
||||
MIRType *pointedTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(pointerTy->GetPointedTyIdx());
|
||||
/*
|
||||
* Here pointed type can be Struct or JArray
|
||||
* We should seriously consider make JArray also a Struct type
|
||||
*/
|
||||
MIRStructType *structTy = nullptr;
|
||||
if (pointedTy->GetKind() != kTypeJArray) {
|
||||
structTy = static_cast<MIRStructType *>(pointedTy);
|
||||
} else {
|
||||
structTy = static_cast<MIRJarrayType *>(pointedTy)->GetParentType();
|
||||
}
|
||||
|
||||
TyIdx fTyIdx = structTy->GetFieldTyIdx(iassign.GetFieldID());
|
||||
MIRType *fType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(fTyIdx));
|
||||
if (fType->GetKind() != kTypeBitField) {
|
||||
return &iassign;
|
||||
}
|
||||
auto byteBitOffsets = beCommon.GetFieldOffset(*structTy, iassign.GetFieldID());
|
||||
auto *bitFieldType = static_cast<MIRBitFieldType *>(fType);
|
||||
return WriteBitField(byteBitOffsets, bitFieldType, iassign.Opnd(0), iassign.GetRHS(), &newBlk);
|
||||
}
|
||||
|
||||
void CGLowerer::LowerIassign(IassignNode &iassign, BlockNode &newBlk)
|
||||
{
|
||||
StmtNode *newStmt = nullptr;
|
||||
if (iassign.GetFieldID() != 0) {
|
||||
newStmt = LowerIassignBitfield(iassign, newBlk);
|
||||
} else {
|
||||
LowerStmt(iassign, newBlk);
|
||||
newStmt = &iassign;
|
||||
}
|
||||
CHECK_FATAL(iassign.GetFieldID() == 0, "fieldID must be 0");
|
||||
LowerStmt(iassign, newBlk);
|
||||
newStmt = &iassign;
|
||||
newBlk.AddStatement(newStmt);
|
||||
}
|
||||
|
||||
@ -653,226 +538,6 @@ BlockNode *CGLowerer::LowerIntrinsiccallToIntrinsicop(StmtNode &stmt)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#if TARGAARCH64
|
||||
static PrimType IsStructElementSame(MIRType *ty)
|
||||
{
|
||||
if (ty->GetKind() == kTypeArray) {
|
||||
MIRArrayType *arrtype = static_cast<MIRArrayType *>(ty);
|
||||
MIRType *pty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(arrtype->GetElemTyIdx());
|
||||
if (pty->GetKind() == kTypeArray || pty->GetKind() == kTypeStruct) {
|
||||
return IsStructElementSame(pty);
|
||||
}
|
||||
return pty->GetPrimType();
|
||||
} else if (ty->GetKind() == kTypeStruct) {
|
||||
MIRStructType *sttype = static_cast<MIRStructType *>(ty);
|
||||
FieldVector fields = sttype->GetFields();
|
||||
PrimType oldtype = PTY_void;
|
||||
for (uint32 fcnt = 0; fcnt < fields.size(); ++fcnt) {
|
||||
TyIdx fieldtyidx = fields[fcnt].second.first;
|
||||
MIRType *fieldty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldtyidx);
|
||||
PrimType ptype = IsStructElementSame(fieldty);
|
||||
if (oldtype != PTY_void && oldtype != ptype) {
|
||||
return PTY_void;
|
||||
} else {
|
||||
oldtype = ptype;
|
||||
}
|
||||
}
|
||||
return oldtype;
|
||||
} else {
|
||||
return ty->GetPrimType();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// return true if successfully lowered
|
||||
bool CGLowerer::LowerStructReturn(BlockNode &newBlk, StmtNode &stmt, bool &lvar)
|
||||
{
|
||||
CallReturnVector *p2nrets = stmt.GetCallReturnVector();
|
||||
if (p2nrets->size() == 0) {
|
||||
return false;
|
||||
}
|
||||
CallReturnPair retPair = (*p2nrets)[0];
|
||||
if (retPair.second.IsReg()) {
|
||||
return false;
|
||||
}
|
||||
DEBUG_ASSERT(mirModule.CurFunction() != nullptr, "CurFunction should not be nullptr");
|
||||
MIRSymbol *retSym = mirModule.CurFunction()->GetLocalOrGlobalSymbol(retPair.first);
|
||||
if (retSym->GetType()->GetPrimType() != PTY_agg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsReturnInMemory(*retSym->GetType())) {
|
||||
lvar = true;
|
||||
} else if (!LowerStructReturnInRegs(newBlk, stmt, *retSym)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGLowerer::LowerStructReturnInRegs(BlockNode &newBlk, StmtNode &stmt, const MIRSymbol &retSym)
|
||||
{
|
||||
// lower callassigned -> call
|
||||
if (stmt.GetOpCode() == OP_callassigned) {
|
||||
auto &callNode = static_cast<CallNode &>(stmt);
|
||||
for (size_t i = 0; i < callNode.GetNopndSize(); ++i) {
|
||||
auto *newOpnd = LowerExpr(callNode, *callNode.GetNopndAt(i), newBlk);
|
||||
callNode.SetOpnd(newOpnd, i);
|
||||
}
|
||||
auto *callStmt = mirModule.GetMIRBuilder()->CreateStmtCall(callNode.GetPUIdx(), callNode.GetNopnd());
|
||||
callStmt->SetSrcPos(callNode.GetSrcPos());
|
||||
newBlk.AddStatement(callStmt);
|
||||
} else if (stmt.GetOpCode() == OP_icallassigned || stmt.GetOpCode() == OP_icallprotoassigned) {
|
||||
auto &icallNode = static_cast<IcallNode &>(stmt);
|
||||
for (size_t i = 0; i < icallNode.GetNopndSize(); ++i) {
|
||||
auto *newOpnd = LowerExpr(icallNode, *icallNode.GetNopndAt(i), newBlk);
|
||||
icallNode.SetOpnd(newOpnd, i);
|
||||
}
|
||||
IcallNode *icallStmt = nullptr;
|
||||
if (stmt.GetOpCode() == OP_icallassigned) {
|
||||
icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcall(icallNode.GetNopnd());
|
||||
} else {
|
||||
icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcallproto(icallNode.GetNopnd(), icallNode.GetRetTyIdx());
|
||||
}
|
||||
icallStmt->SetSrcPos(icallNode.GetSrcPos());
|
||||
newBlk.AddStatement(icallStmt);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Triple::GetTriple().IsAarch64BeOrLe()) {
|
||||
#if TARGAARCH64
|
||||
PrimType primType = PTY_begin;
|
||||
size_t elemNum = 0;
|
||||
if (IsHomogeneousAggregates(*retSym.GetType(), primType, elemNum)) {
|
||||
LowerStructReturnInFpRegs(newBlk, stmt, retSym, primType, elemNum);
|
||||
} else {
|
||||
LowerStructReturnInGpRegs(newBlk, stmt, retSym);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
LowerStructReturnInGpRegs(newBlk, stmt, retSym);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// struct passed in gpregs, lowered into
|
||||
// call &foo
|
||||
// regassign u64 %1 (regread u64 %%retval0)
|
||||
// regassign ptr %2 (addrof ptr $s)
|
||||
// iassign <* u64> 0 (regread ptr %2, regread u64 %1)
|
||||
void CGLowerer::LowerStructReturnInGpRegs(BlockNode &newBlk, const StmtNode &stmt, const MIRSymbol &symbol)
|
||||
{
|
||||
auto size = static_cast<uint32>(symbol.GetType()->GetSize());
|
||||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
// save retval0, retval1
|
||||
PregIdx pIdx1R = 0;
|
||||
PregIdx pIdx2R = 0;
|
||||
DEBUG_ASSERT(GetCurrentFunc() != nullptr, "GetCurrentFunc should not be nullptr");
|
||||
auto genRetvalSave = [this, &newBlk](PregIdx &pIdx, SpecialReg sreg) {
|
||||
auto *regreadNode = mirBuilder->CreateExprRegread(PTY_u64, -sreg);
|
||||
pIdx = GetCurrentFunc()->GetPregTab()->CreatePreg(PTY_u64);
|
||||
auto *aStmt = mirBuilder->CreateStmtRegassign(PTY_u64, pIdx, regreadNode);
|
||||
newBlk.AddStatement(aStmt);
|
||||
};
|
||||
genRetvalSave(pIdx1R, kSregRetval0);
|
||||
if (size > k8ByteSize) {
|
||||
genRetvalSave(pIdx2R, kSregRetval1);
|
||||
}
|
||||
// save &s
|
||||
BaseNode *regAddr = mirBuilder->CreateExprAddrof(0, symbol);
|
||||
LowerTypePtr(*regAddr);
|
||||
PregIdx pIdxL = GetCurrentFunc()->GetPregTab()->CreatePreg(GetLoweredPtrType());
|
||||
auto *aStmt = mirBuilder->CreateStmtRegassign(PTY_a64, pIdxL, regAddr);
|
||||
newBlk.AddStatement(aStmt);
|
||||
|
||||
// str retval to &s
|
||||
for (uint32 curSize = 0; curSize < size;) {
|
||||
// calc addr
|
||||
BaseNode *addrNode = mirBuilder->CreateExprRegread(GetLoweredPtrType(), pIdxL);
|
||||
if (curSize != 0) {
|
||||
MIRType *addrType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(GetLoweredPtrType());
|
||||
addrNode =
|
||||
mirBuilder->CreateExprBinary(OP_add, *addrType, addrNode, mirBuilder->CreateIntConst(curSize, PTY_i32));
|
||||
}
|
||||
|
||||
PregIdx pIdxR = (curSize < k8ByteSize) ? pIdx1R : pIdx2R;
|
||||
uint32 strSize = size - curSize;
|
||||
// gen str retval to &s + offset
|
||||
auto genStrRetval2Memory = [this, &newBlk, &addrNode, &curSize, &pIdxR](PrimType primType) {
|
||||
uint32 shiftSize = (curSize * kBitsPerByte) % k64BitSize;
|
||||
if (CGOptions::IsBigEndian()) {
|
||||
shiftSize = k64BitSize - GetPrimTypeBitSize(primType) + shiftSize;
|
||||
}
|
||||
BaseNode *regreadExp = mirBuilder->CreateExprRegread(PTY_u64, pIdxR);
|
||||
if (shiftSize != 0) {
|
||||
MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(PTY_u64);
|
||||
regreadExp = mirBuilder->CreateExprBinary(OP_lshr, *type, regreadExp,
|
||||
mirBuilder->CreateIntConst(shiftSize, PTY_i32));
|
||||
}
|
||||
auto *pointedType = GlobalTables::GetTypeTable().GetPrimType(primType);
|
||||
auto *iassignStmt = mirBuilder->CreateStmtIassign(*beCommon.BeGetOrCreatePointerType(*pointedType), 0,
|
||||
addrNode, regreadExp);
|
||||
newBlk.AddStatement(iassignStmt);
|
||||
curSize += GetPrimTypeSize(primType);
|
||||
};
|
||||
if (strSize >= k8ByteSize) {
|
||||
genStrRetval2Memory(PTY_u64);
|
||||
} else if (strSize >= k4ByteSize) {
|
||||
genStrRetval2Memory(PTY_u32);
|
||||
} else if (strSize >= k2ByteSize) {
|
||||
genStrRetval2Memory(PTY_u16);
|
||||
} else {
|
||||
genStrRetval2Memory(PTY_u8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// struct passed in fpregs, lowered into
|
||||
// call &foo
|
||||
// regassign f64 %1 (regread f64 %%retval0)
|
||||
// regassign ptr %2 (addrof ptr $s)
|
||||
// iassign <* f64> 0 (regread ptr %2, regread f64 %1)
|
||||
void CGLowerer::LowerStructReturnInFpRegs(BlockNode &newBlk, const StmtNode &stmt, const MIRSymbol &symbol,
|
||||
PrimType primType, size_t elemNum)
|
||||
{
|
||||
// save retvals
|
||||
static constexpr std::array sregs = {kSregRetval0, kSregRetval1, kSregRetval2, kSregRetval3};
|
||||
std::vector<PregIdx> pIdxs(sregs.size(), 0);
|
||||
DEBUG_ASSERT(GetCurrentFunc() != nullptr, "GetCurrentFunc should not be nullptr");
|
||||
for (uint32 i = 0; i < elemNum; ++i) {
|
||||
auto *regreadNode = mirBuilder->CreateExprRegread(primType, -sregs[i]);
|
||||
pIdxs[i] = GetCurrentFunc()->GetPregTab()->CreatePreg(primType);
|
||||
auto *aStmt = mirBuilder->CreateStmtRegassign(primType, pIdxs[i], regreadNode);
|
||||
newBlk.AddStatement(aStmt);
|
||||
}
|
||||
|
||||
// save &s
|
||||
BaseNode *regAddr = mirBuilder->CreateExprAddrof(0, symbol);
|
||||
LowerTypePtr(*regAddr);
|
||||
PregIdx pIdxL = GetCurrentFunc()->GetPregTab()->CreatePreg(GetLoweredPtrType());
|
||||
auto *aStmt = mirBuilder->CreateStmtRegassign(PTY_a64, pIdxL, regAddr);
|
||||
newBlk.AddStatement(aStmt);
|
||||
|
||||
// str retvals to &s
|
||||
for (uint32 i = 0; i < elemNum; ++i) {
|
||||
uint32 offsetSize = i * GetPrimTypeSize(primType);
|
||||
BaseNode *addrNode = mirBuilder->CreateExprRegread(GetLoweredPtrType(), pIdxL);
|
||||
// addr add offset
|
||||
if (offsetSize != 0) {
|
||||
MIRType *addrType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(GetLoweredPtrType());
|
||||
addrNode = mirBuilder->CreateExprBinary(OP_add, *addrType, addrNode,
|
||||
mirBuilder->CreateIntConst(offsetSize, PTY_i32));
|
||||
}
|
||||
// gen iassigen to addr
|
||||
auto *pointedType = GlobalTables::GetTypeTable().GetPrimType(primType);
|
||||
auto *iassignStmt = mirBuilder->CreateStmtIassign(*beCommon.BeGetOrCreatePointerType(*pointedType), 0, addrNode,
|
||||
mirBuilder->CreateExprRegread(PTY_u64, pIdxs[i]));
|
||||
newBlk.AddStatement(iassignStmt);
|
||||
}
|
||||
}
|
||||
|
||||
void CGLowerer::LowerStmt(StmtNode &stmt, BlockNode &newBlk)
|
||||
{
|
||||
for (size_t i = 0; i < stmt.NumOpnds(); ++i) {
|
||||
@ -949,10 +614,7 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block)
|
||||
case OP_icallprotoassigned: {
|
||||
// pass the addr of lvar if this is a struct call assignment
|
||||
bool lvar = false;
|
||||
// nextStmt could be changed by the call to LowerStructReturn
|
||||
if (!LowerStructReturn(*newBlk, *stmt, lvar)) {
|
||||
newBlk->AppendStatementsFromBlock(*LowerCallAssignedStmt(*stmt, lvar));
|
||||
}
|
||||
newBlk->AppendStatementsFromBlock(*LowerCallAssignedStmt(*stmt, lvar));
|
||||
break;
|
||||
}
|
||||
case OP_virtualcallassigned:
|
||||
@ -1077,14 +739,6 @@ StmtNode *CGLowerer::LowerCall(CallNode &callNode, StmtNode *&nextStmt, BlockNod
|
||||
|
||||
if (isArrayStore && checkLoadStore) {
|
||||
bool needCheckStore = true;
|
||||
MIRType *arrayElemType = GetArrayNodeType(*callNode.Opnd(0));
|
||||
MIRType *valueRealType = GetArrayNodeType(*callNode.Opnd(kNodeThirdOpnd));
|
||||
if ((arrayElemType != nullptr) && (valueRealType != nullptr) && (arrayElemType->GetKind() == kTypeClass) &&
|
||||
static_cast<MIRClassType *>(arrayElemType)->IsFinal() && (valueRealType->GetKind() == kTypeClass) &&
|
||||
static_cast<MIRClassType *>(valueRealType)->IsFinal() &&
|
||||
valueRealType->GetTypeIndex() == arrayElemType->GetTypeIndex()) {
|
||||
needCheckStore = false;
|
||||
}
|
||||
|
||||
if (needCheckStore) {
|
||||
MIRFunction *fn =
|
||||
@ -1116,72 +770,12 @@ StmtNode *CGLowerer::LowerCall(CallNode &callNode, StmtNode *&nextStmt, BlockNod
|
||||
return &callNode;
|
||||
}
|
||||
|
||||
MIRType *retType = nullptr;
|
||||
if (callNode.op == OP_icall || callNode.op == OP_icallproto) {
|
||||
if (retTy == nullptr) {
|
||||
return &callNode;
|
||||
} else {
|
||||
retType = retTy;
|
||||
}
|
||||
}
|
||||
|
||||
if (retType == nullptr) {
|
||||
MIRFunction *calleeFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode.GetPUIdx());
|
||||
retType = calleeFunc->GetReturnType();
|
||||
if (calleeFunc->IsReturnStruct() && (retType->GetPrimType() == PTY_void)) {
|
||||
MIRPtrType *pretType = static_cast<MIRPtrType *>((calleeFunc->GetNthParamType(0)));
|
||||
CHECK_FATAL(pretType != nullptr, "nullptr is not expected");
|
||||
retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(pretType->GetPointedTyIdx());
|
||||
CHECK_FATAL((retType->GetKind() == kTypeStruct) || (retType->GetKind() == kTypeUnion),
|
||||
"make sure retType is a struct type");
|
||||
}
|
||||
}
|
||||
|
||||
/* if return type is not of a struct, return */
|
||||
if ((retType->GetKind() != kTypeStruct) && (retType->GetKind() != kTypeUnion)) {
|
||||
return &callNode;
|
||||
}
|
||||
|
||||
DEBUG_ASSERT(mirModule.CurFunction() != nullptr, "curFunction should not be nullptr");
|
||||
MIRSymbol *dsgnSt = mirModule.CurFunction()->GetLocalOrGlobalSymbol(dassignNode->GetStIdx());
|
||||
CHECK_FATAL(dsgnSt->GetType()->IsStructType(), "expects a struct type");
|
||||
MIRStructType *structTy = static_cast<MIRStructType *>(dsgnSt->GetType());
|
||||
if (structTy == nullptr) {
|
||||
return &callNode;
|
||||
}
|
||||
|
||||
RegreadNode *regReadNode = nullptr;
|
||||
if (dassignNode->Opnd(0)->GetOpCode() == OP_regread) {
|
||||
regReadNode = static_cast<RegreadNode *>(dassignNode->Opnd(0));
|
||||
}
|
||||
if (regReadNode == nullptr || (regReadNode->GetRegIdx() != -kSregRetval0)) {
|
||||
return &callNode;
|
||||
}
|
||||
|
||||
MapleVector<BaseNode *> newNopnd(mirModule.CurFuncCodeMemPoolAllocator()->Adapter());
|
||||
AddrofNode *addrofNode = mirModule.CurFuncCodeMemPool()->New<AddrofNode>(OP_addrof);
|
||||
addrofNode->SetPrimType(GetLoweredPtrType());
|
||||
addrofNode->SetStIdx(dsgnSt->GetStIdx());
|
||||
addrofNode->SetFieldID(0);
|
||||
|
||||
if (callNode.op == OP_icall || callNode.op == OP_icallproto) {
|
||||
auto ond = callNode.GetNopnd().begin();
|
||||
newNopnd.emplace_back(*ond);
|
||||
newNopnd.emplace_back(addrofNode);
|
||||
for (++ond; ond != callNode.GetNopnd().end(); ++ond) {
|
||||
newNopnd.emplace_back(*ond);
|
||||
}
|
||||
} else {
|
||||
newNopnd.emplace_back(addrofNode);
|
||||
for (auto *opnd : callNode.GetNopnd()) {
|
||||
newNopnd.emplace_back(opnd);
|
||||
}
|
||||
}
|
||||
|
||||
callNode.SetNOpnd(newNopnd);
|
||||
callNode.SetNumOpnds(static_cast<uint8>(newNopnd.size()));
|
||||
CHECK_FATAL(nextStmt != nullptr, "nullptr is not expected");
|
||||
nextStmt = nextStmt->GetNext();
|
||||
return &callNode;
|
||||
}
|
||||
|
||||
@ -1206,28 +800,6 @@ void CGLowerer::LowerTypePtr(BaseNode &node) const
|
||||
|
||||
void CGLowerer::LowerEntry(MIRFunction &func)
|
||||
{
|
||||
// determine if needed to insert fake parameter to return struct for current function
|
||||
if (func.IsReturnStruct()) {
|
||||
MIRType *retType = func.GetReturnType();
|
||||
#if TARGAARCH64
|
||||
if (Triple::GetTriple().GetArch() == Triple::ArchType::aarch64) {
|
||||
PrimType pty = IsStructElementSame(retType);
|
||||
if (pty == PTY_f32 || pty == PTY_f64) {
|
||||
func.SetStructReturnedInRegs();
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (retType->GetPrimType() != PTY_agg) {
|
||||
return;
|
||||
}
|
||||
if (retType->GetSize() > k16ByteSize) {
|
||||
func.SetFirstArgReturn();
|
||||
func.GetMIRFuncType()->SetFirstArgReturn();
|
||||
} else {
|
||||
func.SetStructReturnedInRegs();
|
||||
}
|
||||
}
|
||||
if (func.IsFirstArgReturn() && func.GetReturnType()->GetPrimType() != PTY_void) {
|
||||
MIRSymbol *retSt = func.GetSymTab()->CreateSymbol(kScopeLocal);
|
||||
retSt->SetStorageClass(kScFormal);
|
||||
@ -1461,7 +1033,8 @@ BaseNode *CGLowerer::LowerDread(DreadNode &dread, const BlockNode &block)
|
||||
if (dread.GetPrimType() == PTY_u1) {
|
||||
dread.SetPrimType(PTY_u8);
|
||||
}
|
||||
return (dread.GetFieldID() == 0 ? LowerDreadToThreadLocal(dread, block) : LowerDreadBitfield(dread));
|
||||
CHECK_FATAL(dread.GetFieldID() == 0, "fieldID must be 0");
|
||||
return LowerDreadToThreadLocal(dread, block);
|
||||
}
|
||||
|
||||
void CGLowerer::LowerRegassign(RegassignNode ®Node, BlockNode &newBlk)
|
||||
@ -1540,21 +1113,16 @@ void CGLowerer::LowerDassign(DassignNode &dsNode, BlockNode &newBlk)
|
||||
StmtNode *newStmt = nullptr;
|
||||
BaseNode *rhs = nullptr;
|
||||
Opcode op = dsNode.GetRHS()->GetOpCode();
|
||||
if (dsNode.GetFieldID() != 0) {
|
||||
newStmt = LowerDassignBitfield(dsNode, newBlk);
|
||||
} else if (op == OP_intrinsicop) {
|
||||
CHECK_FATAL(dsNode.GetFieldID() == 0, "fieldID must be 0");
|
||||
if (op == OP_intrinsicop) {
|
||||
IntrinsicopNode *intrinNode = static_cast<IntrinsicopNode *>(dsNode.GetRHS());
|
||||
MIRType *retType = IntrinDesc::intrinTable[intrinNode->GetIntrinsic()].GetReturnType();
|
||||
CHECK_FATAL(retType != nullptr, "retType should not be nullptr");
|
||||
if (retType->GetKind() == kTypeStruct) {
|
||||
newStmt = LowerIntrinsicopDassign(dsNode, *intrinNode, newBlk);
|
||||
} else {
|
||||
rhs = LowerExpr(dsNode, *intrinNode, newBlk);
|
||||
dsNode.SetRHS(rhs);
|
||||
CHECK_FATAL(dsNode.GetRHS() != nullptr, "dsNode->rhs is null in CGLowerer::LowerDassign");
|
||||
if (!IsDassignNOP(dsNode)) {
|
||||
newStmt = &dsNode;
|
||||
}
|
||||
rhs = LowerExpr(dsNode, *intrinNode, newBlk);
|
||||
dsNode.SetRHS(rhs);
|
||||
CHECK_FATAL(dsNode.GetRHS() != nullptr, "dsNode->rhs is null in CGLowerer::LowerDassign");
|
||||
if (!IsDassignNOP(dsNode)) {
|
||||
newStmt = &dsNode;
|
||||
}
|
||||
} else {
|
||||
rhs = LowerExpr(dsNode, *dsNode.GetRHS(), newBlk);
|
||||
@ -1567,53 +1135,6 @@ void CGLowerer::LowerDassign(DassignNode &dsNode, BlockNode &newBlk)
|
||||
}
|
||||
}
|
||||
|
||||
StmtNode *CGLowerer::LowerIntrinsicopDassign(const DassignNode &dsNode, IntrinsicopNode &intrinNode, BlockNode &newBlk)
|
||||
{
|
||||
for (size_t i = 0; i < intrinNode.GetNumOpnds(); ++i) {
|
||||
DEBUG_ASSERT(intrinNode.Opnd(i) != nullptr, "intrinNode.Opnd(i) should not be nullptr");
|
||||
intrinNode.SetOpnd(LowerExpr(intrinNode, *intrinNode.Opnd(i), newBlk), i);
|
||||
}
|
||||
MIRIntrinsicID intrnID = intrinNode.GetIntrinsic();
|
||||
IntrinDesc *intrinDesc = &IntrinDesc::intrinTable[intrnID];
|
||||
MIRSymbol *st = GlobalTables::GetGsymTable().CreateSymbol(kScopeGlobal);
|
||||
const std::string name = intrinDesc->name;
|
||||
CHECK_FATAL(intrinDesc->name != nullptr, "intrinDesc's name should not be nullptr");
|
||||
st->SetNameStrIdx(name);
|
||||
st->SetStorageClass(kScText);
|
||||
st->SetSKind(kStFunc);
|
||||
MIRFunction *fn = mirModule.GetMemPool()->New<MIRFunction>(&mirModule, st->GetStIdx());
|
||||
MapleVector<BaseNode *> &nOpnds = intrinNode.GetNopnd();
|
||||
st->SetFunction(fn);
|
||||
std::vector<TyIdx> fnTyVec;
|
||||
std::vector<TypeAttrs> fnTaVec;
|
||||
CHECK_FATAL(intrinDesc->IsJsOp(), "intrinDesc should be JsOp");
|
||||
/* setup parameters */
|
||||
for (uint32 i = 0; i < nOpnds.size(); ++i) {
|
||||
fnTyVec.emplace_back(GlobalTables::GetTypeTable().GetTypeFromTyIdx(PTY_a32)->GetTypeIndex());
|
||||
fnTaVec.emplace_back(TypeAttrs());
|
||||
BaseNode *addrNode = beCommon.GetAddressOfNode(*nOpnds[i]);
|
||||
CHECK_FATAL(addrNode != nullptr, "addrNode should not be nullptr");
|
||||
nOpnds[i] = addrNode;
|
||||
}
|
||||
DEBUG_ASSERT(mirModule.CurFunction() != nullptr, "curFunction should not be nullptr");
|
||||
MIRSymbol *dst = mirModule.CurFunction()->GetLocalOrGlobalSymbol(dsNode.GetStIdx());
|
||||
MIRType *ty = dst->GetType();
|
||||
MIRType *fnType = beCommon.BeGetOrCreateFunctionType(ty->GetTypeIndex(), fnTyVec, fnTaVec);
|
||||
st->SetTyIdx(fnType->GetTypeIndex());
|
||||
fn->SetMIRFuncType(static_cast<MIRFuncType *>(fnType));
|
||||
fn->SetReturnTyIdx(ty->GetTypeIndex());
|
||||
CHECK_FATAL(ty->GetKind() == kTypeStruct, "ty's kind should be struct type");
|
||||
CHECK_FATAL(dsNode.GetFieldID() == 0, "dsNode's filedId should equal");
|
||||
AddrofNode *addrofNode = mirBuilder->CreateAddrof(*dst, PTY_a32);
|
||||
MapleVector<BaseNode *> newOpnd(mirModule.CurFuncCodeMemPoolAllocator()->Adapter());
|
||||
newOpnd.emplace_back(addrofNode);
|
||||
(void)newOpnd.insert(newOpnd.end(), nOpnds.begin(), nOpnds.end());
|
||||
CallNode *callStmt = mirModule.CurFuncCodeMemPool()->New<CallNode>(mirModule, OP_call);
|
||||
callStmt->SetPUIdx(st->GetFunction()->GetPuidx());
|
||||
callStmt->SetNOpnd(newOpnd);
|
||||
return callStmt;
|
||||
}
|
||||
|
||||
StmtNode *CGLowerer::LowerDefaultIntrinsicCall(IntrinsiccallNode &intrincall, MIRSymbol &st, MIRFunction &fn)
|
||||
{
|
||||
MIRIntrinsicID intrnID = intrincall.GetIntrinsic();
|
||||
@ -1623,33 +1144,16 @@ StmtNode *CGLowerer::LowerDefaultIntrinsicCall(IntrinsiccallNode &intrincall, MI
|
||||
MapleVector<BaseNode *> &nOpnds = intrincall.GetNopnd();
|
||||
MIRType *retTy = intrinDesc->GetReturnType();
|
||||
CHECK_FATAL(retTy != nullptr, "retTy should not be nullptr");
|
||||
if (retTy->GetKind() == kTypeStruct) {
|
||||
funcTyVec.emplace_back(beCommon.BeGetOrCreatePointerType(*retTy)->GetTypeIndex());
|
||||
fnTaVec.emplace_back(TypeAttrs());
|
||||
fn.SetReturnStruct();
|
||||
}
|
||||
for (uint32 i = 0; i < nOpnds.size(); ++i) {
|
||||
MIRType *argTy = intrinDesc->GetArgType(i);
|
||||
CHECK_FATAL(argTy != nullptr, "argTy should not be nullptr");
|
||||
if (argTy->GetKind() == kTypeStruct) {
|
||||
funcTyVec.emplace_back(GlobalTables::GetTypeTable().GetTypeFromTyIdx(PTY_a32)->GetTypeIndex());
|
||||
fnTaVec.emplace_back(TypeAttrs());
|
||||
BaseNode *addrNode = beCommon.GetAddressOfNode(*nOpnds[i]);
|
||||
CHECK_FATAL(addrNode != nullptr, "can not get address");
|
||||
nOpnds[i] = addrNode;
|
||||
} else {
|
||||
funcTyVec.emplace_back(argTy->GetTypeIndex());
|
||||
fnTaVec.emplace_back(TypeAttrs());
|
||||
}
|
||||
funcTyVec.emplace_back(argTy->GetTypeIndex());
|
||||
fnTaVec.emplace_back(TypeAttrs());
|
||||
}
|
||||
MIRType *funcType = beCommon.BeGetOrCreateFunctionType(retTy->GetTypeIndex(), funcTyVec, fnTaVec);
|
||||
st.SetTyIdx(funcType->GetTypeIndex());
|
||||
fn.SetMIRFuncType(static_cast<MIRFuncType *>(funcType));
|
||||
if (retTy->GetKind() == kTypeStruct) {
|
||||
fn.SetReturnTyIdx(static_cast<TyIdx>(PTY_void));
|
||||
} else {
|
||||
fn.SetReturnTyIdx(retTy->GetTypeIndex());
|
||||
}
|
||||
fn.SetReturnTyIdx(retTy->GetTypeIndex());
|
||||
return static_cast<CallNode *>(mirBuilder->CreateStmtCall(fn.GetPuidx(), nOpnds));
|
||||
}
|
||||
|
||||
|
@ -231,21 +231,6 @@ std::string AArch64CG::FindGCTIBPatternName(const std::string &name) const
|
||||
return iter->second->GetName();
|
||||
}
|
||||
|
||||
void AArch64CG::GenerateObjectMaps(BECommon &beCommon)
|
||||
{
|
||||
for (auto &tyId : GetMIRModule()->GetClassList()) {
|
||||
TyIdx tyIdx(tyId);
|
||||
MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
|
||||
DEBUG_ASSERT(ty != nullptr, "ty nullptr check");
|
||||
/* Only emit GCTIB for classes owned by this module */
|
||||
DEBUG_ASSERT(ty->IsStructType(), "ty isn't MIRStructType* in AArch64CG::GenerateObjectMaps");
|
||||
MIRStructType *strTy = static_cast<MIRStructType *>(ty);
|
||||
if (!strTy->IsLocal()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AArch64CG::EnrollTargetPhases(MaplePhaseManager *pm) const
|
||||
{
|
||||
if (!GetMIRModule()->IsCModule()) {
|
||||
|
@ -712,24 +712,11 @@ void AArch64CGFunc::SelectDassign(StIdx stIdx, FieldID fieldId, PrimType rhsPTyp
|
||||
MIRSymbol *symbol = GetFunction().GetLocalOrGlobalSymbol(stIdx);
|
||||
int32 offset = 0;
|
||||
bool parmCopy = false;
|
||||
if (fieldId != 0) {
|
||||
MIRStructType *structType = static_cast<MIRStructType *>(symbol->GetType());
|
||||
DEBUG_ASSERT(structType != nullptr, "SelectDassign: non-zero fieldID for non-structure");
|
||||
offset = GetBecommon().GetFieldOffset(*structType, fieldId).first;
|
||||
parmCopy = IsParamStructCopy(*symbol);
|
||||
}
|
||||
uint32 regSize = GetPrimTypeBitSize(rhsPType);
|
||||
MIRType *type = symbol->GetType();
|
||||
Operand &stOpnd = LoadIntoRegister(opnd0, IsPrimitiveInteger(rhsPType),
|
||||
regSize, IsSignedInteger(type->GetPrimType()));
|
||||
MOperator mOp = MOP_undef;
|
||||
if ((type->GetKind() == kTypeStruct) || (type->GetKind() == kTypeUnion)) {
|
||||
MIRStructType *structType = static_cast<MIRStructType *>(type);
|
||||
type = structType->GetFieldType(fieldId);
|
||||
} else if (type->GetKind() == kTypeClass) {
|
||||
MIRClassType *classType = static_cast<MIRClassType *>(type);
|
||||
type = classType->GetFieldType(fieldId);
|
||||
}
|
||||
|
||||
uint32 dataSize = GetPrimTypeBitSize(type->GetPrimType());
|
||||
if (type->GetPrimType() == PTY_agg) {
|
||||
@ -748,9 +735,7 @@ void AArch64CGFunc::SelectDassign(StIdx stIdx, FieldID fieldId, PrimType rhsPTyp
|
||||
/* In bpl mode, a func symbol's type is represented as a MIRFuncType instead of a MIRPtrType (pointing to
|
||||
* MIRFuncType), so we allow `kTypeFunction` to appear here */
|
||||
DEBUG_ASSERT(((type->GetKind() == kTypeScalar) || (type->GetKind() == kTypePointer) ||
|
||||
(type->GetKind() == kTypeFunction) || (type->GetKind() == kTypeStruct) ||
|
||||
(type->GetKind() == kTypeUnion) || (type->GetKind() == kTypeArray)),
|
||||
"NYI dassign type");
|
||||
(type->GetKind() == kTypeFunction) || (type->GetKind() == kTypeArray)), "NYI dassign type");
|
||||
PrimType ptyp = type->GetPrimType();
|
||||
if (ptyp == PTY_agg) {
|
||||
ptyp = PTY_a64;
|
||||
@ -823,19 +808,6 @@ void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0)
|
||||
}
|
||||
}
|
||||
|
||||
MemOperand *AArch64CGFunc::GenFormalMemOpndWithSymbol(const MIRSymbol &sym, int64 offset)
|
||||
{
|
||||
MemOperand *memOpnd = nullptr;
|
||||
if (IsParamStructCopy(sym)) {
|
||||
memOpnd = &GetOrCreateMemOpnd(sym, 0, k64BitSize);
|
||||
RegOperand *vreg = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize));
|
||||
Insn &ldInsn = GetInsnBuilder()->BuildInsn(PickLdInsn(k64BitSize, PTY_i64), *vreg, *memOpnd);
|
||||
GetCurBB()->AppendInsn(ldInsn);
|
||||
return CreateMemOperand(k64BitSize, *vreg, CreateImmOperand(offset, k32BitSize, false), sym.IsVolatile());
|
||||
}
|
||||
return &GetOrCreateMemOpnd(sym, offset, k64BitSize);
|
||||
}
|
||||
|
||||
CCImpl *AArch64CGFunc::GetOrCreateLocator(CallConvKind cc)
|
||||
{
|
||||
auto it = hashCCTable.find(cc);
|
||||
@ -876,22 +848,7 @@ void AArch64CGFunc::SelectIassign(IassignNode &stmt)
|
||||
DEBUG_ASSERT(pointerType != nullptr, "expect a pointer type at iassign node");
|
||||
MIRType *pointedType = nullptr;
|
||||
bool isRefField = false;
|
||||
|
||||
if (stmt.GetFieldID() != 0) {
|
||||
MIRType *pointedTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(pointerType->GetPointedTyIdx());
|
||||
MIRStructType *structType = nullptr;
|
||||
if (pointedTy->GetKind() != kTypeJArray) {
|
||||
structType = static_cast<MIRStructType *>(pointedTy);
|
||||
} else {
|
||||
structType = static_cast<MIRJarrayType *>(pointedTy)->GetParentType();
|
||||
}
|
||||
DEBUG_ASSERT(structType != nullptr, "SelectIassign: non-zero fieldID for non-structure");
|
||||
pointedType = structType->GetFieldType(stmt.GetFieldID());
|
||||
offset = GetBecommon().GetFieldOffset(*structType, stmt.GetFieldID()).first;
|
||||
isRefField = GetBecommon().IsRefField(*structType, stmt.GetFieldID());
|
||||
} else {
|
||||
pointedType = GetPointedToType(*pointerType);
|
||||
}
|
||||
pointedType = GetPointedToType(*pointerType);
|
||||
|
||||
PrimType styp = stmt.GetRHS()->GetPrimType();
|
||||
Operand *valOpnd = HandleExpr(stmt, *stmt.GetRHS());
|
||||
@ -917,13 +874,6 @@ Operand *AArch64CGFunc::SelectDread(const BaseNode &parent, DreadNode &expr)
|
||||
PrimType symType = symbol->GetType()->GetPrimType();
|
||||
uint32 offset = 0;
|
||||
bool parmCopy = false;
|
||||
if (expr.GetFieldID() != 0) {
|
||||
MIRStructType *structType = static_cast<MIRStructType *>(symbol->GetType());
|
||||
DEBUG_ASSERT(structType != nullptr, "SelectDread: non-zero fieldID for non-structure");
|
||||
symType = structType->GetFieldType(expr.GetFieldID())->GetPrimType();
|
||||
offset = static_cast<uint32>(GetBecommon().GetFieldOffset(*structType, expr.GetFieldID()).first);
|
||||
parmCopy = IsParamStructCopy(*symbol);
|
||||
}
|
||||
|
||||
uint32 dataSize = GetPrimTypeBitSize(symType);
|
||||
uint32 aggSize = 0;
|
||||
@ -1014,22 +964,7 @@ Operand *AArch64CGFunc::SelectIread(const BaseNode &parent, IreadNode &expr, int
|
||||
MIRType *pointedType = nullptr;
|
||||
bool isRefField = false;
|
||||
|
||||
if (expr.GetFieldID() != 0) {
|
||||
MIRType *pointedTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(pointerType->GetPointedTyIdx());
|
||||
MIRStructType *structType = nullptr;
|
||||
if (pointedTy->GetKind() != kTypeJArray) {
|
||||
structType = static_cast<MIRStructType *>(pointedTy);
|
||||
} else {
|
||||
structType = static_cast<MIRJarrayType *>(pointedTy)->GetParentType();
|
||||
}
|
||||
|
||||
DEBUG_ASSERT(structType != nullptr, "SelectIread: non-zero fieldID for non-structure");
|
||||
pointedType = structType->GetFieldType(expr.GetFieldID());
|
||||
offset = GetBecommon().GetFieldOffset(*structType, expr.GetFieldID()).first;
|
||||
isRefField = GetBecommon().IsRefField(*structType, expr.GetFieldID());
|
||||
} else {
|
||||
pointedType = GetPointedToType(*pointerType);
|
||||
}
|
||||
pointedType = GetPointedToType(*pointerType);
|
||||
|
||||
RegType regType = GetRegTyFromPrimTy(expr.GetPrimType());
|
||||
uint32 regSize = GetPrimTypeSize(expr.GetPrimType());
|
||||
@ -1061,13 +996,7 @@ Operand *AArch64CGFunc::SelectIread(const BaseNode &parent, IreadNode &expr, int
|
||||
bitSize = GetPrimTypeBitSize(expr.GetPrimType());
|
||||
maple::LogInfo::MapleLogger(kLlErr) << "Warning: objsize is zero! \n";
|
||||
} else {
|
||||
if (pointedType->IsStructType()) {
|
||||
MIRStructType *structType = static_cast<MIRStructType *>(pointedType);
|
||||
/* size << 3, that is size * 8, change bytes to bits */
|
||||
bitSize = std::min(structType->GetSize(), static_cast<size_t>(GetPointerSize())) << 3;
|
||||
} else {
|
||||
bitSize = GetPrimTypeBitSize(destType);
|
||||
}
|
||||
bitSize = GetPrimTypeBitSize(destType);
|
||||
if (regType == kRegTyFloat) {
|
||||
destType = expr.GetPrimType();
|
||||
bitSize = GetPrimTypeBitSize(destType);
|
||||
|
@ -61,32 +61,11 @@ uint32 AArch64MemLayout::ComputeStackSpaceRequirementForCall(StmtNode &stmt, int
|
||||
CHECK_NULL_FATAL(be.GetMIRModule().CurFunction());
|
||||
MIRSymbol *sym = be.GetMIRModule().CurFunction()->GetLocalOrGlobalSymbol(dread->GetStIdx());
|
||||
ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx());
|
||||
if (dread->GetFieldID() != 0) {
|
||||
DEBUG_ASSERT(ty->GetKind() == kTypeStruct || ty->GetKind() == kTypeClass ||
|
||||
ty->GetKind() == kTypeUnion,
|
||||
"expect struct or class");
|
||||
if (ty->GetKind() == kTypeStruct || ty->GetKind() == kTypeUnion) {
|
||||
ty = static_cast<MIRStructType *>(ty)->GetFieldType(dread->GetFieldID());
|
||||
} else {
|
||||
ty = static_cast<MIRClassType *>(ty)->GetFieldType(dread->GetFieldID());
|
||||
}
|
||||
}
|
||||
} else if (opndOpcode == OP_iread) {
|
||||
IreadNode *iread = static_cast<IreadNode *>(opnd);
|
||||
ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx());
|
||||
DEBUG_ASSERT(ty->GetKind() == kTypePointer, "expect pointer");
|
||||
ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast<MIRPtrType *>(ty)->GetPointedTyIdx());
|
||||
if (iread->GetFieldID() != 0) {
|
||||
DEBUG_ASSERT(ty->GetKind() == kTypeStruct || ty->GetKind() == kTypeClass ||
|
||||
ty->GetKind() == kTypeUnion,
|
||||
"expect struct or class");
|
||||
CHECK_NULL_FATAL(ty);
|
||||
if (ty->GetKind() == kTypeStruct || ty->GetKind() == kTypeUnion) {
|
||||
ty = static_cast<MIRStructType *>(ty)->GetFieldType(iread->GetFieldID());
|
||||
} else {
|
||||
ty = static_cast<MIRClassType *>(ty)->GetFieldType(iread->GetFieldID());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ty == nullptr) { /* type mismatch */
|
||||
continue;
|
||||
|
@ -195,10 +195,6 @@ bool CGOptions::SolveOptions()
|
||||
opts::cg::cg ? SetOption(CGOptions::kDoCg) : ClearOption(CGOptions::kDoCg);
|
||||
}
|
||||
|
||||
if (opts::cg::objmap.IsEnabledByUser()) {
|
||||
SetGenerateObjectMap(opts::cg::objmap);
|
||||
}
|
||||
|
||||
if (opts::cg::generalRegOnly.IsEnabledByUser()) {
|
||||
opts::cg::generalRegOnly ? EnableGeneralRegOnly() : DisableGeneralRegOnly();
|
||||
}
|
||||
|
@ -55,12 +55,6 @@ maplecl::Option<bool> hotFix({"--hot-fix"},
|
||||
" --no-hot-fix\n",
|
||||
{cgCategory}, maplecl::DisableWith("--no-hot-fix"));
|
||||
|
||||
maplecl::Option<bool> objmap({"--objmap"},
|
||||
" --objmap"
|
||||
" \tCreate object maps (GCTIBs) inside the main output (.s) file\n"
|
||||
" --no-objmap\n",
|
||||
{cgCategory}, maplecl::DisableWith("--no-objmap"));
|
||||
|
||||
maplecl::Option<bool> yieldpoint({"--yieldpoint"},
|
||||
" --yieldpoint \tGenerate yieldpoints [default]\n"
|
||||
" --no-yieldpoint\n",
|
||||
|
@ -382,9 +382,6 @@ void CgFuncPM::DumpFuncCGIR(const CGFunc &f, const std::string &phaseName) const
|
||||
void CgFuncPM::EmitGlobalInfo(MIRModule &m) const
|
||||
{
|
||||
EmitDuplicatedAsmFunc(m);
|
||||
if (cgOptions->IsGenerateObjectMap()) {
|
||||
cg->GenerateObjectMaps(*beCommon);
|
||||
}
|
||||
cg->template Emit<CG::EmitterType::AsmEmitter>([](Emitter* emitter) {
|
||||
emitter->EmitGlobalVariable();
|
||||
emitter->CloseOutput();
|
||||
|
@ -79,15 +79,6 @@ void MemRWNodeHelper::GetMemRWNodeBaseInfo(const BaseNode &node, MIRFunction &mi
|
||||
|
||||
void MemRWNodeHelper::GetTrueMirInfo(const BECommon &beCommon)
|
||||
{
|
||||
// fixup mirType, primType and offset
|
||||
if (fieldId != 0) { // get true field type
|
||||
DEBUG_ASSERT((mirType->IsMIRStructType() || mirType->IsMIRUnionType()),
|
||||
"non-structure");
|
||||
auto *structType = static_cast<MIRStructType *>(mirType);
|
||||
mirType = structType->GetFieldType(fieldId);
|
||||
byteOffset = static_cast<int32>(structType->GetFieldOffsetFromBaseAddr(fieldId).byteOffset);
|
||||
isRefField = beCommon.IsRefField(*structType, fieldId);
|
||||
}
|
||||
primType = mirType->GetPrimType();
|
||||
// get mem size
|
||||
memSize = static_cast<uint32>(mirType->GetSize());
|
||||
@ -451,7 +442,6 @@ static void HandleReturn(StmtNode &stmt, CGFunc &cgFunc)
|
||||
DEBUG_ASSERT(retNode.NumOpnds() <= 1, "NYI return nodes number > 1");
|
||||
Operand *opnd = nullptr;
|
||||
if (retNode.NumOpnds() != 0) {
|
||||
CHECK_FATAL(!cgFunc.GetFunction().StructReturnedInRegs(), "NIY");
|
||||
opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0));
|
||||
}
|
||||
cgFunc.SelectReturn(opnd);
|
||||
|
@ -373,19 +373,8 @@ void Emitter::EmitAsmLabel(const MIRSymbol &mirSymbol, AsmLabel label)
|
||||
emit(align.c_str());
|
||||
#else /* ELF */
|
||||
/* output align, symbol name begin with "classInitProtectRegion" align is 4096 */
|
||||
MIRTypeKind kind = mirSymbol.GetType()->GetKind();
|
||||
MIRStorageClass storage = mirSymbol.GetStorageClass();
|
||||
if (symName.find("classInitProtectRegion") == 0) {
|
||||
Emit(4096); // symbol name begin with "classInitProtectRegion" align is 4096
|
||||
} else if (((kind == kTypeStruct) || (kind == kTypeClass) || (kind == kTypeArray) ||
|
||||
(kind == kTypeUnion)) &&
|
||||
((storage == kScGlobal) || (storage == kScPstatic) || (storage == kScFstatic))) {
|
||||
int32 align = Globals::GetInstance()->GetBECommon()->GetTypeAlign(mirType->GetTypeIndex());
|
||||
if (GetPointerSize() < align) {
|
||||
(void)Emit(std::to_string(align));
|
||||
} else {
|
||||
(void)Emit(std::to_string(k8ByteSize));
|
||||
}
|
||||
} else {
|
||||
(void)Emit(
|
||||
std::to_string(Globals::GetInstance()->GetBECommon()->GetTypeAlign(mirType->GetTypeIndex())));
|
||||
@ -397,22 +386,13 @@ void Emitter::EmitAsmLabel(const MIRSymbol &mirSymbol, AsmLabel label)
|
||||
case kAsmAlign: {
|
||||
uint8 align = mirSymbol.GetAttrs().GetAlignValue();
|
||||
if (align == 0) {
|
||||
if (mirSymbol.GetType()->GetKind() == kTypeStruct || mirSymbol.GetType()->GetKind() == kTypeClass ||
|
||||
mirSymbol.GetType()->GetKind() == kTypeArray || mirSymbol.GetType()->GetKind() == kTypeUnion) {
|
||||
if (GetCG()->GetTargetMachine()->isX8664()) {
|
||||
return;
|
||||
} else {
|
||||
align = Globals::GetInstance()->GetBECommon()->GetTypeAlign(mirSymbol.GetType()->GetTypeIndex());
|
||||
if (GetCG()->GetTargetMachine()->isAArch64() || GetCG()->GetTargetMachine()->isRiscV() ||
|
||||
GetCG()->GetTargetMachine()->isArm32() || GetCG()->GetTargetMachine()->isArk()) {
|
||||
if (CGOptions::IsArm64ilp32() && mirSymbol.GetType()->GetPrimType() == PTY_a32) {
|
||||
align = kAlignOfU8;
|
||||
}
|
||||
} else {
|
||||
align = Globals::GetInstance()->GetBECommon()->GetTypeAlign(mirSymbol.GetType()->GetTypeIndex());
|
||||
if (GetCG()->GetTargetMachine()->isAArch64() || GetCG()->GetTargetMachine()->isRiscV() ||
|
||||
GetCG()->GetTargetMachine()->isArm32() || GetCG()->GetTargetMachine()->isArk()) {
|
||||
if (CGOptions::IsArm64ilp32() && mirSymbol.GetType()->GetPrimType() == PTY_a32) {
|
||||
align = kAlignOfU8;
|
||||
} else {
|
||||
align = static_cast<uint8>(log2(align));
|
||||
}
|
||||
} else {
|
||||
align = static_cast<uint8>(log2(align));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -848,12 +828,6 @@ void Emitter::EmitScalarConstant(MIRConst &mirConst, bool newLine, bool flag32,
|
||||
if (symAddr.GetOffset() != 0) {
|
||||
(void)Emit(" + ").Emit(symAddr.GetOffset());
|
||||
}
|
||||
if (symAddr.GetFieldID() > 1) {
|
||||
MIRStructType *structType = static_cast<MIRStructType *>(symAddrSym->GetType());
|
||||
DEBUG_ASSERT(structType != nullptr, "EmitScalarConstant: non-zero fieldID for non-structure");
|
||||
(void)Emit(" + ").Emit(
|
||||
Globals::GetInstance()->GetBECommon()->GetFieldOffset(*structType, symAddr.GetFieldID()).first);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kConstAddrofFunc: {
|
||||
@ -1343,23 +1317,9 @@ int64 Emitter::GetFieldOffsetValue(const std::string &className, const MIRIntCon
|
||||
uint64 idx = static_cast<uint64>(intConst.GetExtValue());
|
||||
bool isDefTabIndex = idx & 0x1;
|
||||
int64 fieldIdx = idx >> 1;
|
||||
if (isDefTabIndex) {
|
||||
/* it's def table index. */
|
||||
return fieldIdx;
|
||||
} else {
|
||||
/* really offset. */
|
||||
uint8 charBitWidth = GetPrimTypeSize(PTY_i8) * kBitsPerByte;
|
||||
GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(className);
|
||||
auto it = strIdx2Type.find(strIdx);
|
||||
CHECK_FATAL(it->second != nullptr, "valid iterator check");
|
||||
DEBUG_ASSERT(it != strIdx2Type.end(), "Can not find type");
|
||||
MIRType &ty = *it->second;
|
||||
MIRStructType &structType = static_cast<MIRStructType &>(ty);
|
||||
std::pair<int32, int32> fieldOffsetPair =
|
||||
Globals::GetInstance()->GetBECommon()->GetFieldOffset(structType, fieldIdx);
|
||||
int64 fieldOffset = fieldOffsetPair.first * static_cast<int64>(charBitWidth) + fieldOffsetPair.second;
|
||||
return fieldOffset;
|
||||
}
|
||||
CHECK_FATAL(isDefTabIndex > 0, "isDefTabIndex > 0");
|
||||
/* it's def table index. */
|
||||
return fieldIdx;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
@ -1703,7 +1663,7 @@ void Emitter::EmitConstantTable(const MIRSymbol &mirSymbol, MIRConst &mirConst,
|
||||
} else { /* intconst */
|
||||
EmitIntConst(mirSymbol, aggConst, itabConflictIndex, strIdx2Type, i);
|
||||
}
|
||||
} else if (elemConst->GetType().GetKind() == kTypeArray || elemConst->GetType().GetKind() == kTypeStruct) {
|
||||
} else if (elemConst->GetType().GetKind() == kTypeArray) {
|
||||
if (StringUtils::StartsWith(mirSymbol.GetName(), namemangler::kOffsetTabStr) && (i == 0 || i == 1)) {
|
||||
/* EmitOffsetValueTable */
|
||||
#ifdef USE_32BIT_REF
|
||||
@ -1761,9 +1721,6 @@ void Emitter::EmitArrayConstant(MIRConst &mirConst)
|
||||
}
|
||||
} else if (elemConst->GetType().GetKind() == kTypeArray) {
|
||||
EmitArrayConstant(*elemConst);
|
||||
} else if (elemConst->GetType().GetKind() == kTypeStruct || elemConst->GetType().GetKind() == kTypeClass ||
|
||||
elemConst->GetType().GetKind() == kTypeUnion) {
|
||||
EmitStructConstant(*elemConst);
|
||||
} else if (elemConst->GetKind() == kConstAddrofFunc) {
|
||||
EmitScalarConstant(*elemConst);
|
||||
} else {
|
||||
@ -1792,125 +1749,6 @@ void Emitter::EmitArrayConstant(MIRConst &mirConst)
|
||||
#endif
|
||||
}
|
||||
|
||||
void Emitter::EmitStructConstant(MIRConst &mirConst)
|
||||
{
|
||||
#ifdef ARK_LITECG_DEBUG
|
||||
uint32_t subStructFieldCounts = 0;
|
||||
EmitStructConstant(mirConst, subStructFieldCounts);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Emitter::EmitStructConstant(MIRConst &mirConst, uint32 &subStructFieldCounts)
|
||||
{
|
||||
#ifdef ARK_LITECG_DEBUG
|
||||
StructEmitInfo *sEmitInfo = cg->GetMIRModule()->GetMemPool()->New<StructEmitInfo>();
|
||||
CHECK_FATAL(sEmitInfo != nullptr, "create a new struct emit info failed in Emitter::EmitStructConstant");
|
||||
MIRType &mirType = mirConst.GetType();
|
||||
MIRAggConst &structCt = static_cast<MIRAggConst &>(mirConst);
|
||||
MIRStructType &structType = static_cast<MIRStructType &>(mirType);
|
||||
auto structPack = static_cast<uint8>(structType.GetTypeAttrs().GetPack());
|
||||
/* all elements of struct. */
|
||||
uint8 num;
|
||||
if (structType.GetKind() == kTypeUnion) {
|
||||
num = 1;
|
||||
} else {
|
||||
num = static_cast<uint8>(structType.GetFieldsSize());
|
||||
}
|
||||
BECommon *beCommon = Globals::GetInstance()->GetBECommon();
|
||||
/* total size of emitted elements size. */
|
||||
uint32 size = beCommon->GetTypeSize(structType.GetTypeIndex());
|
||||
uint32 fieldIdx = 1;
|
||||
if (structType.GetKind() == kTypeUnion) {
|
||||
fieldIdx = structCt.GetFieldIdItem(0);
|
||||
}
|
||||
for (uint32 i = 0; i < num; ++i) {
|
||||
if (((i + 1) == num) && cg->GetMIRModule()->GetSrcLang() == kSrcLangC) {
|
||||
isFlexibleArray = beCommon->GetHasFlexibleArray(mirType.GetTypeIndex().GetIdx());
|
||||
arraySize = 0;
|
||||
}
|
||||
MIRConst *elemConst;
|
||||
if (structType.GetKind() == kTypeStruct) {
|
||||
elemConst = structCt.GetAggConstElement(i + 1);
|
||||
} else {
|
||||
elemConst = structCt.GetAggConstElement(fieldIdx);
|
||||
}
|
||||
MIRType *elemType = structType.GetElemType(i);
|
||||
if (structType.GetKind() == kTypeUnion) {
|
||||
CHECK_NULL_FATAL(elemConst);
|
||||
elemType = &(elemConst->GetType());
|
||||
}
|
||||
MIRType *nextElemType = nullptr;
|
||||
if (i != static_cast<uint32>(num - 1)) {
|
||||
nextElemType = structType.GetElemType(i + 1);
|
||||
}
|
||||
uint64 elemSize = beCommon->GetTypeSize(elemType->GetTypeIndex());
|
||||
uint8 charBitWidth = GetPrimTypeSize(PTY_i8) * kBitsPerByte;
|
||||
if (elemType->GetKind() == kTypeBitField) {
|
||||
if (elemConst == nullptr) {
|
||||
MIRIntConst *zeroFill = GlobalTables::GetIntConstTable().GetOrCreateIntConst(0, *elemType);
|
||||
elemConst = zeroFill;
|
||||
}
|
||||
std::pair<int32_t, int32_t> fieldOffsetPair = beCommon->GetFieldOffset(structType, fieldIdx);
|
||||
uint64_t fieldOffset = static_cast<uint64_t>(static_cast<int64_t>(fieldOffsetPair.first)) *
|
||||
static_cast<uint64_t>(charBitWidth) +
|
||||
static_cast<uint64_t>(static_cast<int64_t>(fieldOffsetPair.second));
|
||||
EmitBitFieldConstant(*sEmitInfo, *elemConst, nextElemType, fieldOffset);
|
||||
} else {
|
||||
if (elemConst != nullptr) {
|
||||
if (IsPrimitiveScalar(elemType->GetPrimType())) {
|
||||
EmitScalarConstant(*elemConst, true, false, true);
|
||||
} else if (elemType->GetKind() == kTypeArray) {
|
||||
if (elemType->GetSize() != 0) {
|
||||
EmitArrayConstant(*elemConst);
|
||||
}
|
||||
} else if ((elemType->GetKind() == kTypeStruct) || (elemType->GetKind() == kTypeClass) ||
|
||||
(elemType->GetKind() == kTypeUnion)) {
|
||||
EmitStructConstant(*elemConst, subStructFieldCounts);
|
||||
fieldIdx += subStructFieldCounts;
|
||||
} else {
|
||||
DEBUG_ASSERT(false, "should not run here");
|
||||
}
|
||||
} else {
|
||||
EmitNullConstant(elemSize);
|
||||
}
|
||||
sEmitInfo->IncreaseTotalSize(elemSize);
|
||||
sEmitInfo->SetNextFieldOffset(sEmitInfo->GetTotalSize() * charBitWidth);
|
||||
}
|
||||
|
||||
if (nextElemType != nullptr && kTypeBitField != nextElemType->GetKind()) {
|
||||
DEBUG_ASSERT(i < static_cast<uint32>(num - 1), "NYI");
|
||||
uint8 nextAlign = Globals::GetInstance()->GetBECommon()->GetTypeAlign(nextElemType->GetTypeIndex());
|
||||
auto fieldAttr = structType.GetFields()[i + 1].second.second;
|
||||
nextAlign = fieldAttr.IsPacked() ? 1 : std::min(nextAlign, structPack);
|
||||
DEBUG_ASSERT(nextAlign != 0, "expect non-zero");
|
||||
/* append size, append 0 when align need. */
|
||||
uint64 totalSize = sEmitInfo->GetTotalSize();
|
||||
uint64 psize = (totalSize % nextAlign == 0) ? 0 : (nextAlign - (totalSize % nextAlign));
|
||||
if (psize != 0) {
|
||||
EmitNullConstant(psize);
|
||||
sEmitInfo->IncreaseTotalSize(psize);
|
||||
sEmitInfo->SetNextFieldOffset(sEmitInfo->GetTotalSize() * charBitWidth);
|
||||
}
|
||||
/* element is uninitialized, emit null constant. */
|
||||
}
|
||||
fieldIdx++;
|
||||
}
|
||||
if (structType.GetKind() == kTypeStruct) {
|
||||
/* The reason of subtracting one is that fieldIdx adds one at the end of the cycle. */
|
||||
CHECK_FATAL(fieldIdx > 0, "must not be zero");
|
||||
subStructFieldCounts = fieldIdx - 1;
|
||||
} else if (structType.GetKind() == kTypeUnion) {
|
||||
subStructFieldCounts = static_cast<uint32>(beCommon->GetStructFieldCount(structType.GetTypeIndex()));
|
||||
}
|
||||
|
||||
isFlexibleArray = false;
|
||||
uint64 opSize = size - sEmitInfo->GetTotalSize();
|
||||
if (opSize != 0) {
|
||||
EmitNullConstant(opSize);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* BlockMarker is for Debugging/Profiling */
|
||||
void Emitter::EmitBlockMarker(const std::string &markerName, const std::string §ionName, bool withAddr,
|
||||
const std::string &addrName)
|
||||
@ -2314,10 +2152,6 @@ void Emitter::EmitLocalVariable(const CGFunc &cgFunc)
|
||||
MIRConst *ct = st->GetKonst();
|
||||
if (ct == nullptr) {
|
||||
EmitAsmLabel(*st, kAsmComm);
|
||||
} else if (kTypeStruct == ty->GetKind() || kTypeUnion == ty->GetKind() ||
|
||||
kTypeClass == ty->GetKind()) {
|
||||
EmitAsmLabel(*st, kAsmSyname);
|
||||
EmitStructConstant(*ct);
|
||||
} else if (kTypeArray == ty->GetKind()) {
|
||||
if (ty->GetSize() != 0) {
|
||||
EmitAsmLabel(*st, kAsmSyname);
|
||||
@ -2727,13 +2561,6 @@ void Emitter::EmitGlobalVariable()
|
||||
} else {
|
||||
EmitArrayConstant(*mirConst);
|
||||
}
|
||||
} else if (mirType->GetKind() == kTypeStruct || mirType->GetKind() == kTypeClass ||
|
||||
mirType->GetKind() == kTypeUnion) {
|
||||
if (mirSymbol->HasAddrOfValues()) {
|
||||
EmitConstantTable(*mirSymbol, *mirConst, strIdx2Type);
|
||||
} else {
|
||||
EmitStructConstant(*mirConst);
|
||||
}
|
||||
} else {
|
||||
DEBUG_ASSERT(false, "NYI");
|
||||
}
|
||||
@ -2769,10 +2596,6 @@ void Emitter::EmitGlobalVariable()
|
||||
} else if (kTypeArray == mirType->GetKind()) {
|
||||
EmitAsmLabel(*mirSymbol, kAsmSyname);
|
||||
EmitArrayConstant(*ct);
|
||||
} else if (kTypeStruct == mirType->GetKind() || kTypeClass == mirType->GetKind() ||
|
||||
kTypeUnion == mirType->GetKind()) {
|
||||
EmitAsmLabel(*mirSymbol, kAsmSyname);
|
||||
EmitStructConstant(*ct);
|
||||
} else {
|
||||
CHECK_FATAL(0, "Unknown type in Global pstatic");
|
||||
}
|
||||
|
@ -616,12 +616,6 @@ MirTypeInfo MPISel::GetMirTypeInfoFormFieldIdAndMirType(FieldID fieldId, MIRType
|
||||
{
|
||||
MirTypeInfo mirTypeInfo;
|
||||
/* fixup primType and offset */
|
||||
if (fieldId != 0) {
|
||||
DEBUG_ASSERT((mirType->IsMIRStructType() || mirType->IsMIRUnionType()), "non-structure");
|
||||
MIRStructType *structType = static_cast<MIRStructType *>(mirType);
|
||||
mirType = structType->GetFieldType(fieldId);
|
||||
mirTypeInfo.offset = static_cast<uint64_t>(cgFunc->GetBecommon().GetFieldOffset(*structType, fieldId).first);
|
||||
}
|
||||
mirTypeInfo.primType = mirType->GetPrimType();
|
||||
// aggSize for AggType
|
||||
if (mirTypeInfo.primType == maple::PTY_agg) {
|
||||
|
@ -26,15 +26,8 @@ MemOperand &X64MPIsel::GetOrCreateMemOpndFromSymbol(const MIRSymbol &symbol, Fie
|
||||
{
|
||||
PrimType symType;
|
||||
int32 fieldOffset = 0;
|
||||
if (fieldId == 0) {
|
||||
symType = symbol.GetType()->GetPrimType();
|
||||
} else {
|
||||
MIRType *mirType = symbol.GetType();
|
||||
DEBUG_ASSERT((mirType->IsMIRStructType() || mirType->IsMIRUnionType()), "non-structure");
|
||||
MIRStructType *structType = static_cast<MIRStructType *>(mirType);
|
||||
symType = structType->GetFieldType(fieldId)->GetPrimType();
|
||||
fieldOffset = static_cast<int32>(cgFunc->GetBecommon().GetFieldOffset(*structType, fieldId).first);
|
||||
}
|
||||
CHECK_FATAL(fieldId == 0, "fieldId must be 0");
|
||||
symType = symbol.GetType()->GetPrimType();
|
||||
uint32 opndSz = (symType == PTY_agg) ? k64BitSize : GetPrimTypeBitSize(symType);
|
||||
return GetOrCreateMemOpndFromSymbol(symbol, opndSz, fieldOffset);
|
||||
}
|
||||
@ -79,45 +72,13 @@ void X64MPIsel::SelectReturn(NaryStmtNode &retNode, Operand &opnd)
|
||||
return;
|
||||
}
|
||||
std::vector<RegOperand *> retRegs;
|
||||
if (!cgFunc->GetFunction().StructReturnedInRegs() || retNode.Opnd(0)->GetOpCode() == OP_constval) {
|
||||
PrimType oriPrimType = retMech.GetPrimTypeOfReg0();
|
||||
regno_t retReg = retMech.GetReg0();
|
||||
DEBUG_ASSERT(retReg != kRinvalid, "NIY");
|
||||
RegOperand &retOpnd = cgFunc->GetOpndBuilder()->CreatePReg(retReg, GetPrimTypeBitSize(oriPrimType),
|
||||
cgFunc->GetRegTyFromPrimTy(oriPrimType));
|
||||
retRegs.push_back(&retOpnd);
|
||||
SelectCopy(retOpnd, opnd, oriPrimType, retNode.Opnd(0)->GetPrimType());
|
||||
} else {
|
||||
CHECK_FATAL(opnd.IsMemoryAccessOperand(), "NIY");
|
||||
MemOperand &memOpnd = static_cast<MemOperand &>(opnd);
|
||||
ImmOperand *offsetOpnd = memOpnd.GetOffsetOperand();
|
||||
RegOperand *baseOpnd = memOpnd.GetBaseRegister();
|
||||
|
||||
PrimType oriPrimType0 = retMech.GetPrimTypeOfReg0();
|
||||
regno_t retReg0 = retMech.GetReg0();
|
||||
DEBUG_ASSERT(retReg0 != kRinvalid, "NIY");
|
||||
RegOperand &retOpnd0 = cgFunc->GetOpndBuilder()->CreatePReg(retReg0, GetPrimTypeBitSize(oriPrimType0),
|
||||
cgFunc->GetRegTyFromPrimTy(oriPrimType0));
|
||||
MemOperand &rhsMemOpnd0 = cgFunc->GetOpndBuilder()->CreateMem(GetPrimTypeBitSize(oriPrimType0));
|
||||
rhsMemOpnd0.SetBaseRegister(*baseOpnd);
|
||||
rhsMemOpnd0.SetOffsetOperand(*offsetOpnd);
|
||||
retRegs.push_back(&retOpnd0);
|
||||
SelectCopy(retOpnd0, rhsMemOpnd0, oriPrimType0);
|
||||
|
||||
regno_t retReg1 = retMech.GetReg1();
|
||||
if (retReg1 != kRinvalid) {
|
||||
PrimType oriPrimType1 = retMech.GetPrimTypeOfReg1();
|
||||
RegOperand &retOpnd1 = cgFunc->GetOpndBuilder()->CreatePReg(retReg1, GetPrimTypeBitSize(oriPrimType1),
|
||||
cgFunc->GetRegTyFromPrimTy(oriPrimType1));
|
||||
MemOperand &rhsMemOpnd1 = cgFunc->GetOpndBuilder()->CreateMem(GetPrimTypeBitSize(oriPrimType1));
|
||||
ImmOperand &newOffsetOpnd = static_cast<ImmOperand &>(*offsetOpnd->Clone(*cgFunc->GetMemoryPool()));
|
||||
newOffsetOpnd.SetValue(newOffsetOpnd.GetValue() + GetPrimTypeSize(oriPrimType0));
|
||||
rhsMemOpnd1.SetBaseRegister(*baseOpnd);
|
||||
rhsMemOpnd1.SetOffsetOperand(newOffsetOpnd);
|
||||
retRegs.push_back(&retOpnd1);
|
||||
SelectCopy(retOpnd1, rhsMemOpnd1, oriPrimType1);
|
||||
}
|
||||
}
|
||||
PrimType oriPrimType = retMech.GetPrimTypeOfReg0();
|
||||
regno_t retReg = retMech.GetReg0();
|
||||
DEBUG_ASSERT(retReg != kRinvalid, "NIY");
|
||||
RegOperand &retOpnd = cgFunc->GetOpndBuilder()->CreatePReg(retReg, GetPrimTypeBitSize(oriPrimType),
|
||||
cgFunc->GetRegTyFromPrimTy(oriPrimType));
|
||||
retRegs.push_back(&retOpnd);
|
||||
SelectCopy(retOpnd, opnd, oriPrimType, retNode.Opnd(0)->GetPrimType());
|
||||
/* for optimization ,insert pseudo ret ,in case rax,rdx is removed*/
|
||||
SelectPseduoForReturn(retRegs);
|
||||
}
|
||||
|
@ -79,9 +79,6 @@ bool X64CG::IsExclusiveFunc(MIRFunction &mirFunc)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* NOTE: Consider making be_common a field of CG. */
|
||||
void X64CG::GenerateObjectMaps(BECommon &beCommon) {}
|
||||
|
||||
/* Used for GCTIB pattern merging */
|
||||
std::string X64CG::FindGCTIBPatternName(const std::string &name) const
|
||||
{
|
||||
|
@ -28,15 +28,14 @@ uint8 X64Emitter::GetSymbolAlign(const MIRSymbol &mirSymbol, bool isComm)
|
||||
MIRTypeKind kind = mirSymbol.GetType()->GetKind();
|
||||
if (isComm) {
|
||||
MIRStorageClass storage = mirSymbol.GetStorageClass();
|
||||
if (((kind == kTypeStruct) || (kind == kTypeClass) || (kind == kTypeArray) || (kind == kTypeUnion)) &&
|
||||
((storage == kScGlobal) || (storage == kScPstatic) || (storage == kScFstatic)) &&
|
||||
if ((kind == kTypeArray) && ((storage == kScGlobal) || (storage == kScPstatic) || (storage == kScFstatic)) &&
|
||||
alignInByte < kSizeOfPTR) {
|
||||
alignInByte = kQ;
|
||||
return alignInByte;
|
||||
}
|
||||
}
|
||||
if (alignInByte == 0) {
|
||||
if (kind == kTypeStruct || kind == kTypeClass || kind == kTypeArray || kind == kTypeUnion) {
|
||||
if (kind == kTypeArray) {
|
||||
return alignInByte;
|
||||
} else {
|
||||
alignInByte = Globals::GetInstance()->GetBECommon()->GetTypeAlign(mirSymbol.GetType()->GetTypeIndex());
|
||||
@ -1544,104 +1543,6 @@ void X64Emitter::EmitFunctionFoot(CGFunc &cgFunc)
|
||||
assmbler.EmitFunctionFoot(symIdx, funcAttr);
|
||||
}
|
||||
|
||||
uint64 X64Emitter::EmitStructure(MIRConst &mirConst, CG &cg, bool belongsToDataSec)
|
||||
{
|
||||
uint32 subStructFieldCounts = 0;
|
||||
uint64 valueSize = EmitStructure(mirConst, cg, subStructFieldCounts, belongsToDataSec);
|
||||
return valueSize;
|
||||
}
|
||||
|
||||
uint64 X64Emitter::EmitStructure(MIRConst &mirConst, CG &cg, uint32 &subStructFieldCounts, bool belongsToDataSec)
|
||||
{
|
||||
uint64 valueSize = 0;
|
||||
#ifdef ARK_LITECG_DEBUG
|
||||
StructEmitInfo *sEmitInfo = cg.GetMIRModule()->GetMemPool()->New<StructEmitInfo>();
|
||||
CHECK_NULL_FATAL(sEmitInfo);
|
||||
MIRType &mirType = mirConst.GetType();
|
||||
MIRAggConst &structCt = static_cast<MIRAggConst &>(mirConst);
|
||||
MIRStructType &structType = static_cast<MIRStructType &>(mirType);
|
||||
uint8 structPack = static_cast<uint8>(structType.GetTypeAttrs().GetPack());
|
||||
MIRTypeKind structKind = structType.GetKind();
|
||||
/* all elements of struct. */
|
||||
uint8 num = structKind == kTypeUnion ? 1 : static_cast<uint8>(structType.GetFieldsSize());
|
||||
BECommon *beCommon = Globals::GetInstance()->GetBECommon();
|
||||
/* total size of emitted elements size. */
|
||||
uint64 sizeInByte = GetSymbolSize(structType.GetTypeIndex());
|
||||
uint32 fieldIdx = structKind == kTypeUnion ? structCt.GetFieldIdItem(0) : 1;
|
||||
for (uint32 i = 0; i < num; ++i) {
|
||||
MIRConst *elemConst =
|
||||
structKind == kTypeStruct ? structCt.GetAggConstElement(i + 1) : structCt.GetAggConstElement(fieldIdx);
|
||||
DEBUG_ASSERT(elemConst != nullptr, "elemConst should not be nullptr");
|
||||
MIRType *elemType = structKind == kTypeUnion ? &(elemConst->GetType()) : structType.GetElemType(i);
|
||||
MIRType *nextElemType = i != static_cast<uint32>(num - 1) ? structType.GetElemType(i + 1) : nullptr;
|
||||
uint64 elemSize = GetSymbolSize(elemType->GetTypeIndex());
|
||||
uint8 charBitWidth = GetPrimTypeSize(PTY_i8) * k8Bits;
|
||||
MIRTypeKind elemKind = elemType->GetKind();
|
||||
if (elemKind == kTypeBitField) {
|
||||
if (elemConst == nullptr) {
|
||||
MIRIntConst *zeroFill = GlobalTables::GetIntConstTable().GetOrCreateIntConst(0, *elemType);
|
||||
elemConst = zeroFill;
|
||||
}
|
||||
pair<int32, int32> fieldOffsetPair = beCommon->GetFieldOffset(structType, fieldIdx);
|
||||
uint64 fieldOffset =
|
||||
static_cast<uint64>(static_cast<int64>(fieldOffsetPair.first)) * static_cast<uint64>(charBitWidth) +
|
||||
static_cast<uint64>(static_cast<int64>(fieldOffsetPair.second));
|
||||
EmitBitField(*sEmitInfo, *elemConst, nextElemType, fieldOffset);
|
||||
} else {
|
||||
if (elemConst != nullptr) {
|
||||
if (IsPrimitiveScalar(elemType->GetPrimType())) {
|
||||
valueSize += EmitSingleElement(*elemConst, belongsToDataSec, true);
|
||||
} else if (elemKind == kTypeArray) {
|
||||
if (elemType->GetSize() != 0) {
|
||||
valueSize += EmitArray(*elemConst, cg, belongsToDataSec);
|
||||
}
|
||||
} else if (elemKind == kTypeStruct || elemKind == kTypeClass || elemKind == kTypeUnion) {
|
||||
valueSize += EmitStructure(*elemConst, cg, subStructFieldCounts, belongsToDataSec);
|
||||
fieldIdx += subStructFieldCounts;
|
||||
} else {
|
||||
DEBUG_ASSERT(false, "should not run here");
|
||||
}
|
||||
} else {
|
||||
assmbler.EmitNull(elemSize);
|
||||
}
|
||||
sEmitInfo->IncreaseTotalSize(elemSize);
|
||||
sEmitInfo->SetNextFieldOffset(sEmitInfo->GetTotalSize() * charBitWidth);
|
||||
}
|
||||
|
||||
if (nextElemType != nullptr && nextElemType->GetKind() != kTypeBitField) {
|
||||
DEBUG_ASSERT(i < static_cast<uint32>(num - 1), "NYI");
|
||||
uint8 nextAlign = Globals::GetInstance()->GetBECommon()->GetTypeAlign(nextElemType->GetTypeIndex());
|
||||
auto fieldAttr = structType.GetFields()[i + 1].second.second;
|
||||
nextAlign = fieldAttr.IsPacked() ? 1 : min(nextAlign, structPack);
|
||||
DEBUG_ASSERT(nextAlign != 0, "expect non-zero");
|
||||
/* append size, append 0 when align need. */
|
||||
uint64 totalSize = sEmitInfo->GetTotalSize();
|
||||
uint64 psize = (totalSize % nextAlign == 0) ? 0 : (nextAlign - (totalSize % nextAlign));
|
||||
/* element is uninitialized, emit null constant. */
|
||||
if (psize != 0) {
|
||||
assmbler.EmitNull(psize);
|
||||
sEmitInfo->IncreaseTotalSize(psize);
|
||||
sEmitInfo->SetNextFieldOffset(sEmitInfo->GetTotalSize() * charBitWidth);
|
||||
}
|
||||
}
|
||||
fieldIdx++;
|
||||
}
|
||||
if (structType.GetKind() == kTypeStruct) {
|
||||
/* The reason of subtracting one is that fieldIdx adds one at the end of the cycle. */
|
||||
DEBUG_ASSERT(fieldIdx > 0, "must not be zero");
|
||||
subStructFieldCounts = fieldIdx - 1;
|
||||
} else if (structType.GetKind() == kTypeUnion) {
|
||||
subStructFieldCounts = static_cast<uint32>(beCommon->GetStructFieldCount(structType.GetTypeIndex()));
|
||||
}
|
||||
|
||||
uint64 opSize = sizeInByte - sEmitInfo->GetTotalSize();
|
||||
if (opSize != 0) {
|
||||
assmbler.EmitNull(opSize);
|
||||
}
|
||||
#endif
|
||||
return valueSize;
|
||||
}
|
||||
|
||||
uint64 X64Emitter::EmitArray(MIRConst &mirConst, CG &cg, bool belongsToDataSec)
|
||||
{
|
||||
uint64 valueSize = 0;
|
||||
@ -1680,9 +1581,6 @@ uint64 X64Emitter::EmitArray(MIRConst &mirConst, CG &cg, bool belongsToDataSec)
|
||||
}
|
||||
} else if (elemConst->GetType().GetKind() == kTypeArray) {
|
||||
valueSize += EmitArray(*elemConst, cg, belongsToDataSec);
|
||||
} else if (elemConst->GetType().GetKind() == kTypeStruct || elemConst->GetType().GetKind() == kTypeClass ||
|
||||
elemConst->GetType().GetKind() == kTypeUnion) {
|
||||
valueSize += EmitStructure(*elemConst, cg);
|
||||
} else if (elemConst->GetKind() == kConstAddrofFunc) {
|
||||
valueSize += EmitSingleElement(*elemConst, belongsToDataSec);
|
||||
} else {
|
||||
@ -1730,11 +1628,6 @@ void X64Emitter::EmitAddrofElement(MIRConst &mirConst, bool belongsToDataSec)
|
||||
if (symAddr.GetOffset() != 0) {
|
||||
symAddrOfs = symAddr.GetOffset();
|
||||
}
|
||||
if (symAddr.GetFieldID() > 1) {
|
||||
MIRStructType *structType = static_cast<MIRStructType *>(symAddrSym->GetType());
|
||||
DEBUG_ASSERT(structType != nullptr, "EmitScalarConstant: non-zero fieldID for non-structure");
|
||||
structFieldOfs = Globals::GetInstance()->GetBECommon()->GetFieldOffset(*structType, symAddr.GetFieldID()).first;
|
||||
}
|
||||
assmbler.StoreNameIntoSymMap(symIdx, addrName);
|
||||
assmbler.EmitAddrValue(symIdx, symAddrOfs, structFieldOfs, belongsToDataSec);
|
||||
#endif
|
||||
@ -1939,9 +1832,7 @@ void X64Emitter::EmitLocalVariable(CGFunc &cgFunc)
|
||||
(ct->GetKind() == maple::kConstDoubleConst || ct->GetKind() == maple::kConstFloatConst);
|
||||
auto secType = isFloatTy ? kSText : kSData;
|
||||
assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSALocal, secType);
|
||||
if (kind == kTypeStruct || kind == kTypeUnion || kind == kTypeClass) {
|
||||
valueSize = EmitStructure(*ct, *cgFunc.GetCG());
|
||||
} else if (kind == kTypeArray) {
|
||||
if (kind == kTypeArray) {
|
||||
valueSize = EmitArray(*ct, *cgFunc.GetCG());
|
||||
} else if (isFloatTy) {
|
||||
MIRType &elmType = ct->GetType();
|
||||
@ -2033,9 +1924,6 @@ void X64Emitter::EmitGlobalVariable(CG &cg)
|
||||
} else if (kind == kTypeArray) {
|
||||
CHECK_FATAL(!mirSymbol->HasAddrOfValues(), "EmitGlobalVariable: need EmitConstantTable");
|
||||
valueSize = EmitArray(*mirConst, cg);
|
||||
} else if (kind == kTypeStruct || kind == kTypeClass || kind == kTypeUnion) {
|
||||
CHECK_FATAL(!mirSymbol->HasAddrOfValues(), "EmitGlobalVariable: need EmitConstantTable");
|
||||
EmitStructure(*mirConst, cg);
|
||||
} else {
|
||||
DEBUG_ASSERT(false, "EmitGlobalVariable: Unknown mirKind");
|
||||
}
|
||||
@ -2063,8 +1951,6 @@ void X64Emitter::EmitGlobalVariable(CG &cg)
|
||||
}
|
||||
} else if (kind == kTypeArray) {
|
||||
(void)EmitArray(*mirConst, cg, false);
|
||||
} else if (kind == kTypeStruct || kind == kTypeUnion || kind == kTypeClass) {
|
||||
(void)EmitStructure(*mirConst, cg);
|
||||
} else {
|
||||
FATAL(kLncFatal, "Unknown type in Global pstatic");
|
||||
}
|
||||
|
@ -48,32 +48,12 @@ uint32 X64MemLayout::ComputeStackSpaceRequirementForCall(StmtNode &stmt, int32 &
|
||||
CHECK_NULL_FATAL(be.GetMIRModule().CurFunction());
|
||||
MIRSymbol *sym = be.GetMIRModule().CurFunction()->GetLocalOrGlobalSymbol(dread->GetStIdx());
|
||||
ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx());
|
||||
if (dread->GetFieldID() != 0) {
|
||||
DEBUG_ASSERT(ty->GetKind() == kTypeStruct || ty->GetKind() == kTypeClass ||
|
||||
ty->GetKind() == kTypeUnion,
|
||||
"expect struct or class");
|
||||
if (ty->GetKind() == kTypeStruct || ty->GetKind() == kTypeUnion) {
|
||||
ty = static_cast<MIRStructType *>(ty)->GetFieldType(dread->GetFieldID());
|
||||
} else {
|
||||
ty = static_cast<MIRClassType *>(ty)->GetFieldType(dread->GetFieldID());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* OP_iread */
|
||||
IreadNode *iread = static_cast<IreadNode *>(opnd);
|
||||
ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx());
|
||||
DEBUG_ASSERT(ty->GetKind() == kTypePointer, "expect pointer");
|
||||
ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast<MIRPtrType *>(ty)->GetPointedTyIdx());
|
||||
if (iread->GetFieldID() != 0) {
|
||||
DEBUG_ASSERT(ty->GetKind() == kTypeStruct || ty->GetKind() == kTypeClass ||
|
||||
ty->GetKind() == kTypeUnion,
|
||||
"expect struct or class");
|
||||
if (ty->GetKind() == kTypeStruct || ty->GetKind() == kTypeUnion) {
|
||||
ty = static_cast<MIRStructType *>(ty)->GetFieldType(iread->GetFieldID());
|
||||
} else {
|
||||
ty = static_cast<MIRClassType *>(ty)->GetFieldType(iread->GetFieldID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CCLocInfo ploc;
|
||||
|
@ -98,10 +98,6 @@ LiteCGTypeKind LMIRBuilder::LiteCGGetTypeKind(Type *type) const
|
||||
return kLiteCGTypeFArray;
|
||||
case MIRTypeKind::kTypeJArray:
|
||||
return kLiteCGTypeJArray;
|
||||
case MIRTypeKind::kTypeStruct:
|
||||
return kLiteCGTypeStruct;
|
||||
case MIRTypeKind::kTypeUnion:
|
||||
return kLiteCGTypeUnion;
|
||||
case MIRTypeKind::kTypeClass:
|
||||
return kLiteCGTypeClass;
|
||||
case MIRTypeKind::kTypeInterface:
|
||||
@ -170,33 +166,6 @@ bool LMIRBuilder::IsHeapPointerType(Type *mirType) const
|
||||
return mirType->GetPrimType() == PTY_ref;
|
||||
}
|
||||
|
||||
Type *LMIRBuilder::CreateStructTypeInternal(const String &name,
|
||||
std::vector<std::pair<std::string_view, Type *>> &fields_)
|
||||
{
|
||||
FieldVector parentFields; // parentFields not used.
|
||||
// not sure about the cost
|
||||
FieldVector fields;
|
||||
for (auto field : fields_) {
|
||||
auto strIdx = mirBuilder.GetOrCreateStringIndex(field.first.data());
|
||||
fields.push_back(FieldPair(strIdx, TyIdxFieldAttrPair(field.second->GetTypeIndex(), FieldAttrs())));
|
||||
}
|
||||
auto type = GlobalTables::GetTypeTable().GetOrCreateStructType(name, fields, parentFields, module);
|
||||
return type;
|
||||
}
|
||||
|
||||
Type *LMIRBuilder::GetStructType(const String &name)
|
||||
{
|
||||
GStrIdx strIdx = GlobalTables::GetStrTable().GetStrIdxFromName(name);
|
||||
TyIdx typeIdx = GlobalTables::GetTypeNameTable().GetTyIdxFromGStrIdx(strIdx);
|
||||
MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(typeIdx);
|
||||
return type;
|
||||
}
|
||||
|
||||
StructConst &LMIRBuilder::CreateStructConstInternal(StructType *type)
|
||||
{
|
||||
return *module.GetMemPool()->New<StructConst>(module, *type);
|
||||
}
|
||||
|
||||
ArrayConst &LMIRBuilder::CreateArrayConstInternal(ArrayType *type)
|
||||
{
|
||||
return *module.GetMemPool()->New<ArrayConst>(module, *type);
|
||||
@ -601,14 +570,6 @@ Expr LMIRBuilder::IntrinsicOp(IntrinsicId id, Type *type, Args &args_)
|
||||
return Expr(mirBuilder.CreateExprIntrinsicop(func, OP_intrinsicop, *type, args), type);
|
||||
}
|
||||
|
||||
Expr LMIRBuilder::DreadWithField(Var &var, FieldId id)
|
||||
{
|
||||
auto *type = var.GetType();
|
||||
CHECK_FATAL(type->IsStructType(), "DreadWithField: must be a struct type!");
|
||||
auto *fldType = static_cast<MIRStructType *>(type)->GetFieldType(id);
|
||||
return Expr(mirBuilder.CreateExprDread(*fldType, id, var), fldType);
|
||||
}
|
||||
|
||||
Expr LMIRBuilder::Iread(Type *type, Expr addr, Type *baseType, FieldId fieldId)
|
||||
{
|
||||
return Expr(mirBuilder.CreateExprIread(*type, *baseType, fieldId, addr.GetNode()), type);
|
||||
|
@ -345,30 +345,8 @@ public:
|
||||
MIRType *GetOrCreateJarrayType(const MIRType &elem);
|
||||
MIRType *GetOrCreateFunctionType(const TyIdx &, const std::vector<TyIdx> &, const std::vector<TypeAttrs> &,
|
||||
bool isVarg = false, const TypeAttrs &retAttrs = TypeAttrs());
|
||||
MIRType *GetOrCreateStructType(const std::string &name, const FieldVector &fields, const FieldVector &prntFields,
|
||||
MIRModule &module)
|
||||
{
|
||||
return GetOrCreateStructOrUnion(name, fields, prntFields, module);
|
||||
}
|
||||
|
||||
MIRType *GetOrCreateUnionType(const std::string &name, const FieldVector &fields, const FieldVector &parentFields,
|
||||
MIRModule &module)
|
||||
{
|
||||
return GetOrCreateStructOrUnion(name, fields, parentFields, module, false);
|
||||
}
|
||||
|
||||
MIRType *GetOrCreateClassType(const std::string &name, MIRModule &module)
|
||||
{
|
||||
return GetOrCreateClassOrInterface(name, module, true);
|
||||
}
|
||||
|
||||
MIRType *GetOrCreateInterfaceType(const std::string &name, MIRModule &module)
|
||||
{
|
||||
return GetOrCreateClassOrInterface(name, module, false);
|
||||
}
|
||||
|
||||
void PushIntoFieldVector(FieldVector &fields, const std::string &name, const MIRType &type);
|
||||
void AddFieldToStructType(MIRStructType &structType, const std::string &fieldName, const MIRType &fieldType);
|
||||
|
||||
TyIdx lastDefaultTyIdx;
|
||||
|
||||
@ -408,10 +386,6 @@ private:
|
||||
|
||||
void CreateMirTypeNodeAt(MIRType &pType, TyIdx tyIdxUsed, MIRModule *module, bool isObject, bool isIncomplete);
|
||||
MIRType *CreateAndUpdateMirTypeNode(MIRType &pType);
|
||||
MIRType *GetOrCreateStructOrUnion(const std::string &name, const FieldVector &fields,
|
||||
const FieldVector &printFields, MIRModule &module, bool forStruct = true,
|
||||
const TypeAttrs &attrs = TypeAttrs());
|
||||
MIRType *GetOrCreateClassOrInterface(const std::string &name, MIRModule &module, bool forClass);
|
||||
|
||||
MIRType *CreateMirType(uint32 primTypeIdx) const;
|
||||
void PutToHashTable(MIRType *mirType);
|
||||
|
@ -155,7 +155,6 @@ struct IntrinDesc {
|
||||
static MIRType *jsValueType;
|
||||
static MIRModule *mirModule;
|
||||
static void InitMIRModule(MIRModule *mirModule);
|
||||
static MIRType *GetOrCreateJSValueType();
|
||||
static IntrinDesc intrinTable[INTRN_LAST + 1];
|
||||
};
|
||||
} // namespace maple
|
||||
|
@ -38,16 +38,7 @@ REGISTER_SAFE_CAST(MIRPtrType, from.GetKind() == kTypePointer);
|
||||
REGISTER_SAFE_CAST(MIRArrayType, from.GetKind() == kTypeArray);
|
||||
REGISTER_SAFE_CAST(MIRFarrayType, from.GetKind() == kTypeFArray ||
|
||||
instance_of<MIRJarrayType>(from));
|
||||
REGISTER_SAFE_CAST(MIRStructType, from.GetKind() == kTypeStruct ||
|
||||
from.GetKind() == kTypeStructIncomplete ||
|
||||
from.GetKind() == kTypeUnion ||
|
||||
instance_of<MIRClassType>(from) ||
|
||||
instance_of<MIRInterfaceType>(from));
|
||||
REGISTER_SAFE_CAST(MIRJarrayType, from.GetKind() == kTypeJArray);
|
||||
REGISTER_SAFE_CAST(MIRClassType, from.GetKind() == kTypeClass ||
|
||||
from.GetKind() == kTypeClassIncomplete);
|
||||
REGISTER_SAFE_CAST(MIRInterfaceType, from.GetKind() == kTypeInterface ||
|
||||
from.GetKind() == kTypeInterfaceIncomplete);
|
||||
REGISTER_SAFE_CAST(MIRBitFieldType, from.GetKind() == kTypeBitField);
|
||||
REGISTER_SAFE_CAST(MIRFuncType, from.GetKind() == kTypeFunction);
|
||||
REGISTER_SAFE_CAST(MIRTypeByName, from.GetKind() == kTypeByName);
|
||||
|
@ -116,29 +116,7 @@ public:
|
||||
MIRFunction *GetOrCreateFunction(const std::string &, TyIdx);
|
||||
MIRFunction *GetFunctionFromSymbol(const MIRSymbol &funcst);
|
||||
MIRFunction *GetFunctionFromName(const std::string &);
|
||||
// For compiler-generated metadata struct
|
||||
void AddIntFieldConst(const MIRStructType &sType, MIRAggConst &newConst, uint32 fieldID, int64 constValue);
|
||||
void AddAddrofFieldConst(const MIRStructType &sType, MIRAggConst &newConst, uint32 fieldID,
|
||||
const MIRSymbol &fieldSt);
|
||||
void AddAddroffuncFieldConst(const MIRStructType &sType, MIRAggConst &newConst, uint32 fieldID,
|
||||
const MIRSymbol &funcSt);
|
||||
|
||||
bool TraverseToNamedField(MIRStructType &structType, GStrIdx nameIdx, uint32 &fieldID);
|
||||
bool TraverseToNamedFieldWithTypeAndMatchStyle(MIRStructType &structType, GStrIdx nameIdx, TyIdx typeIdx,
|
||||
uint32 &fieldID, unsigned int matchStyle);
|
||||
void TraverseToNamedFieldWithType(MIRStructType &structType, GStrIdx nameIdx, TyIdx typeIdx, uint32 &fieldID,
|
||||
uint32 &idx);
|
||||
|
||||
FieldID GetStructFieldIDFromNameAndType(MIRType &type, const std::string &name, TyIdx idx, unsigned int matchStyle);
|
||||
FieldID GetStructFieldIDFromNameAndType(MIRType &type, const std::string &name, TyIdx idx);
|
||||
FieldID GetStructFieldIDFromNameAndTypeParentFirst(MIRType &type, const std::string &name, TyIdx idx);
|
||||
FieldID GetStructFieldIDFromNameAndTypeParentFirstFoundInChild(MIRType &type, const std::string &name, TyIdx idx);
|
||||
|
||||
FieldID GetStructFieldIDFromFieldName(MIRType &type, const std::string &name);
|
||||
FieldID GetStructFieldIDFromFieldNameParentFirst(MIRType *type, const std::string &name);
|
||||
|
||||
void SetStructFieldIDFromFieldName(MIRStructType &structType, const std::string &name, GStrIdx newStrIdx,
|
||||
const MIRType &newFieldType);
|
||||
// for creating Function.
|
||||
MIRSymbol *GetFunctionArgument(MIRFunction &fun, uint32 index) const
|
||||
{
|
||||
|
@ -478,10 +478,6 @@ public:
|
||||
bool HasCall() const;
|
||||
void SetHasCall();
|
||||
|
||||
bool IsReturnStruct() const;
|
||||
void SetReturnStruct();
|
||||
void SetReturnStruct(const MIRType &retType);
|
||||
|
||||
bool IsUserFunc() const;
|
||||
void SetUserFunc();
|
||||
|
||||
@ -498,11 +494,6 @@ public:
|
||||
void SetHasAsm();
|
||||
bool HasAsm() const;
|
||||
|
||||
void SetStructReturnedInRegs();
|
||||
bool StructReturnedInRegs() const;
|
||||
|
||||
void SetReturnStruct(const MIRType *retType);
|
||||
|
||||
bool IsEmpty() const;
|
||||
bool IsClinit() const;
|
||||
uint32 GetInfo(GStrIdx strIdx) const;
|
||||
@ -615,17 +606,6 @@ public:
|
||||
return codeMemPoolAllocator;
|
||||
}
|
||||
|
||||
TyIdx GetFuncRetStructTyIdx()
|
||||
{
|
||||
TyIdx tyIdx = GetFormalDefAt(0).formalTyIdx;
|
||||
MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
|
||||
CHECK_FATAL(ty->GetKind() == kTypePointer, "Fake param not a pointer");
|
||||
MIRPtrType *pType = static_cast<MIRPtrType *>(ty);
|
||||
tyIdx = pType->GetPointedTyIdx();
|
||||
CHECK_FATAL(GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx)->IsStructType(), "Must be struct return type");
|
||||
return tyIdx;
|
||||
}
|
||||
|
||||
void EnterFormals();
|
||||
void NewBody();
|
||||
|
||||
|
@ -317,7 +317,6 @@ public:
|
||||
#endif
|
||||
const std::string &GetFileNameFromFileNum(uint32 fileNum) const;
|
||||
#ifdef ARK_LITECG_DEBUG
|
||||
void DumpToCxxHeaderFile(std::set<std::string> &leafClasses, const std::string &pathToOutf) const;
|
||||
void DumpClassToFile(const std::string &path) const;
|
||||
void DumpFunctionList(const std::unordered_set<std::string> *dumpFuncSet) const;
|
||||
void DumpGlobalArraySymbol() const;
|
||||
@ -822,10 +821,6 @@ public:
|
||||
bool HasNotWarned(uint32 postion, uint32 stmtOriginalID);
|
||||
|
||||
private:
|
||||
#ifdef ARK_LITECG_DEBUG
|
||||
void DumpTypeTreeToCxxHeaderFile(MIRType &ty, std::unordered_set<MIRType *> &dumpedClasses) const;
|
||||
#endif
|
||||
|
||||
MemPool *memPool;
|
||||
MemPool *pragmaMemPool;
|
||||
MapleAllocator memPoolAllocator;
|
||||
|
@ -356,11 +356,6 @@ private:
|
||||
return from.IsMIRPtrType() || from.IsMIRJarrayType();
|
||||
}
|
||||
|
||||
bool IsInterfaceOrClass(const MIRType &mirType) const
|
||||
{
|
||||
return mirType.IsMIRClassType() || mirType.IsMIRInterfaceType();
|
||||
}
|
||||
|
||||
TyIdx tyIdx = TyIdx(0);
|
||||
};
|
||||
|
||||
@ -1201,8 +1196,6 @@ public:
|
||||
void Dump(int32 indent) const override;
|
||||
#endif
|
||||
|
||||
bool CheckNode(const MIRModule &mod) const;
|
||||
|
||||
AddrofNode *CloneTree(MapleAllocator &allocator) const override
|
||||
{
|
||||
return allocator.GetMemPool()->New<AddrofNode>(*this);
|
||||
|
@ -572,25 +572,12 @@ public:
|
||||
{
|
||||
uint8 align = GetAttrs().GetAlignValue();
|
||||
if (align == 0) {
|
||||
if (GetType()->GetKind() == kTypeStruct || GetType()->GetKind() == kTypeClass ||
|
||||
GetType()->GetKind() == kTypeArray || GetType()->GetKind() == kTypeUnion) {
|
||||
// when x64 does not driver, there is no triple init, this is a temporary plan
|
||||
if (Triple::GetTriple().GetArch() == Triple::ArchType::x64) {
|
||||
return align;
|
||||
}
|
||||
uint8 alignMin = 0;
|
||||
if (GetType()->GetAlign() > 0) {
|
||||
alignMin = static_cast<uint8>(log2(GetType()->GetAlign()));
|
||||
}
|
||||
align = std::max<uint8>(3, alignMin); // 3: alignment in bytes of uint8
|
||||
} else {
|
||||
align = static_cast<uint8>(GetType()->GetAlign());
|
||||
if (Triple::GetTriple().IsAarch64BeOrLe()) {
|
||||
if (isArm64ilp32 && GetType()->GetPrimType() == PTY_a32) {
|
||||
align = 3; // 3: alignment in bytes of uint8
|
||||
} else {
|
||||
align = static_cast<uint8>(log2(align));
|
||||
}
|
||||
align = static_cast<uint8>(GetType()->GetAlign());
|
||||
if (Triple::GetTriple().IsAarch64BeOrLe()) {
|
||||
if (isArm64ilp32 && GetType()->GetPrimType() == PTY_a32) {
|
||||
align = 3; // 3: alignment in bytes of uint8
|
||||
} else {
|
||||
align = static_cast<uint8>(log2(align));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -183,8 +183,6 @@ enum MIRTypeKind : std::uint8_t {
|
||||
kTypeArray,
|
||||
kTypeFArray,
|
||||
kTypeJArray,
|
||||
kTypeStruct,
|
||||
kTypeUnion,
|
||||
kTypeClass,
|
||||
kTypeInterface,
|
||||
kTypeStructIncomplete,
|
||||
@ -815,8 +813,6 @@ struct OffsetType {
|
||||
|
||||
int32 val = kOffsetUnknown;
|
||||
};
|
||||
|
||||
class MIRStructType; // circular dependency exists, no other choice
|
||||
class MIRFuncType;
|
||||
|
||||
// if it is a bitfield, byteoffset gives the offset of the container for
|
||||
@ -938,31 +934,11 @@ public:
|
||||
return typeKind == kTypePointer;
|
||||
}
|
||||
|
||||
bool IsMIRStructType() const
|
||||
{
|
||||
return (typeKind == kTypeStruct) || (typeKind == kTypeStructIncomplete);
|
||||
}
|
||||
|
||||
bool IsMIRUnionType() const
|
||||
{
|
||||
return typeKind == kTypeUnion;
|
||||
}
|
||||
|
||||
bool IsMIRClassType() const
|
||||
{
|
||||
return (typeKind == kTypeClass) || (typeKind == kTypeClassIncomplete);
|
||||
}
|
||||
|
||||
bool IsMIRInterfaceType() const
|
||||
{
|
||||
return (typeKind == kTypeInterface) || (typeKind == kTypeInterfaceIncomplete);
|
||||
}
|
||||
|
||||
bool IsInstanceOfMIRStructType() const
|
||||
{
|
||||
return IsMIRStructType() || IsMIRClassType() || IsMIRInterfaceType();
|
||||
}
|
||||
|
||||
bool IsMIRJarrayType() const
|
||||
{
|
||||
return typeKind == kTypeJArray;
|
||||
@ -1023,11 +999,6 @@ public:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// return any struct type directly embedded in this type
|
||||
virtual MIRStructType *EmbeddedStructType()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual int64 GetBitOffsetFromBaseAddr(FieldID fieldID)
|
||||
{
|
||||
@ -1095,8 +1066,6 @@ public:
|
||||
#endif
|
||||
size_t GetSize() const override;
|
||||
uint32 GetAlign() const override;
|
||||
TyIdxFieldAttrPair GetPointedTyIdxFldAttrPairWithFieldID(FieldID fldId) const;
|
||||
TyIdx GetPointedTyIdxWithFieldID(FieldID fieldID) const;
|
||||
size_t GetHashIndex() const override
|
||||
{
|
||||
constexpr uint8 idxShift = 4;
|
||||
@ -1240,7 +1209,6 @@ public:
|
||||
std::string GetCompactMplTypeName() const override;
|
||||
bool HasFields() const override;
|
||||
uint32 NumberOfFieldIDs() const override;
|
||||
MIRStructType *EmbeddedStructType() override;
|
||||
size_t ElemNumber() const;
|
||||
|
||||
private:
|
||||
@ -1299,7 +1267,6 @@ public:
|
||||
|
||||
bool HasFields() const override;
|
||||
uint32 NumberOfFieldIDs() const override;
|
||||
MIRStructType *EmbeddedStructType() override;
|
||||
|
||||
int64 GetBitOffsetFromBaseAddr(FieldID fieldID) override
|
||||
{
|
||||
@ -1323,512 +1290,6 @@ class GenericDeclare;
|
||||
class AnnotationType;
|
||||
class GenericType;
|
||||
// used by kTypeStruct, kTypeStructIncomplete, kTypeUnion
|
||||
class MIRStructType : public MIRType {
|
||||
public:
|
||||
explicit MIRStructType(MIRTypeKind typeKind) : MIRType(typeKind, PTY_agg) {}
|
||||
|
||||
MIRStructType(MIRTypeKind typeKind, GStrIdx strIdx) : MIRType(typeKind, PTY_agg, strIdx) {}
|
||||
|
||||
~MIRStructType() override = default;
|
||||
|
||||
bool IsStructType() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
FieldVector &GetFields()
|
||||
{
|
||||
return fields;
|
||||
}
|
||||
const FieldVector &GetFields() const
|
||||
{
|
||||
return fields;
|
||||
}
|
||||
void SetFields(const FieldVector &newFields)
|
||||
{
|
||||
this->fields = newFields;
|
||||
}
|
||||
|
||||
const FieldPair &GetFieldsElemt(size_t n) const
|
||||
{
|
||||
DEBUG_ASSERT(n < fields.size(), "array index out of range");
|
||||
return fields.at(n);
|
||||
}
|
||||
|
||||
FieldPair &GetFieldsElemt(size_t n)
|
||||
{
|
||||
DEBUG_ASSERT(n < fields.size(), "array index out of range");
|
||||
return fields.at(n);
|
||||
}
|
||||
|
||||
size_t GetFieldsSize() const
|
||||
{
|
||||
return fields.size();
|
||||
}
|
||||
|
||||
const std::vector<TyIdx> &GetFieldInferredTyIdx() const
|
||||
{
|
||||
return fieldInferredTyIdx;
|
||||
}
|
||||
|
||||
FieldVector &GetStaticFields()
|
||||
{
|
||||
return staticFields;
|
||||
}
|
||||
const FieldVector &GetStaticFields() const
|
||||
{
|
||||
return staticFields;
|
||||
}
|
||||
|
||||
const FieldPair &GetStaticFieldsPair(size_t i) const
|
||||
{
|
||||
return staticFields.at(i);
|
||||
}
|
||||
|
||||
GStrIdx GetStaticFieldsGStrIdx(size_t i) const
|
||||
{
|
||||
return staticFields.at(i).first;
|
||||
}
|
||||
|
||||
FieldVector &GetParentFields()
|
||||
{
|
||||
return parentFields;
|
||||
}
|
||||
void SetParentFields(const FieldVector &newParentFields)
|
||||
{
|
||||
this->parentFields = newParentFields;
|
||||
}
|
||||
const FieldVector &GetParentFields() const
|
||||
{
|
||||
return parentFields;
|
||||
}
|
||||
const FieldPair &GetParentFieldsElemt(size_t n) const
|
||||
{
|
||||
DEBUG_ASSERT(n < parentFields.size(), "array index out of range");
|
||||
return parentFields.at(n);
|
||||
}
|
||||
size_t GetParentFieldsSize() const
|
||||
{
|
||||
return parentFields.size();
|
||||
}
|
||||
|
||||
MethodVector &GetMethods()
|
||||
{
|
||||
return methods;
|
||||
}
|
||||
const MethodVector &GetMethods() const
|
||||
{
|
||||
return methods;
|
||||
}
|
||||
|
||||
const MethodPair &GetMethodsElement(size_t n) const
|
||||
{
|
||||
DEBUG_ASSERT(n < methods.size(), "array index out of range");
|
||||
return methods.at(n);
|
||||
}
|
||||
|
||||
MethodPtrVector &GetVTableMethods()
|
||||
{
|
||||
return vTableMethods;
|
||||
}
|
||||
|
||||
const MethodPair *GetVTableMethodsElemt(size_t n) const
|
||||
{
|
||||
DEBUG_ASSERT(n < vTableMethods.size(), "array index out of range");
|
||||
return vTableMethods.at(n);
|
||||
}
|
||||
|
||||
size_t GetVTableMethodsSize() const
|
||||
{
|
||||
return vTableMethods.size();
|
||||
}
|
||||
|
||||
const MethodPtrVector &GetItableMethods() const
|
||||
{
|
||||
return iTableMethods;
|
||||
}
|
||||
|
||||
bool IsImported() const
|
||||
{
|
||||
return isImported;
|
||||
}
|
||||
|
||||
void SetIsImported(bool flag)
|
||||
{
|
||||
isImported = flag;
|
||||
}
|
||||
|
||||
bool IsUsed() const
|
||||
{
|
||||
return isUsed;
|
||||
}
|
||||
|
||||
void SetIsUsed(bool flag)
|
||||
{
|
||||
isUsed = flag;
|
||||
}
|
||||
|
||||
bool IsCPlusPlus() const
|
||||
{
|
||||
return isCPlusPlus;
|
||||
}
|
||||
|
||||
void SetIsCPlusPlus(bool flag)
|
||||
{
|
||||
isCPlusPlus = flag;
|
||||
}
|
||||
|
||||
GStrIdx GetFieldGStrIdx(FieldID id) const
|
||||
{
|
||||
const FieldPair &fieldPair = TraverseToField(id);
|
||||
return fieldPair.first;
|
||||
}
|
||||
|
||||
const TyIdxFieldAttrPair GetFieldTyIdxAttrPair(FieldID id) const
|
||||
{
|
||||
return TraverseToField(id).second;
|
||||
}
|
||||
|
||||
TyIdxFieldAttrPair GetTyidxFieldAttrPair(size_t n) const
|
||||
{
|
||||
return fields.at(n).second;
|
||||
}
|
||||
|
||||
TyIdx GetFieldTyIdx(FieldID id) const
|
||||
{
|
||||
const FieldPair &fieldPair = TraverseToField(id);
|
||||
return fieldPair.second.first;
|
||||
}
|
||||
|
||||
FieldAttrs GetFieldAttrs(FieldID id) const
|
||||
{
|
||||
const FieldPair &fieldPair = TraverseToField(id);
|
||||
return fieldPair.second.second;
|
||||
}
|
||||
|
||||
FieldAttrs GetFieldAttrs(GStrIdx fieldStrIdx) const
|
||||
{
|
||||
const FieldPair &fieldPair = TraverseToField(fieldStrIdx);
|
||||
return fieldPair.second.second;
|
||||
}
|
||||
|
||||
bool IsFieldVolatile(FieldID id) const
|
||||
{
|
||||
const FieldPair &fieldPair = TraverseToField(id);
|
||||
return fieldPair.second.second.GetAttr(FLDATTR_volatile);
|
||||
}
|
||||
|
||||
bool IsFieldFinal(FieldID id) const
|
||||
{
|
||||
const FieldPair &fieldPair = TraverseToField(id);
|
||||
return fieldPair.second.second.GetAttr(FLDATTR_final);
|
||||
}
|
||||
|
||||
bool IsFieldRCUnownedRef(FieldID id) const
|
||||
{
|
||||
const FieldPair &fieldPair = TraverseToField(id);
|
||||
return fieldPair.second.second.GetAttr(FLDATTR_rcunowned);
|
||||
}
|
||||
|
||||
bool IsFieldRCWeak(FieldID id) const
|
||||
{
|
||||
const FieldPair &fieldPair = TraverseToField(id);
|
||||
return fieldPair.second.second.GetAttr(FLDATTR_rcweak);
|
||||
}
|
||||
|
||||
bool IsFieldRestrict(FieldID id) const
|
||||
{
|
||||
const FieldPair &fieldPair = TraverseToField(id);
|
||||
return fieldPair.second.second.GetAttr(FLDATTR_restrict);
|
||||
}
|
||||
|
||||
bool IsOwnField(FieldID id) const
|
||||
{
|
||||
const FieldPair &fieldPair = TraverseToField(id);
|
||||
return std::find(fields.begin(), fields.end(), fieldPair) != fields.end();
|
||||
}
|
||||
|
||||
TypeAttrs &GetTypeAttrs()
|
||||
{
|
||||
return typeAttrs;
|
||||
}
|
||||
|
||||
const TypeAttrs &GetTypeAttrs() const
|
||||
{
|
||||
return typeAttrs;
|
||||
}
|
||||
|
||||
void SetTypeAttrs(const TypeAttrs &attrs)
|
||||
{
|
||||
typeAttrs = attrs;
|
||||
}
|
||||
|
||||
bool HasVolatileField() const override;
|
||||
bool HasTypeParam() const override;
|
||||
bool EqualTo(const MIRType &type) const override;
|
||||
MIRType *CopyMIRTypeNode() const override
|
||||
{
|
||||
return new MIRStructType(*this);
|
||||
}
|
||||
|
||||
TyIdx GetElemTyIdx(size_t n) const
|
||||
{
|
||||
DEBUG_ASSERT(n < fields.size(), "array index out of range");
|
||||
return fields.at(n).second.first;
|
||||
}
|
||||
|
||||
void SetElemtTyIdxSimple(size_t n, TyIdx tyIdx)
|
||||
{
|
||||
DEBUG_ASSERT(n < fields.size(), "array index out of range");
|
||||
fields.at(n).second.first = tyIdx;
|
||||
}
|
||||
|
||||
TyIdx GetStaticElemtTyIdx(size_t n) const
|
||||
{
|
||||
DEBUG_ASSERT(n < staticFields.size(), "array index out of range");
|
||||
return staticFields.at(n).second.first;
|
||||
}
|
||||
|
||||
void SetStaticElemtTyIdx(size_t n, TyIdx tyIdx)
|
||||
{
|
||||
staticFields.at(n).second.first = tyIdx;
|
||||
}
|
||||
|
||||
void SetMethodTyIdx(size_t n, TyIdx tyIdx)
|
||||
{
|
||||
DEBUG_ASSERT(n < methods.size(), "array index out of range");
|
||||
methods.at(n).second.first = tyIdx;
|
||||
}
|
||||
|
||||
MIRType *GetElemType(uint32 n) const;
|
||||
|
||||
MIRType *GetFieldType(FieldID fieldID);
|
||||
|
||||
void SetElemtTyIdx(size_t n, TyIdx tyIdx)
|
||||
{
|
||||
DEBUG_ASSERT(n < fields.size(), "array index out of range");
|
||||
fields.at(n).second = TyIdxFieldAttrPair(tyIdx, FieldAttrs());
|
||||
}
|
||||
|
||||
GStrIdx GetElemStrIdx(size_t n) const
|
||||
{
|
||||
DEBUG_ASSERT(n < fields.size(), "array index out of range");
|
||||
return fields.at(n).first;
|
||||
}
|
||||
|
||||
void SetElemStrIdx(size_t n, GStrIdx idx)
|
||||
{
|
||||
DEBUG_ASSERT(n < fields.size(), "array index out of range");
|
||||
fields.at(n).first = idx;
|
||||
}
|
||||
|
||||
void SetElemInferredTyIdx(size_t n, TyIdx tyIdx)
|
||||
{
|
||||
if (n >= fieldInferredTyIdx.size()) {
|
||||
(void)fieldInferredTyIdx.insert(fieldInferredTyIdx.end(), n + 1 - fieldInferredTyIdx.size(), kInitTyIdx);
|
||||
}
|
||||
DEBUG_ASSERT(n < fieldInferredTyIdx.size(), "array index out of range");
|
||||
fieldInferredTyIdx.at(n) = tyIdx;
|
||||
}
|
||||
|
||||
TyIdx GetElemInferredTyIdx(size_t n)
|
||||
{
|
||||
if (n >= fieldInferredTyIdx.size()) {
|
||||
(void)fieldInferredTyIdx.insert(fieldInferredTyIdx.end(), n + 1 - fieldInferredTyIdx.size(), kInitTyIdx);
|
||||
}
|
||||
DEBUG_ASSERT(n < fieldInferredTyIdx.size(), "array index out of range");
|
||||
return fieldInferredTyIdx.at(n);
|
||||
}
|
||||
#ifdef ARK_LITECG_DEBUG
|
||||
void DumpFieldsAndMethods(int indent, bool hasMethod) const;
|
||||
void Dump(int indent, bool dontUseName = false) const override;
|
||||
#endif
|
||||
virtual void SetComplete()
|
||||
{
|
||||
typeKind = (typeKind == kTypeUnion) ? typeKind : kTypeStruct;
|
||||
}
|
||||
|
||||
// only meaningful for MIRClassType and MIRInterface types
|
||||
bool IsLocal() const;
|
||||
|
||||
size_t GetSize() const override;
|
||||
uint32 GetTypedefOriginalAlign() const;
|
||||
uint32 GetAlign() const override;
|
||||
uint32 GetAlignAux(bool toGetOriginal) const;
|
||||
uint32 GetUnadjustedAlign() const override;
|
||||
|
||||
size_t GetHashIndex() const override
|
||||
{
|
||||
constexpr uint8 attrShift = 3;
|
||||
return ((static_cast<size_t>(nameStrIdx) << kShiftNumOfNameStrIdx) + (typeKind << kShiftNumOfTypeKind) +
|
||||
((typeAttrs.GetAttrFlag() << attrShift) + typeAttrs.GetAlignValue())) %
|
||||
kTypeHashLength;
|
||||
}
|
||||
|
||||
virtual void ClearContents()
|
||||
{
|
||||
fields.clear();
|
||||
staticFields.clear();
|
||||
parentFields.clear();
|
||||
methods.clear();
|
||||
vTableMethods.clear();
|
||||
iTableMethods.clear();
|
||||
isImported = false;
|
||||
isUsed = false;
|
||||
hasVolatileField = false;
|
||||
hasVolatileFieldSet = false;
|
||||
}
|
||||
|
||||
virtual const std::vector<MIRInfoPair> &GetInfo() const
|
||||
{
|
||||
CHECK_FATAL(false, "can not use GetInfo");
|
||||
}
|
||||
|
||||
virtual const MIRInfoPair &GetInfoElemt(size_t) const
|
||||
{
|
||||
CHECK_FATAL(false, "can not use GetInfoElemt");
|
||||
}
|
||||
|
||||
virtual const std::vector<bool> &GetInfoIsString() const
|
||||
{
|
||||
CHECK_FATAL(false, "can not use GetInfoIsString");
|
||||
}
|
||||
|
||||
virtual bool GetInfoIsStringElemt(size_t) const
|
||||
{
|
||||
CHECK_FATAL(false, "can not use GetInfoIsStringElemt");
|
||||
}
|
||||
|
||||
std::vector<GenericDeclare *> &GetGenericDeclare()
|
||||
{
|
||||
return genericDeclare;
|
||||
}
|
||||
|
||||
void AddClassGenericDeclare(GenericDeclare *gd)
|
||||
{
|
||||
genericDeclare.push_back(gd);
|
||||
}
|
||||
|
||||
void AddFieldGenericDeclare(const GStrIdx &g, AnnotationType *a)
|
||||
{
|
||||
if (fieldGenericDeclare.find(g) != fieldGenericDeclare.end()) {
|
||||
CHECK_FATAL(fieldGenericDeclare[g] == a, "MUST BE");
|
||||
}
|
||||
fieldGenericDeclare[g] = a;
|
||||
}
|
||||
|
||||
AnnotationType *GetFieldGenericDeclare(const GStrIdx &g)
|
||||
{
|
||||
if (fieldGenericDeclare.find(g) == fieldGenericDeclare.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return fieldGenericDeclare[g];
|
||||
}
|
||||
|
||||
void AddInheritaceGeneric(GenericType *a)
|
||||
{
|
||||
inheritanceGeneric.push_back(a);
|
||||
}
|
||||
|
||||
std::vector<GenericType *> &GetInheritanceGeneric()
|
||||
{
|
||||
return inheritanceGeneric;
|
||||
}
|
||||
|
||||
virtual const MIREncodedArray &GetStaticValue() const
|
||||
{
|
||||
CHECK_FATAL(false, "can not use GetStaticValue");
|
||||
}
|
||||
|
||||
virtual void PushbackMIRInfo(const MIRInfoPair &)
|
||||
{
|
||||
CHECK_FATAL(false, "can not use PushbackMIRInfo");
|
||||
}
|
||||
|
||||
virtual void PushbackStaticValue(EncodedValue &)
|
||||
{
|
||||
CHECK_FATAL(false, "can not use PushbackStaticValue");
|
||||
}
|
||||
|
||||
virtual void PushbackIsString(bool)
|
||||
{
|
||||
CHECK_FATAL(false, "can not use PushbackIsString");
|
||||
}
|
||||
|
||||
bool HasFields() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
uint32 NumberOfFieldIDs() const override;
|
||||
MIRStructType *EmbeddedStructType() override
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
virtual FieldPair TraverseToFieldRef(FieldID &fieldID) const;
|
||||
std::string GetMplTypeName() const override;
|
||||
std::string GetCompactMplTypeName() const override;
|
||||
FieldPair TraverseToField(FieldID fieldID) const;
|
||||
|
||||
int64 GetBitOffsetFromBaseAddr(FieldID fieldID) override;
|
||||
|
||||
FieldInfo GetFieldOffsetFromBaseAddr(FieldID fieldID) const;
|
||||
|
||||
bool HasPadding() const;
|
||||
|
||||
bool HasZeroWidthBitField() const;
|
||||
|
||||
void AddFieldLayout(const FieldInfo &info)
|
||||
{
|
||||
fieldLayout.emplace_back(info);
|
||||
}
|
||||
|
||||
std::vector<FieldInfo> &GetFieldLayout()
|
||||
{
|
||||
if (!layoutComputed) {
|
||||
ComputeLayout();
|
||||
}
|
||||
return fieldLayout;
|
||||
}
|
||||
|
||||
uint32 GetFieldTypeAlignByFieldPair(const FieldPair &fieldPair);
|
||||
|
||||
protected:
|
||||
FieldVector fields {};
|
||||
std::vector<TyIdx> fieldInferredTyIdx {};
|
||||
FieldVector staticFields {};
|
||||
FieldVector parentFields {}; // fields belong to the ancestors not fully defined
|
||||
MethodVector methods {}; // for the list of member function prototypes
|
||||
MethodPtrVector vTableMethods {}; // the list of implmentation for all virtual functions for this type
|
||||
MethodPtrVector iTableMethods {}; // the list of all interface functions for this type; For classes, they are
|
||||
// implementation functions, For interfaces, they are abstact functions.
|
||||
// Weak indicates the actual definition is in another module.
|
||||
bool isImported = false;
|
||||
bool isUsed = false;
|
||||
bool isCPlusPlus = false; // empty struct in C++ has size 1 byte
|
||||
mutable bool hasVolatileField = false; // for caching computed value
|
||||
mutable bool hasVolatileFieldSet = false; // if true, just read hasVolatileField;
|
||||
// otherwise compute to initialize hasVolatileField
|
||||
std::vector<GenericDeclare *> genericDeclare;
|
||||
std::map<GStrIdx, AnnotationType *> fieldGenericDeclare;
|
||||
std::vector<GenericType *> inheritanceGeneric;
|
||||
TypeAttrs typeAttrs;
|
||||
mutable uint32 fieldsNum = kInvalidFieldNum;
|
||||
mutable std::vector<FieldInfo> fieldLayout;
|
||||
mutable size_t size = kInvalidSize;
|
||||
|
||||
bool layoutComputed = false;
|
||||
|
||||
private:
|
||||
FieldPair TraverseToField(GStrIdx fieldStrIdx) const;
|
||||
bool HasVolatileFieldInFields(const FieldVector &fieldsOfStruct) const;
|
||||
bool HasTypeParamInFields(const FieldVector &fieldsOfStruct) const;
|
||||
int64 GetBitOffsetFromUnionBaseAddr(FieldID fieldID);
|
||||
int64 GetBitOffsetFromStructBaseAddr(FieldID fieldID);
|
||||
void ComputeUnionLayout();
|
||||
void ComputeLayout();
|
||||
};
|
||||
|
||||
class MIRJarrayType : public MIRFarrayType {
|
||||
public:
|
||||
MIRJarrayType()
|
||||
@ -1853,16 +1314,6 @@ public:
|
||||
return new MIRJarrayType(*this);
|
||||
}
|
||||
|
||||
MIRStructType *GetParentType();
|
||||
|
||||
bool IsPrimitiveArray()
|
||||
{
|
||||
if (jNameStrIdx == 0u) {
|
||||
DetermineName();
|
||||
}
|
||||
return fromPrimitive;
|
||||
}
|
||||
|
||||
int GetDim()
|
||||
{
|
||||
if (jNameStrIdx == 0u) {
|
||||
@ -1882,300 +1333,10 @@ private:
|
||||
void DetermineName(); // determine the internal name of this type
|
||||
TyIdx parentTyIdx {0}; // since Jarray is also an object, this is j.lang.Object
|
||||
GStrIdx jNameStrIdx {0}; // for internal j name of Jarray. nameStrIdx is used for other purpose
|
||||
bool fromPrimitive = false; // the lowest dimension is primitive type
|
||||
int dim = 0; // the dimension if decidable at compile time. otherwise 0
|
||||
};
|
||||
|
||||
// used by kTypeClass, kTypeClassIncomplete
|
||||
class MIRClassType : public MIRStructType {
|
||||
public:
|
||||
explicit MIRClassType(MIRTypeKind tKind) : MIRStructType(tKind) {}
|
||||
MIRClassType(MIRTypeKind tKind, GStrIdx strIdx) : MIRStructType(tKind, strIdx) {}
|
||||
~MIRClassType() override = default;
|
||||
|
||||
bool EqualTo(const MIRType &type) const override;
|
||||
|
||||
MIRType *CopyMIRTypeNode() const override
|
||||
{
|
||||
return new MIRClassType(*this);
|
||||
}
|
||||
|
||||
const std::vector<MIRInfoPair> &GetInfo() const override
|
||||
{
|
||||
return info;
|
||||
}
|
||||
void PushbackMIRInfo(const MIRInfoPair &pair) override
|
||||
{
|
||||
info.push_back(pair);
|
||||
}
|
||||
uint32 GetInfo(const std::string &infoStr) const;
|
||||
uint32 GetInfo(GStrIdx strIdx) const;
|
||||
size_t GetInfoSize() const
|
||||
{
|
||||
return info.size();
|
||||
}
|
||||
|
||||
const MIRInfoPair &GetInfoElemt(size_t n) const override
|
||||
{
|
||||
DEBUG_ASSERT(n < info.size(), "array index out of range");
|
||||
return info.at(n);
|
||||
}
|
||||
|
||||
const std::vector<bool> &GetInfoIsString() const override
|
||||
{
|
||||
return infoIsString;
|
||||
}
|
||||
|
||||
void PushbackIsString(bool isString) override
|
||||
{
|
||||
infoIsString.push_back(isString);
|
||||
}
|
||||
|
||||
size_t GetInfoIsStringSize() const
|
||||
{
|
||||
return infoIsString.size();
|
||||
}
|
||||
|
||||
bool GetInfoIsStringElemt(size_t n) const override
|
||||
{
|
||||
DEBUG_ASSERT(n < infoIsString.size(), "array index out of range");
|
||||
return infoIsString.at(n);
|
||||
}
|
||||
|
||||
const MIREncodedArray &GetStaticValue() const override
|
||||
{
|
||||
return staticValue;
|
||||
}
|
||||
void PushbackStaticValue(EncodedValue &encodedValue) override
|
||||
{
|
||||
staticValue.push_back(encodedValue);
|
||||
}
|
||||
|
||||
TyIdx GetParentTyIdx() const
|
||||
{
|
||||
return parentTyIdx;
|
||||
}
|
||||
void SetParentTyIdx(TyIdx idx)
|
||||
{
|
||||
parentTyIdx = idx;
|
||||
}
|
||||
|
||||
std::vector<TyIdx> &GetInterfaceImplemented()
|
||||
{
|
||||
return interfacesImplemented;
|
||||
}
|
||||
const std::vector<TyIdx> &GetInterfaceImplemented() const
|
||||
{
|
||||
return interfacesImplemented;
|
||||
}
|
||||
TyIdx GetNthInterfaceImplemented(size_t i) const
|
||||
{
|
||||
DEBUG_ASSERT(i < interfacesImplemented.size(), "array index out of range");
|
||||
return interfacesImplemented.at(i);
|
||||
}
|
||||
|
||||
void SetNthInterfaceImplemented(size_t i, TyIdx tyIdx)
|
||||
{
|
||||
DEBUG_ASSERT(i < interfacesImplemented.size(), "array index out of range");
|
||||
interfacesImplemented.at(i) = tyIdx;
|
||||
}
|
||||
void PushbackInterfaceImplemented(TyIdx idx)
|
||||
{
|
||||
interfacesImplemented.push_back(idx);
|
||||
}
|
||||
#ifdef ARK_LITECG_DEBUG
|
||||
void Dump(int indent, bool dontUseName = false) const override;
|
||||
void DumpAsCxx(int indent) const override;
|
||||
#endif
|
||||
void SetComplete() override
|
||||
{
|
||||
typeKind = kTypeClass;
|
||||
}
|
||||
|
||||
bool IsFinal() const;
|
||||
bool IsAbstract() const;
|
||||
bool IsInner() const;
|
||||
bool HasVolatileField() const override;
|
||||
bool HasTypeParam() const override;
|
||||
FieldPair TraverseToFieldRef(FieldID &fieldID) const override;
|
||||
size_t GetSize() const override;
|
||||
|
||||
FieldID GetLastFieldID() const;
|
||||
FieldID GetFirstFieldID() const
|
||||
{
|
||||
return GetLastFieldID() - fields.size() + 1;
|
||||
}
|
||||
|
||||
FieldID GetFirstLocalFieldID() const;
|
||||
// return class id or superclass id accroding to input string
|
||||
void AddImplementedInterface(TyIdx interfaceTyIdx)
|
||||
{
|
||||
if (std::find(interfacesImplemented.begin(), interfacesImplemented.end(), interfaceTyIdx) ==
|
||||
interfacesImplemented.end()) {
|
||||
interfacesImplemented.push_back(interfaceTyIdx);
|
||||
}
|
||||
}
|
||||
|
||||
void ClearContents() override
|
||||
{
|
||||
MIRStructType::ClearContents();
|
||||
parentTyIdx = TyIdx(0);
|
||||
interfacesImplemented.clear(); // for the list of interfaces the class implements
|
||||
info.clear();
|
||||
infoIsString.clear();
|
||||
staticValue.clear();
|
||||
}
|
||||
|
||||
size_t GetHashIndex() const override
|
||||
{
|
||||
return ((static_cast<size_t>(nameStrIdx) << kShiftNumOfNameStrIdx) + (typeKind << kShiftNumOfTypeKind)) %
|
||||
kTypeHashLength;
|
||||
}
|
||||
|
||||
uint32 NumberOfFieldIDs() const override;
|
||||
|
||||
private:
|
||||
TyIdx parentTyIdx {0};
|
||||
std::vector<TyIdx> interfacesImplemented {}; // for the list of interfaces the class implements
|
||||
std::vector<MIRInfoPair> info {};
|
||||
std::vector<bool> infoIsString {};
|
||||
MIREncodedArray staticValue {}; // DELETE THIS
|
||||
};
|
||||
|
||||
// used by kTypeInterface, kTypeInterfaceIncomplete
|
||||
class MIRInterfaceType : public MIRStructType {
|
||||
public:
|
||||
explicit MIRInterfaceType(MIRTypeKind tKind) : MIRStructType(tKind) {}
|
||||
MIRInterfaceType(MIRTypeKind tKind, GStrIdx strIdx) : MIRStructType(tKind, strIdx) {}
|
||||
~MIRInterfaceType() override = default;
|
||||
|
||||
bool EqualTo(const MIRType &type) const override;
|
||||
|
||||
MIRType *CopyMIRTypeNode() const override
|
||||
{
|
||||
return new MIRInterfaceType(*this);
|
||||
}
|
||||
|
||||
const std::vector<MIRInfoPair> &GetInfo() const override
|
||||
{
|
||||
return info;
|
||||
}
|
||||
void PushbackMIRInfo(const MIRInfoPair &pair) override
|
||||
{
|
||||
info.push_back(pair);
|
||||
}
|
||||
uint32 GetInfo(const std::string &infoStr) const;
|
||||
uint32 GetInfo(GStrIdx strIdx) const;
|
||||
size_t GetInfoSize() const
|
||||
{
|
||||
return info.size();
|
||||
}
|
||||
|
||||
const MIRInfoPair &GetInfoElemt(size_t n) const override
|
||||
{
|
||||
DEBUG_ASSERT(n < info.size(), "array index out of range");
|
||||
return info.at(n);
|
||||
}
|
||||
|
||||
const std::vector<bool> &GetInfoIsString() const override
|
||||
{
|
||||
return infoIsString;
|
||||
}
|
||||
void PushbackIsString(bool isString) override
|
||||
{
|
||||
infoIsString.push_back(isString);
|
||||
}
|
||||
size_t GetInfoIsStringSize() const
|
||||
{
|
||||
return infoIsString.size();
|
||||
}
|
||||
bool GetInfoIsStringElemt(size_t n) const override
|
||||
{
|
||||
DEBUG_ASSERT(n < infoIsString.size(), "array index out of range");
|
||||
return infoIsString.at(n);
|
||||
}
|
||||
|
||||
const MIREncodedArray &GetStaticValue() const override
|
||||
{
|
||||
return staticValue;
|
||||
}
|
||||
void PushbackStaticValue(EncodedValue &encodedValue) override
|
||||
{
|
||||
staticValue.push_back(encodedValue);
|
||||
}
|
||||
|
||||
std::vector<TyIdx> &GetParentsTyIdx()
|
||||
{
|
||||
return parentsTyIdx;
|
||||
}
|
||||
void SetParentsTyIdx(const std::vector<TyIdx> &parents)
|
||||
{
|
||||
parentsTyIdx = parents;
|
||||
}
|
||||
const std::vector<TyIdx> &GetParentsTyIdx() const
|
||||
{
|
||||
return parentsTyIdx;
|
||||
}
|
||||
|
||||
TyIdx GetParentsElementTyIdx(size_t i) const
|
||||
{
|
||||
DEBUG_ASSERT(i < parentsTyIdx.size(), "array index out of range");
|
||||
return parentsTyIdx[i];
|
||||
}
|
||||
|
||||
void SetParentsElementTyIdx(size_t i, TyIdx tyIdx)
|
||||
{
|
||||
DEBUG_ASSERT(i < parentsTyIdx.size(), "array index out of range");
|
||||
parentsTyIdx[i] = tyIdx;
|
||||
}
|
||||
#ifdef ARK_LITECG_DEBUG
|
||||
void Dump(int indent, bool dontUseName = false) const override;
|
||||
#endif
|
||||
bool HasVolatileField() const override;
|
||||
bool HasTypeParam() const override;
|
||||
FieldPair TraverseToFieldRef(FieldID &fieldID) const override;
|
||||
void SetComplete() override
|
||||
{
|
||||
typeKind = kTypeInterface;
|
||||
}
|
||||
|
||||
size_t GetSize() const override;
|
||||
|
||||
void ClearContents() override
|
||||
{
|
||||
MIRStructType::ClearContents();
|
||||
parentsTyIdx.clear();
|
||||
info.clear();
|
||||
infoIsString.clear();
|
||||
staticValue.clear();
|
||||
}
|
||||
|
||||
size_t GetHashIndex() const override
|
||||
{
|
||||
return ((static_cast<size_t>(nameStrIdx) << kShiftNumOfNameStrIdx) + (typeKind << kShiftNumOfTypeKind)) %
|
||||
kTypeHashLength;
|
||||
}
|
||||
|
||||
bool HasFields() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint32 NumberOfFieldIDs() const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
MIRStructType *EmbeddedStructType() override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<TyIdx> parentsTyIdx {}; // multiple inheritence
|
||||
std::vector<MIRInfoPair> info {};
|
||||
std::vector<bool> infoIsString {};
|
||||
MIREncodedArray staticValue {}; // DELETE THIS
|
||||
};
|
||||
|
||||
class MIRBitFieldType : public MIRType {
|
||||
public:
|
||||
MIRBitFieldType(uint8 field, PrimType pt) : MIRType(kTypeBitField, pt), fieldSize(field) {}
|
||||
@ -2513,7 +1674,6 @@ MIRType *GetElemType(const MIRType &arrayType);
|
||||
// aarch64 specific
|
||||
bool IsHomogeneousAggregates(const MIRType &ty, PrimType &primType, size_t &elemNum, bool firstDepth = true);
|
||||
bool IsParamStructCopyToMemory(const MIRType &ty);
|
||||
bool IsReturnInMemory(const MIRType &ty);
|
||||
#endif // MIR_FEATURE_FULL
|
||||
} // namespace maple
|
||||
|
||||
|
@ -270,60 +270,12 @@ MIRType *TypeTable::GetOrCreateFunctionType(const TyIdx &retTyIdx, const std::ve
|
||||
return typeTable.at(tyIdx);
|
||||
}
|
||||
|
||||
MIRType *TypeTable::GetOrCreateStructOrUnion(const std::string &name, const FieldVector &fields,
|
||||
const FieldVector &parentFields, MIRModule &module, bool forStruct,
|
||||
const TypeAttrs &attrs)
|
||||
{
|
||||
GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name);
|
||||
MIRStructType type(forStruct ? kTypeStruct : kTypeUnion, strIdx);
|
||||
type.SetFields(fields);
|
||||
type.SetParentFields(parentFields);
|
||||
type.SetTypeAttrs(attrs);
|
||||
|
||||
TyIdx tyIdx = GetOrCreateMIRType(&type);
|
||||
// Global?
|
||||
module.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, tyIdx);
|
||||
module.PushbackTypeDefOrder(strIdx);
|
||||
DEBUG_ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateStructOrUnion");
|
||||
return typeTable.at(tyIdx);
|
||||
}
|
||||
|
||||
void TypeTable::PushIntoFieldVector(FieldVector &fields, const std::string &name, const MIRType &type)
|
||||
{
|
||||
GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name);
|
||||
fields.push_back(FieldPair(strIdx, TyIdxFieldAttrPair(type.GetTypeIndex(), FieldAttrs())));
|
||||
}
|
||||
|
||||
MIRType *TypeTable::GetOrCreateClassOrInterface(const std::string &name, MIRModule &module, bool forClass)
|
||||
{
|
||||
GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name);
|
||||
TyIdx tyIdx = module.GetTypeNameTab()->GetTyIdxFromGStrIdx(strIdx);
|
||||
if (!tyIdx) {
|
||||
if (forClass) {
|
||||
MIRClassType type(kTypeClassIncomplete, strIdx); // for class type
|
||||
tyIdx = GetOrCreateMIRType(&type);
|
||||
} else {
|
||||
MIRInterfaceType type(kTypeInterfaceIncomplete, strIdx); // for interface type
|
||||
tyIdx = GetOrCreateMIRType(&type);
|
||||
}
|
||||
module.PushbackTypeDefOrder(strIdx);
|
||||
module.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, tyIdx);
|
||||
if (typeTable[tyIdx]->GetNameStrIdx() == 0u) {
|
||||
typeTable[tyIdx]->SetNameStrIdx(strIdx);
|
||||
}
|
||||
}
|
||||
DEBUG_ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateClassOrInterface");
|
||||
return typeTable.at(tyIdx);
|
||||
}
|
||||
|
||||
void TypeTable::AddFieldToStructType(MIRStructType &structType, const std::string &fieldName, const MIRType &fieldType)
|
||||
{
|
||||
GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fieldName);
|
||||
FieldAttrs fieldAttrs;
|
||||
fieldAttrs.SetAttr(FLDATTR_final); // Mark compiler-generated struct fields as final to improve AliasAnalysis
|
||||
structType.GetFields().push_back(FieldPair(strIdx, TyIdxFieldAttrPair(fieldType.GetTypeIndex(), fieldAttrs)));
|
||||
}
|
||||
|
||||
void FPConstTable::PostInit()
|
||||
{
|
||||
MIRType &typeFloat = *GlobalTables::GetTypeTable().GetPrimType(PTY_f32);
|
||||
|
@ -27,52 +27,6 @@ IntrinDesc IntrinDesc::intrinTable[INTRN_LAST + 1] = {
|
||||
#include "intrinsics.def"
|
||||
#undef DEF_MIR_INTRINSIC
|
||||
};
|
||||
MIRType *IntrinDesc::GetOrCreateJSValueType()
|
||||
{
|
||||
if (jsValueType != nullptr) {
|
||||
return jsValueType;
|
||||
}
|
||||
MIRBuilder *jsBuilder = mirModule->GetMIRBuilder();
|
||||
FieldVector payloadFields;
|
||||
GStrIdx i32 = jsBuilder->GetOrCreateStringIndex("i32");
|
||||
GStrIdx u32 = jsBuilder->GetOrCreateStringIndex("u32");
|
||||
GStrIdx boo = jsBuilder->GetOrCreateStringIndex("boo");
|
||||
GStrIdx ptr = jsBuilder->GetOrCreateStringIndex("ptr");
|
||||
payloadFields.push_back(
|
||||
FieldPair(i32, TyIdxFieldAttrPair(GlobalTables::GetTypeTable().GetInt32()->GetTypeIndex(), FieldAttrs())));
|
||||
payloadFields.push_back(
|
||||
FieldPair(u32, TyIdxFieldAttrPair(GlobalTables::GetTypeTable().GetUInt32()->GetTypeIndex(), FieldAttrs())));
|
||||
payloadFields.push_back(
|
||||
FieldPair(boo, TyIdxFieldAttrPair(GlobalTables::GetTypeTable().GetUInt32()->GetTypeIndex(), FieldAttrs())));
|
||||
payloadFields.push_back(
|
||||
FieldPair(ptr, TyIdxFieldAttrPair(GlobalTables::GetTypeTable().GetVoidPtr()->GetTypeIndex(), FieldAttrs())));
|
||||
FieldVector parentFields;
|
||||
MIRType *payloadType =
|
||||
GlobalTables::GetTypeTable().GetOrCreateUnionType("payload_type", payloadFields, parentFields, *mirModule);
|
||||
FieldVector sFields;
|
||||
GStrIdx payload = jsBuilder->GetOrCreateStringIndex("payload");
|
||||
GStrIdx tag = jsBuilder->GetOrCreateStringIndex("tag");
|
||||
sFields.push_back(FieldPair(payload, TyIdxFieldAttrPair(payloadType->GetTypeIndex(), FieldAttrs())));
|
||||
sFields.push_back(
|
||||
FieldPair(tag, TyIdxFieldAttrPair(GlobalTables::GetTypeTable().GetUInt32()->GetTypeIndex(), FieldAttrs())));
|
||||
MIRType *sType = GlobalTables::GetTypeTable().GetOrCreateStructType("s_type", sFields, parentFields, *mirModule);
|
||||
CHECK_FATAL(sType != nullptr, "can't get struct type, check it!");
|
||||
FieldVector jsValLayoutFields;
|
||||
GStrIdx asBits = jsBuilder->GetOrCreateStringIndex("asBits");
|
||||
GStrIdx s = jsBuilder->GetOrCreateStringIndex("s");
|
||||
GStrIdx asDouble = jsBuilder->GetOrCreateStringIndex("asDouble");
|
||||
GStrIdx asPtr = jsBuilder->GetOrCreateStringIndex("asPtr");
|
||||
jsValLayoutFields.push_back(
|
||||
FieldPair(asBits, TyIdxFieldAttrPair(GlobalTables::GetTypeTable().GetUInt64()->GetTypeIndex(), FieldAttrs())));
|
||||
jsValLayoutFields.push_back(FieldPair(s, TyIdxFieldAttrPair(sType->GetTypeIndex(), FieldAttrs())));
|
||||
jsValLayoutFields.push_back(FieldPair(
|
||||
asDouble, TyIdxFieldAttrPair(GlobalTables::GetTypeTable().GetDouble()->GetTypeIndex(), FieldAttrs())));
|
||||
jsValLayoutFields.push_back(
|
||||
FieldPair(asPtr, TyIdxFieldAttrPair(GlobalTables::GetTypeTable().GetVoidPtr()->GetTypeIndex(), FieldAttrs())));
|
||||
MIRType *jsValLayoutType = GlobalTables::GetTypeTable().GetOrCreateUnionType("jsval_layout_type", jsValLayoutFields,
|
||||
parentFields, *mirModule);
|
||||
return jsValLayoutType;
|
||||
}
|
||||
|
||||
void IntrinDesc::InitMIRModule(MIRModule *mod)
|
||||
{
|
||||
|
@ -17,212 +17,6 @@
|
||||
#include "mir_symbol_builder.h"
|
||||
|
||||
namespace maple {
|
||||
// This is for compiler-generated metadata 1-level struct
|
||||
void MIRBuilder::AddIntFieldConst(const MIRStructType &sType, MIRAggConst &newConst, uint32 fieldID, int64 constValue)
|
||||
{
|
||||
DEBUG_ASSERT(fieldID > 0, "must not be zero");
|
||||
auto *fieldConst =
|
||||
GlobalTables::GetIntConstTable().GetOrCreateIntConst(constValue, *sType.GetElemType(fieldID - 1));
|
||||
newConst.AddItem(fieldConst, fieldID);
|
||||
}
|
||||
|
||||
// This is for compiler-generated metadata 1-level struct
|
||||
void MIRBuilder::AddAddrofFieldConst(const MIRStructType &structType, MIRAggConst &newConst, uint32 fieldID,
|
||||
const MIRSymbol &fieldSymbol)
|
||||
{
|
||||
AddrofNode *fieldExpr = CreateExprAddrof(0, fieldSymbol, mirModule->GetMemPool());
|
||||
DEBUG_ASSERT(fieldID > 0, "must not be zero");
|
||||
auto *fieldConst = mirModule->GetMemPool()->New<MIRAddrofConst>(fieldExpr->GetStIdx(), fieldExpr->GetFieldID(),
|
||||
*structType.GetElemType(fieldID - 1));
|
||||
newConst.AddItem(fieldConst, fieldID);
|
||||
}
|
||||
|
||||
// This is for compiler-generated metadata 1-level struct
|
||||
void MIRBuilder::AddAddroffuncFieldConst(const MIRStructType &structType, MIRAggConst &newConst, uint32 fieldID,
|
||||
const MIRSymbol &funcSymbol)
|
||||
{
|
||||
MIRConst *fieldConst = nullptr;
|
||||
MIRFunction *vMethod = funcSymbol.GetFunction();
|
||||
if (vMethod->IsAbstract()) {
|
||||
DEBUG_ASSERT(fieldID > 0, "must not be zero");
|
||||
fieldConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(0, *structType.GetElemType(fieldID - 1));
|
||||
} else {
|
||||
AddroffuncNode *addrofFuncExpr =
|
||||
CreateExprAddroffunc(funcSymbol.GetFunction()->GetPuidx(), mirModule->GetMemPool());
|
||||
DEBUG_ASSERT(fieldID > 0, "must not be zero");
|
||||
fieldConst = mirModule->GetMemPool()->New<MIRAddroffuncConst>(addrofFuncExpr->GetPUIdx(),
|
||||
*structType.GetElemType(fieldID - 1));
|
||||
}
|
||||
newConst.AddItem(fieldConst, fieldID);
|
||||
}
|
||||
|
||||
// fieldID is continuously being updated during traversal;
|
||||
// when the field is found, its field id is returned via fieldID
|
||||
bool MIRBuilder::TraverseToNamedField(MIRStructType &structType, GStrIdx nameIdx, uint32 &fieldID)
|
||||
{
|
||||
TyIdx tid(0);
|
||||
return TraverseToNamedFieldWithTypeAndMatchStyle(structType, nameIdx, tid, fieldID, kMatchAnyField);
|
||||
}
|
||||
|
||||
// traverse parent first but match self first.
|
||||
void MIRBuilder::TraverseToNamedFieldWithType(MIRStructType &structType, GStrIdx nameIdx, TyIdx typeIdx,
|
||||
uint32 &fieldID, uint32 &idx)
|
||||
{
|
||||
if (structType.IsIncomplete()) {
|
||||
(void)incompleteTypeRefedSet.insert(structType.GetTypeIndex());
|
||||
}
|
||||
// process parent
|
||||
if (structType.GetKind() == kTypeClass || structType.GetKind() == kTypeClassIncomplete) {
|
||||
auto &classType = static_cast<MIRClassType &>(structType);
|
||||
MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(classType.GetParentTyIdx());
|
||||
auto *parentType = static_cast<MIRStructType *>(type);
|
||||
if (parentType != nullptr) {
|
||||
++fieldID;
|
||||
TraverseToNamedFieldWithType(*parentType, nameIdx, typeIdx, fieldID, idx);
|
||||
}
|
||||
}
|
||||
for (uint32 fieldIdx = 0; fieldIdx < structType.GetFieldsSize(); ++fieldIdx) {
|
||||
++fieldID;
|
||||
TyIdx fieldTyIdx = structType.GetFieldsElemt(fieldIdx).second.first;
|
||||
MIRType *fieldType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldTyIdx);
|
||||
if (structType.GetFieldsElemt(fieldIdx).first == nameIdx) {
|
||||
if (typeIdx == 0u || fieldTyIdx == typeIdx) {
|
||||
idx = fieldID;
|
||||
continue;
|
||||
}
|
||||
// for pointer type, check their pointed type
|
||||
MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(typeIdx);
|
||||
if (type->IsOfSameType(*fieldType)) {
|
||||
idx = fieldID;
|
||||
}
|
||||
}
|
||||
|
||||
if (fieldType->IsStructType()) {
|
||||
auto *subStructType = static_cast<MIRStructType *>(fieldType);
|
||||
TraverseToNamedFieldWithType(*subStructType, nameIdx, typeIdx, fieldID, idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fieldID is continuously being updated during traversal;
|
||||
// when the field is found, its field id is returned via fieldID
|
||||
//
|
||||
// typeidx: TyIdx(0) means do not check types.
|
||||
// matchstyle: 0: do not match but traverse to update fieldID
|
||||
// 1: match top level field only
|
||||
// 2: match any field
|
||||
// 4: traverse parent first
|
||||
// 0xc: do not match but traverse to update fieldID, traverse parent first, found in child
|
||||
bool MIRBuilder::TraverseToNamedFieldWithTypeAndMatchStyle(MIRStructType &structType, GStrIdx nameIdx, TyIdx typeIdx,
|
||||
uint32 &fieldID, unsigned int matchStyle)
|
||||
{
|
||||
if (structType.IsIncomplete()) {
|
||||
(void)incompleteTypeRefedSet.insert(structType.GetTypeIndex());
|
||||
}
|
||||
if (matchStyle & kParentFirst) {
|
||||
// process parent
|
||||
if ((structType.GetKind() != kTypeClass) && (structType.GetKind() != kTypeClassIncomplete)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto &classType = static_cast<MIRClassType &>(structType);
|
||||
MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(classType.GetParentTyIdx());
|
||||
auto *parentType = static_cast<MIRStructType *>(type);
|
||||
if (parentType != nullptr) {
|
||||
++fieldID;
|
||||
if (matchStyle == (kFoundInChild | kParentFirst | kUpdateFieldID)) {
|
||||
matchStyle = kParentFirst;
|
||||
uint32 idxBackup = nameIdx;
|
||||
nameIdx.reset();
|
||||
// do not match but traverse to update fieldID, traverse parent first
|
||||
TraverseToNamedFieldWithTypeAndMatchStyle(*parentType, nameIdx, typeIdx, fieldID, matchStyle);
|
||||
nameIdx.reset(idxBackup);
|
||||
} else if (TraverseToNamedFieldWithTypeAndMatchStyle(*parentType, nameIdx, typeIdx, fieldID, matchStyle)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (uint32 fieldIdx = 0; fieldIdx < structType.GetFieldsSize(); ++fieldIdx) {
|
||||
++fieldID;
|
||||
TyIdx fieldTyIdx = structType.GetFieldsElemt(fieldIdx).second.first;
|
||||
MIRType *fieldType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldTyIdx);
|
||||
DEBUG_ASSERT(fieldType != nullptr, "fieldType is null");
|
||||
if (matchStyle && structType.GetFieldsElemt(fieldIdx).first == nameIdx) {
|
||||
if (typeIdx == 0u || fieldTyIdx == typeIdx ||
|
||||
fieldType->IsOfSameType(*GlobalTables::GetTypeTable().GetTypeFromTyIdx(typeIdx))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
unsigned int style = matchStyle & kMatchAnyField;
|
||||
if (fieldType->IsStructType()) {
|
||||
auto *subStructType = static_cast<MIRStructType *>(fieldType);
|
||||
if (TraverseToNamedFieldWithTypeAndMatchStyle(*subStructType, nameIdx, typeIdx, fieldID, style)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FieldID MIRBuilder::GetStructFieldIDFromNameAndType(MIRType &type, const std::string &name, TyIdx idx,
|
||||
unsigned int matchStyle)
|
||||
{
|
||||
auto &structType = static_cast<MIRStructType &>(type);
|
||||
uint32 fieldID = 0;
|
||||
GStrIdx strIdx = GetStringIndex(name);
|
||||
if (TraverseToNamedFieldWithTypeAndMatchStyle(structType, strIdx, idx, fieldID, matchStyle)) {
|
||||
return fieldID;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
FieldID MIRBuilder::GetStructFieldIDFromNameAndType(MIRType &type, const std::string &name, TyIdx idx)
|
||||
{
|
||||
return GetStructFieldIDFromNameAndType(type, name, idx, kMatchAnyField);
|
||||
}
|
||||
|
||||
FieldID MIRBuilder::GetStructFieldIDFromNameAndTypeParentFirst(MIRType &type, const std::string &name, TyIdx idx)
|
||||
{
|
||||
return GetStructFieldIDFromNameAndType(type, name, idx, kParentFirst);
|
||||
}
|
||||
|
||||
FieldID MIRBuilder::GetStructFieldIDFromNameAndTypeParentFirstFoundInChild(MIRType &type, const std::string &name,
|
||||
TyIdx idx)
|
||||
{
|
||||
// do not match but traverse to update fieldID, traverse parent first, found in child
|
||||
return GetStructFieldIDFromNameAndType(type, name, idx, kFoundInChild | kParentFirst | kUpdateFieldID);
|
||||
}
|
||||
|
||||
FieldID MIRBuilder::GetStructFieldIDFromFieldName(MIRType &type, const std::string &name)
|
||||
{
|
||||
return GetStructFieldIDFromNameAndType(type, name, TyIdx(0), kMatchAnyField);
|
||||
}
|
||||
|
||||
FieldID MIRBuilder::GetStructFieldIDFromFieldNameParentFirst(MIRType *type, const std::string &name)
|
||||
{
|
||||
if (type == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return GetStructFieldIDFromNameAndType(*type, name, TyIdx(0), kParentFirst);
|
||||
}
|
||||
|
||||
void MIRBuilder::SetStructFieldIDFromFieldName(MIRStructType &structType, const std::string &name, GStrIdx newStrIdx,
|
||||
const MIRType &newFieldType)
|
||||
{
|
||||
uint32 fieldID = 0;
|
||||
GStrIdx strIdx = GetStringIndex(name);
|
||||
while (true) {
|
||||
if (structType.GetElemStrIdx(fieldID) == strIdx) {
|
||||
if (newStrIdx != 0u) {
|
||||
structType.SetElemStrIdx(fieldID, newStrIdx);
|
||||
}
|
||||
structType.SetElemtTyIdx(fieldID, newFieldType.GetTypeIndex());
|
||||
return;
|
||||
}
|
||||
++fieldID;
|
||||
}
|
||||
}
|
||||
|
||||
// create a function named str
|
||||
MIRFunction *MIRBuilder::GetOrCreateFunction(const std::string &str, TyIdx retTyIdx)
|
||||
{
|
||||
|
@ -24,7 +24,6 @@ namespace {
|
||||
using namespace maple;
|
||||
enum FuncProp : uint32_t {
|
||||
kFuncPropHasCall = 1U, // the function has call
|
||||
kFuncPropRetStruct = 1U << 1, // the function returns struct
|
||||
kFuncPropUserFunc = 1U << 2, // the function is a user func
|
||||
kFuncPropInfoPrinted = 1U << 3, // to avoid printing frameSize/moduleid/funcSize info more
|
||||
// than once per function since they
|
||||
@ -32,7 +31,6 @@ enum FuncProp : uint32_t {
|
||||
kFuncPropNeverReturn = 1U << 4, // the function when called never returns
|
||||
kFuncPropHasSetjmp = 1U << 5, // the function contains call to setjmp
|
||||
kFuncPropHasAsm = 1U << 6, // the function has use of inline asm
|
||||
kFuncPropStructReturnedInRegs = 1U << 7, // the function returns struct in registers
|
||||
};
|
||||
} // namespace
|
||||
|
||||
@ -168,36 +166,6 @@ void MIRFunction::SetHasCall()
|
||||
flag |= kFuncPropHasCall;
|
||||
}
|
||||
|
||||
bool MIRFunction::IsReturnStruct() const
|
||||
{
|
||||
return flag & kFuncPropRetStruct;
|
||||
}
|
||||
void MIRFunction::SetReturnStruct()
|
||||
{
|
||||
flag |= kFuncPropRetStruct;
|
||||
}
|
||||
void MIRFunction::SetReturnStruct(const MIRType &retType)
|
||||
{
|
||||
if (retType.IsStructType()) {
|
||||
flag |= kFuncPropRetStruct;
|
||||
}
|
||||
}
|
||||
void MIRFunction::SetReturnStruct(const MIRType *retType)
|
||||
{
|
||||
switch (retType->GetKind()) {
|
||||
case kTypeUnion:
|
||||
case kTypeStruct:
|
||||
case kTypeStructIncomplete:
|
||||
case kTypeClass:
|
||||
case kTypeClassIncomplete:
|
||||
case kTypeInterface:
|
||||
case kTypeInterfaceIncomplete:
|
||||
flag |= kFuncPropRetStruct;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
bool MIRFunction::IsUserFunc() const
|
||||
{
|
||||
return flag & kFuncPropUserFunc;
|
||||
@ -249,16 +217,6 @@ bool MIRFunction::HasAsm() const
|
||||
return ((flag & kFuncPropHasAsm) != kTypeflagZero);
|
||||
}
|
||||
|
||||
void MIRFunction::SetStructReturnedInRegs()
|
||||
{
|
||||
flag |= kFuncPropStructReturnedInRegs;
|
||||
}
|
||||
|
||||
bool MIRFunction::StructReturnedInRegs() const
|
||||
{
|
||||
return ((flag & kFuncPropStructReturnedInRegs) != kTypeflagZero);
|
||||
}
|
||||
|
||||
void MIRFunction::SetAttrsFromSe(uint8 specialEffect)
|
||||
{
|
||||
// NoPrivateDefEffect
|
||||
|
@ -789,11 +789,6 @@ MIRFuncType *MIRLower::FuncTypeFromFuncPtrExpr(BaseNode *x)
|
||||
if (preg->GetOp() == OP_dread) {
|
||||
const MIRSymbol *symbol = preg->rematInfo.sym;
|
||||
MIRType *mirType = symbol->GetType();
|
||||
if (preg->fieldID != 0) {
|
||||
MIRStructType *structty = static_cast<MIRStructType *>(mirType);
|
||||
FieldPair thepair = structty->TraverseToField(preg->fieldID);
|
||||
mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first);
|
||||
}
|
||||
|
||||
if (mirType->GetKind() == kTypePointer) {
|
||||
res = static_cast<MIRPtrType *>(mirType)->GetPointedFuncType();
|
||||
@ -821,11 +816,6 @@ MIRFuncType *MIRLower::FuncTypeFromFuncPtrExpr(BaseNode *x)
|
||||
DreadNode *dread = static_cast<DreadNode *>(x);
|
||||
MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx());
|
||||
MIRType *mirType = symbol->GetType();
|
||||
if (dread->GetFieldID() != 0) {
|
||||
MIRStructType *structty = static_cast<MIRStructType *>(mirType);
|
||||
FieldPair thepair = structty->TraverseToField(dread->GetFieldID());
|
||||
mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first);
|
||||
}
|
||||
if (mirType->GetKind() == kTypePointer) {
|
||||
res = static_cast<MIRPtrType *>(mirType)->GetPointedFuncType();
|
||||
}
|
||||
|
@ -246,18 +246,6 @@ void MIRModule::DumpGlobals(bool emitStructureType) const
|
||||
const std::string &name = GlobalTables::GetStrTable().GetStringFromStrIdx(*it);
|
||||
MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
|
||||
DEBUG_ASSERT(type != nullptr, "type should not be nullptr here");
|
||||
bool isStructType = type->IsStructType();
|
||||
if (isStructType) {
|
||||
auto *structType = static_cast<MIRStructType *>(type);
|
||||
// still emit what in extern_structtype_set_
|
||||
if (!emitStructureType &&
|
||||
externStructTypeSet.find(structType->GetTypeIndex()) == externStructTypeSet.end()) {
|
||||
continue;
|
||||
}
|
||||
if (structType->IsImported()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
LogInfo::MapleLogger() << "type $" << name << " ";
|
||||
if (type->GetKind() == kTypeByName) {
|
||||
@ -395,13 +383,6 @@ void MIRModule::DumpDefType()
|
||||
const std::string &name = GlobalTables::GetStrTable().GetStringFromStrIdx(*it);
|
||||
MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
|
||||
DEBUG_ASSERT(type != nullptr, "type should not be nullptr here");
|
||||
bool isStructType = type->IsStructType();
|
||||
if (isStructType) {
|
||||
auto *structType = static_cast<MIRStructType *>(type);
|
||||
if (structType->IsImported()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
LogInfo::MapleLogger() << "type $" << name << " ";
|
||||
if (type->GetKind() == kTypeByName) {
|
||||
LogInfo::MapleLogger() << "void";
|
||||
@ -480,85 +461,6 @@ const std::string &MIRModule::GetFileNameFromFileNum(uint32 fileNum) const
|
||||
}
|
||||
|
||||
#ifdef ARK_LITECG_DEBUG
|
||||
void MIRModule::DumpTypeTreeToCxxHeaderFile(MIRType &ty, std::unordered_set<MIRType *> &dumpedClasses) const
|
||||
{
|
||||
if (dumpedClasses.find(&ty) != dumpedClasses.end()) {
|
||||
return;
|
||||
}
|
||||
// first, insert ty to the dumped_classes to prevent infinite recursion
|
||||
(void)dumpedClasses.insert(&ty);
|
||||
DEBUG_ASSERT(ty.GetKind() == kTypeClass || ty.GetKind() == kTypeStruct || ty.GetKind() == kTypeUnion ||
|
||||
ty.GetKind() == kTypeInterface,
|
||||
"Unexpected MIRType.");
|
||||
/* No need to emit interfaces; because "interface variables are
|
||||
final and static by default and methods are public and abstract"
|
||||
*/
|
||||
if (ty.GetKind() == kTypeInterface) {
|
||||
return;
|
||||
}
|
||||
// dump all of its parents
|
||||
if (srcLang == kSrcLangC || srcLang == kSrcLangCPlusPlus) {
|
||||
DEBUG_ASSERT((ty.GetKind() == kTypeStruct || ty.GetKind() == kTypeUnion),
|
||||
"type should be either struct or union");
|
||||
} else {
|
||||
DEBUG_ASSERT(false, "source languages other than C/C++ are not supported yet");
|
||||
}
|
||||
if (srcLang == kSrcLangC || srcLang == kSrcLangCPlusPlus) {
|
||||
// how to access parent fields????
|
||||
DEBUG_ASSERT(false, "not yet implemented");
|
||||
}
|
||||
}
|
||||
|
||||
void MIRModule::DumpToCxxHeaderFile(std::set<std::string> &leafClasses, const std::string &pathToOutf) const
|
||||
{
|
||||
if (pathToOutf.empty()) {
|
||||
return;
|
||||
}
|
||||
std::ofstream mpltFile;
|
||||
mpltFile.open(pathToOutf, std::ios::trunc);
|
||||
std::streambuf *backup = LogInfo::MapleLogger().rdbuf();
|
||||
LogInfo::MapleLogger().rdbuf(mpltFile.rdbuf()); // change cout's buffer to that of file
|
||||
char *headerGuard = strdup(pathToOutf.c_str());
|
||||
CHECK_FATAL(headerGuard != nullptr, "strdup failed");
|
||||
for (char *p = headerGuard; *p; ++p) {
|
||||
if (!isalnum(*p)) {
|
||||
*p = '_';
|
||||
} else if (isalpha(*p) && islower(*p)) {
|
||||
*p = toupper(*p);
|
||||
}
|
||||
}
|
||||
// define a hash table
|
||||
std::unordered_set<MIRType *> dumpedClasses;
|
||||
const char *prefix = "__SRCLANG_UNKNOWN_";
|
||||
if (srcLang == kSrcLangC || srcLang == kSrcLangCPlusPlus) {
|
||||
prefix = "__SRCLANG_CXX_";
|
||||
}
|
||||
LogInfo::MapleLogger() << "#ifndef " << prefix << headerGuard << "__\n";
|
||||
LogInfo::MapleLogger() << "#define " << prefix << headerGuard << "__\n";
|
||||
LogInfo::MapleLogger() << "/* this file is compiler-generated; do not edit */\n\n";
|
||||
LogInfo::MapleLogger() << "#include <stdint.h>\n";
|
||||
LogInfo::MapleLogger() << "#include <complex.h>\n";
|
||||
for (auto &s : leafClasses) {
|
||||
CHECK_FATAL(!s.empty(), "string is null");
|
||||
GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(s);
|
||||
TyIdx tyIdx = typeNameTab->GetTyIdxFromGStrIdx(strIdx);
|
||||
MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
|
||||
if (ty == nullptr) {
|
||||
continue;
|
||||
}
|
||||
DEBUG_ASSERT(ty->GetKind() == kTypeClass || ty->GetKind() == kTypeStruct || ty->GetKind() == kTypeUnion ||
|
||||
ty->GetKind() == kTypeInterface,
|
||||
"");
|
||||
DumpTypeTreeToCxxHeaderFile(*ty, dumpedClasses);
|
||||
}
|
||||
LogInfo::MapleLogger() << "#endif /* " << prefix << headerGuard << "__ */\n";
|
||||
/* restore cout */
|
||||
LogInfo::MapleLogger().rdbuf(backup);
|
||||
free(headerGuard);
|
||||
headerGuard = nullptr;
|
||||
mpltFile.close();
|
||||
}
|
||||
|
||||
void MIRModule::DumpClassToFile(const std::string &path) const
|
||||
{
|
||||
std::string strPath(path);
|
||||
|
@ -68,76 +68,11 @@ bool BaseNode::MayThrowException()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AddrofNode::CheckNode(const MIRModule &mod) const
|
||||
{
|
||||
const MIRSymbol *st = mod.CurFunction()->GetLocalOrGlobalSymbol(GetStIdx());
|
||||
DEBUG_ASSERT(st != nullptr, "null ptr check");
|
||||
MIRType *ty = st->GetType();
|
||||
switch (ty->GetKind()) {
|
||||
case kTypeScalar: {
|
||||
return IsPrimitiveScalar(GetPrimType());
|
||||
}
|
||||
case kTypeArray: {
|
||||
return GetPrimType() == PTY_agg;
|
||||
}
|
||||
case kTypeUnion:
|
||||
case kTypeStruct:
|
||||
case kTypeStructIncomplete: {
|
||||
if (GetFieldID() == 0) {
|
||||
return GetPrimType() == PTY_agg;
|
||||
}
|
||||
auto *structType = static_cast<MIRStructType *>(ty);
|
||||
TyIdx fTyIdx = structType->GetFieldTyIdx(fieldID);
|
||||
MIRType *subType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fTyIdx);
|
||||
MIRTypeKind subKind = subType->GetKind();
|
||||
return (subKind == kTypeBitField) ||
|
||||
(subKind == kTypeScalar && IsPrimitiveScalar(GetPrimType())) ||
|
||||
(subKind == kTypePointer && IsPrimitivePoint(GetPrimType())) ||
|
||||
(subKind == kTypeStruct && GetPrimType() == PTY_agg) || (fTyIdx != 0u && GetPrimType() == PTY_agg);
|
||||
}
|
||||
case kTypeClass:
|
||||
case kTypeClassIncomplete: {
|
||||
if (fieldID == 0) {
|
||||
return GetPrimType() == PTY_agg;
|
||||
}
|
||||
auto *classType = static_cast<MIRClassType *>(ty);
|
||||
MIRType *subType = classType->GetFieldType(fieldID);
|
||||
MIRTypeKind subKind = subType->GetKind();
|
||||
return (subKind == kTypeBitField) ||
|
||||
(subKind == kTypeScalar && IsPrimitiveScalar(GetPrimType())) ||
|
||||
(subKind == kTypePointer && IsPrimitivePoint(GetPrimType())) ||
|
||||
(subKind == kTypeStruct && GetPrimType() == PTY_agg);
|
||||
}
|
||||
case kTypeInterface:
|
||||
case kTypeInterfaceIncomplete: {
|
||||
if (fieldID == 0) {
|
||||
return GetPrimType() == PTY_agg;
|
||||
}
|
||||
auto *interfaceType = static_cast<MIRInterfaceType *>(ty);
|
||||
MIRType *subType = interfaceType->GetFieldType(fieldID);
|
||||
MIRTypeKind subKind = subType->GetKind();
|
||||
return (subKind == kTypeBitField) ||
|
||||
(subKind == kTypeScalar && IsPrimitiveScalar(GetPrimType())) ||
|
||||
(subKind == kTypePointer && IsPrimitivePoint(GetPrimType())) ||
|
||||
(subKind == kTypeStruct && GetPrimType() == PTY_agg);
|
||||
}
|
||||
case kTypePointer:
|
||||
return IsPrimitivePoint(GetPrimType());
|
||||
case kTypeParam:
|
||||
case kTypeGenericInstant:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
MIRType *IreadNode::GetType() const
|
||||
{
|
||||
MIRPtrType *ptrtype = static_cast<MIRPtrType *>(GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx));
|
||||
if (fieldID == 0) {
|
||||
return ptrtype->GetPointedType();
|
||||
}
|
||||
return GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrtype->GetPointedTyIdxWithFieldID(fieldID));
|
||||
CHECK_FATAL(fieldID == 0, "fieldID must be 0");
|
||||
return ptrtype->GetPointedType();
|
||||
}
|
||||
|
||||
bool IreadNode::IsVolatile() const
|
||||
@ -1435,26 +1370,6 @@ inline MIRTypeKind GetPointedTypeKind(TyIdx tyIdx)
|
||||
return pointedType->GetKind();
|
||||
}
|
||||
|
||||
MIRTypeKind GetFieldTypeKind(MIRStructType *structType, FieldID fieldId)
|
||||
{
|
||||
TyIdx fieldTyIdx;
|
||||
if (fieldId > 0) {
|
||||
MIRType *mirType = structType->GetFieldType(fieldId);
|
||||
fieldTyIdx = mirType->GetTypeIndex();
|
||||
} else {
|
||||
DEBUG_ASSERT(static_cast<unsigned>(-fieldId) < structType->GetParentFieldsSize() + 1,
|
||||
"array index out of range");
|
||||
fieldTyIdx = structType->GetParentFieldsElemt(-fieldId - 1).second.first;
|
||||
}
|
||||
return GetTypeKind(fieldTyIdx);
|
||||
}
|
||||
|
||||
inline bool IsStructureTypeKind(MIRTypeKind kind)
|
||||
{
|
||||
return kind == kTypeStruct || kind == kTypeStructIncomplete || kind == kTypeUnion || kind == kTypeClass ||
|
||||
kind == kTypeClassIncomplete || kind == kTypeInterface || kind == kTypeInterfaceIncomplete;
|
||||
}
|
||||
|
||||
bool IsSignedType(const BaseNode *opnd)
|
||||
{
|
||||
switch (opnd->GetPrimType()) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -91,21 +91,6 @@ public:
|
||||
if (typeAttr.GetAttr(ATTR_oneelem_simd)) {
|
||||
return true;
|
||||
}
|
||||
if (fieldID != 0) {
|
||||
auto type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(symOrPreg.mirSt->GetTyIdx());
|
||||
if (type->IsMIRArrayType()) {
|
||||
type = static_cast<MIRArrayType *>(type)->GetElemType();
|
||||
}
|
||||
if (!type->IsMIRStructType()) {
|
||||
return false;
|
||||
}
|
||||
MIRStructType *structType = static_cast<MIRStructType *>(
|
||||
GlobalTables::GetTypeTable().GetTypeFromTyIdx(symOrPreg.mirSt->GetTyIdx()));
|
||||
FieldAttrs fattrs = structType->GetFieldAttrs(fieldID);
|
||||
if (fattrs.GetAttr(FLDATTR_oneelem_simd)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1395,13 +1395,6 @@ static bool ExtractbitsRedundant(const ExtractbitsNode &x, MIRFunction &f)
|
||||
MIRSymbol *sym = f.GetLocalOrGlobalSymbol(dread->GetStIdx());
|
||||
ASSERT_NOT_NULL(sym);
|
||||
mirType = sym->GetType();
|
||||
if (dread->GetFieldID() != 0) {
|
||||
MIRStructType *structType = dynamic_cast<MIRStructType*>(mirType);
|
||||
if (structType == nullptr) {
|
||||
return false;
|
||||
}
|
||||
mirType = structType->GetFieldType(dread->GetFieldID());
|
||||
}
|
||||
} else if (opnd->GetOpCode() == OP_iread) {
|
||||
IreadNode *iread = static_cast<IreadNode*>(opnd);
|
||||
MIRPtrType *ptrType =
|
||||
@ -1410,13 +1403,6 @@ static bool ExtractbitsRedundant(const ExtractbitsNode &x, MIRFunction &f)
|
||||
return false;
|
||||
}
|
||||
mirType = ptrType->GetPointedType();
|
||||
if (iread->GetFieldID() != 0) {
|
||||
MIRStructType *structType = dynamic_cast<MIRStructType*>(mirType);
|
||||
if (structType == nullptr) {
|
||||
return false;
|
||||
}
|
||||
mirType = structType->GetFieldType(iread->GetFieldID());
|
||||
}
|
||||
} else if (opnd->GetOpCode() == OP_extractbits &&
|
||||
x.GetBitsSize() > static_cast<ExtractbitsNode*>(opnd)->GetBitsSize()) {
|
||||
return (x.GetOpCode() == OP_zext && x.GetPrimType() == opnd->GetPrimType() &&
|
||||
@ -1488,10 +1474,6 @@ std::pair<BaseNode*, std::optional<IntVal>> ConstantFold::FoldIread(IreadNode *n
|
||||
TyIdx typeId = msy->GetTyIdx();
|
||||
CHECK_FATAL(!GlobalTables::GetTypeTable().GetTypeTable().empty(), "container check");
|
||||
MIRType *msyType = GlobalTables::GetTypeTable().GetTypeTable()[typeId];
|
||||
if (addrofNode->GetFieldID() != 0) {
|
||||
CHECK_FATAL(msyType->IsStructType(), "must be");
|
||||
msyType = static_cast<MIRStructType*>(msyType)->GetFieldType(addrofNode->GetFieldID());
|
||||
}
|
||||
MIRPtrType *ptrType = static_cast<MIRPtrType *>(GlobalTables::GetTypeTable().GetTypeFromTyIdx(node->GetTyIdx()));
|
||||
// If the high level type of iaddrof/iread doesn't match
|
||||
// the type of addrof's rhs, this optimization cannot be done.
|
||||
|
Loading…
Reference in New Issue
Block a user