diff --git a/src/maple_ir/include/global_tables.h b/src/maple_ir/include/global_tables.h index afc8ac4bb3684e4e8452ef65318e02bf9a26ded4..5e8bce42e95cc339968460f27df720b4e0e94fd7 100644 --- a/src/maple_ir/include/global_tables.h +++ b/src/maple_ir/include/global_tables.h @@ -116,7 +116,9 @@ class TypeTable { void SetTypeWithTyIdx(const TyIdx &tyIdx, MIRType &type); - TyIdx GetOrCreateMIRType(MIRType *pType); + MIRType *CreateAndUpdateMirTypeNode(MIRType *pType); + MIRType *GetOrCreateMIRTypeNode(MIRType *ptype); + TyIdx GetOrCreateMIRType(MIRType *pType) { return GetOrCreateMIRTypeNode(pType)->GetTypeIndex(); } size_t GetTypeTableSize() const { return typeTable.size(); @@ -362,6 +364,8 @@ class TypeTable { void PutToHashTable(MIRType *mirType); std::unordered_set typeHashTable; + std::unordered_map ptrTypeMap; + std::unordered_map refTypeMap; std::vector typeTable; }; diff --git a/src/maple_ir/src/global_tables.cpp b/src/maple_ir/src/global_tables.cpp index d12855f1e829074402cd69ac3196a5f121711848..e29f6ff170b6c519ed7b3d1307f0e446b172f8dc 100644 --- a/src/maple_ir/src/global_tables.cpp +++ b/src/maple_ir/src/global_tables.cpp @@ -27,7 +27,7 @@ MIRType *TypeTable::CreateMirType(uint32 primTypeIdx) const { return mirType; } -TypeTable::TypeTable() { +TypeTable::TypeTable() : ptrTypeMap(), refTypeMap() { // enter the primitve types in type_table_ typeTable.push_back(static_cast(nullptr)); ASSERT(typeTable.size() == static_cast(PTY_void), "use PTY_void as the first index to type table"); @@ -63,16 +63,43 @@ void TypeTable::PutToHashTable(MIRType *mirType) { typeHashTable.insert(mirType); } -TyIdx TypeTable::GetOrCreateMIRType(MIRType *pType) { - { - const auto it = typeHashTable.find(pType); - if (it != typeHashTable.end()) { - return (*it)->GetTypeIndex(); +MIRType *TypeTable::CreateAndUpdateMirTypeNode(MIRType *ptype) { + MIRType *ntype = ptype->CopyMIRTypeNode(); + ntype->SetTypeIndex(TyIdx(typeTable.size())); + typeTable.push_back(ntype); + + if (ptype->GetKind() == kTypePointer) { + MIRPtrType *pty = static_cast(ptype); + if (pty->GetPrimType() == PTY_ptr) { + ptrTypeMap[pty->GetPointedTyIdx()] = ntype->GetTypeIndex(); + } else { + refTypeMap[pty->GetPointedTyIdx()] = ntype->GetTypeIndex(); + } + } else { + typeHashTable.insert(ntype); + } + return ntype; +} + +MIRType* TypeTable::GetOrCreateMIRTypeNode(MIRType *ptype) { + if (ptype->GetKind() == kTypePointer) { + MIRPtrType *type = static_cast(ptype); + auto *pMap = (type->GetPrimType() == PTY_ptr ? &ptrTypeMap : &refTypeMap); + auto *otherPMap = (type->GetPrimType() == PTY_ref ? &ptrTypeMap : &refTypeMap); + auto it = pMap->find(type->GetPointedTyIdx()); + if (it != pMap->end()) { + return GetTypeFromTyIdx(it->second); } + CHECK_FATAL(!((PrimType)(type->GetPointedTyIdx().GetIdx()) >= kPtyDerived && type->GetPrimType() == PTY_ref && + otherPMap->find(type->GetPointedTyIdx()) != otherPMap->end()), "GetOrCreateMIRType: ref pointed-to type %d has previous ptr occurrence", type->GetPointedTyIdx().GetIdx()); + return CreateAndUpdateMirTypeNode(ptype); + } + + auto it = typeHashTable.find(ptype); + if (it != typeHashTable.end()) { + return *it; } - MIRType *newTy = CreateType(*pType); - PutToHashTable(newTy); - return newTy->GetTypeIndex(); + return CreateAndUpdateMirTypeNode(ptype); } MIRType *TypeTable::voidPtrType = nullptr;