diff --git a/src/mapleall/maple_me/include/alias_class.h b/src/mapleall/maple_me/include/alias_class.h index 9486b5d3f544a650f3089ff74ec934b9fed44fd1..37c59257c401351bcb111863f1774de8e937288c 100644 --- a/src/mapleall/maple_me/include/alias_class.h +++ b/src/mapleall/maple_me/include/alias_class.h @@ -196,6 +196,7 @@ class AliasClass : public AnalysisResult { void ApplyUnionForDassignCopy(AliasElem &lhsAe, AliasElem *rhsAe, BaseNode &rhs); bool SetNextLevNADSForEscapePtr(AliasElem &lhsAe, BaseNode &rhs); void CreateMirroringAliasElems(const OriginalSt *ost1, OriginalSt *ost2); + void UnionNextLevelOfAliasOst(std::set &aesToUnionNextLev); AliasElem *FindOrCreateDummyNADSAe(); AliasElem &FindOrCreateAliasElemOfAddrofOSt(OriginalSt &oSt); void CollectMayDefForMustDefs(const StmtNode &stmt, std::set &mayDefOsts); diff --git a/src/mapleall/maple_me/src/alias_class.cpp b/src/mapleall/maple_me/src/alias_class.cpp index 2739d736cc7d29641249b7f314c0f83055a11c57..017b38ec20c3d4f0b1995f2c8defa934e8ccec21 100644 --- a/src/mapleall/maple_me/src/alias_class.cpp +++ b/src/mapleall/maple_me/src/alias_class.cpp @@ -338,7 +338,7 @@ AliasInfo AliasClass::CreateAliasElemsExpr(BaseNode &expr) { auto *opnd = expr.Opnd(1); if (!opnd->IsConstval() || !IsAddress(expr.GetPrimType())) { - return AliasInfo(aliasInfo.ae, aliasInfo.fieldID, OffsetType::InvalidOffset()); + return AliasInfo(aliasInfo.ae, 0, OffsetType::InvalidOffset()); } auto mirConst = static_cast(opnd)->GetConstVal(); CHECK_FATAL(mirConst->GetKind() == kConstInt, "array index must be integer"); @@ -350,7 +350,7 @@ AliasInfo AliasClass::CreateAliasElemsExpr(BaseNode &expr) { } constexpr int64 bitsPerByte = 8; OffsetType newOffset = aliasInfo.offset + static_cast(constVal) * bitsPerByte; - return AliasInfo(aliasInfo.ae, aliasInfo.fieldID, newOffset); + return AliasInfo(aliasInfo.ae, 0, newOffset); } case OP_array: { for (size_t i = 1; i < expr.NumOpnds(); ++i) { @@ -551,10 +551,20 @@ void AliasClass::ApplyUnionForDassignCopy(AliasElem &lhsAe, AliasElem *rhsAe, Ba if (SetNextLevNADSForEscapePtr(lhsAe, rhs)) { return; } - if (rhsAe == nullptr || rhsAe->GetOriginalSt().GetIndirectLev() > 0 || rhsAe->IsNotAllDefsSeen()) { + if (rhsAe == nullptr) { lhsAe.SetNextLevNotAllDefsSeen(true); return; } + if (rhsAe->GetOriginalSt().GetIndirectLev() > 0 || rhsAe->IsNotAllDefsSeen()) { + unionFind.Union(lhsAe.GetClassID(), rhsAe->GetClassID()); + lhsAe.SetNextLevNotAllDefsSeen(true); + return; + } + if (rhsAe->GetOriginalSt().GetIndirectLev() < 0) { + for (auto *ost : rhsAe->GetOriginalSt().GetNextLevelOsts()) { + osym2Elem[ost->GetIndex()]->SetNextLevNotAllDefsSeen(true); + } + } if (mirModule.IsCModule()) { TyIdx lhsTyIdx = lhsAe.GetOriginalSt().GetTyIdx(); TyIdx rhsTyIdx = rhsAe->GetOriginalSt().GetTyIdx(); @@ -633,13 +643,6 @@ void AliasClass::ApplyUnionForCopies(StmtNode &stmt) { AliasElem *lhsAe = FindOrCreateAliasElem(*ost); ASSERT_NOT_NULL(lhsAe); ApplyUnionForDassignCopy(*lhsAe, rhsAinfo.ae, *stmt.Opnd(0)); - // at p = x, if the next level of either side exists, create other - // side's next level - if (mirModule.IsCModule() && rhsAinfo.ae && - (lhsAe->GetOriginalSt().GetTyIdx() == rhsAinfo.ae->GetOriginalSt().GetTyIdx())) { - CreateMirroringAliasElems(&rhsAinfo.ae->GetOriginalSt(), &lhsAe->GetOriginalSt()); - CreateMirroringAliasElems(&lhsAe->GetOriginalSt(), &rhsAinfo.ae->GetOriginalSt()); - } return; } case OP_iassign: { @@ -766,6 +769,7 @@ void AliasClass::CreateAssignSets() { if (id2Elem[rootID]->GetAssignSet() == nullptr) { id2Elem[rootID]->assignSet = acMemPool.New>(acAlloc.Adapter()); } + id2Elem[id]->assignSet = id2Elem[rootID]->assignSet; id2Elem[rootID]->AddAssignToSet(id); } } @@ -805,6 +809,68 @@ void AliasClass::UnionAllPointedTos() { unionFind.Union(pointedTos[0]->GetClassID(), pointedTos[i]->GetClassID()); } } + +void AliasClass::UnionNextLevelOfAliasOst(std::set &aesToUnionNextLev) { + while (!aesToUnionNextLev.empty()) { + auto tmpSet = aesToUnionNextLev; + aesToUnionNextLev.clear(); + for (auto *aliasElem : tmpSet) { + auto aeId = aliasElem->GetClassID(); + if (unionFind.Root(aeId) != aeId) { + continue; + } + + std::set mayAliasOsts; + for (uint32 id = 0; id < id2Elem.size(); ++id) { + if (unionFind.Root(id) != aeId) { + continue; + } + auto *ost = id2Elem[id]->GetOst(); + auto &nextLevOsts = ost->GetNextLevelOsts(); + (void)mayAliasOsts.insert(nextLevOsts.begin(), nextLevOsts.end()); + + auto *assignSet = id2Elem[id]->GetAssignSet(); + if (assignSet == nullptr) { + continue; + } + for (auto valAliasId : *assignSet) { + if (valAliasId == id) { + continue; + } + auto &nextLevOsts = id2Elem[valAliasId]->GetOst()->GetNextLevelOsts(); + (void)mayAliasOsts.insert(nextLevOsts.begin(), nextLevOsts.end()); + } + } + + if (mayAliasOsts.empty()) { + continue; + } + + for (auto itA = mayAliasOsts.begin(); itA != mayAliasOsts.end(); ++itA) { + auto *ostA = *itA; + if (ostA->IsFinal()) { + continue; + } + auto itB = itA; + ++itB; + for (; itB != mayAliasOsts.end(); ++itB) { + auto *ostB = *itB; + if (ostB->IsFinal()) { + continue; + } + + auto idA = FindAliasElem(*ostA)->GetClassID(); + auto idB = FindAliasElem(*ostB)->GetClassID(); + if (unionFind.Root(idA) != unionFind.Root(idB)) { + unionFind.Union(idA, idB); + aesToUnionNextLev.insert(id2Elem[unionFind.Root(idA)]); + } + } + } + } + } +} + // process the union among the pointed's of assignsets void AliasClass::ApplyUnionForPointedTos() { // first, process nextLevNotAllDefsSeen for alias elems until no change @@ -825,7 +891,7 @@ void AliasClass::ApplyUnionForPointedTos() { } } } - }; + } // only for c language // base ptr may add/sub an offset to point to any field if (mirModule.IsCModule()) { @@ -837,9 +903,10 @@ void AliasClass::ApplyUnionForPointedTos() { UnionForAggAndFields(); } + std::vector aliasElemProcessed(id2Elem.size(), false); MapleSet tempset(std::less(), acAlloc.Adapter()); for (AliasElem *aliaselem : id2Elem) { - if (aliaselem->GetAssignSet() == nullptr) { + if (aliaselem->GetAssignSet() == nullptr || aliasElemProcessed[aliaselem->GetClassID()]) { continue; } @@ -853,6 +920,7 @@ void AliasClass::ApplyUnionForPointedTos() { hasNextLevNotAllDefsSeen = true; break; } + aliasElemProcessed[*setit] = true; } if (hasNextLevNotAllDefsSeen) { // make all pointedto's in this assignSet notAllDefsSeen @@ -872,6 +940,7 @@ void AliasClass::ApplyUnionForPointedTos() { } // apply union among the assignSet elements + std::set aesToUnionNextLev; tempset = *(aliaselem->GetAssignSet()); while (tempset.size() > 1) { // At least two elements in the same assignSet so that we can connect their next level // pick one alias element @@ -888,13 +957,19 @@ void AliasClass::ApplyUnionForPointedTos() { if (!MayAliasBasicAA(*ost1it, *ost2it)) { continue; } - AliasElem *indae1 = FindAliasElem(**ost1it); - AliasElem *indae2 = FindAliasElem(**ost2it); - unionFind.Union(indae1->GetClassID(), indae2->GetClassID()); + uint32 idA = FindAliasElem(**ost1it)->GetClassID(); + uint32 idB = FindAliasElem(**ost2it)->GetClassID(); + if (unionFind.Root(idA) != unionFind.Root(idB)) { + unionFind.Union(idA, idB); + aesToUnionNextLev.insert(id2Elem[unionFind.Root(idA)]); + } } } } } + + // union next-level-osts of aliased osts + UnionNextLevelOfAliasOst(aesToUnionNextLev); } } @@ -930,9 +1005,14 @@ void AliasClass::UnionForNotAllDefsSeen() { if (!rootIDOfNADSs.empty()) { unsigned int elemIdA = *(rootIDOfNADSs.begin()); rootIDOfNADSs.erase(rootIDOfNADSs.begin()); + std::set aesToUnionNextLev; for (size_t elemIdB : rootIDOfNADSs) { - unionFind.Union(elemIdA, elemIdB); + if (unionFind.Root(elemIdA) != unionFind.Root(elemIdB)) { + unionFind.Union(elemIdA, elemIdB); + aesToUnionNextLev.insert(id2Elem[unionFind.Root(elemIdA)]); + } } + UnionNextLevelOfAliasOst(aesToUnionNextLev); for (auto *aliasElem : id2Elem) { if (unionFind.Root(aliasElem->GetClassID()) == unionFind.Root(elemIdA)) { aliasElem->SetNotAllDefsSeen(true); @@ -957,9 +1037,16 @@ void AliasClass::UnionForNotAllDefsSeenCLang() { // Union notAllDefsSeenAe with the other notAllDefsSeen aes. AliasElem *notAllDefsSeenAe = notAllDefsSeenAes[0]; (void)notAllDefsSeenAes.erase(notAllDefsSeenAes.begin()); + std::set aesToUnionNextLev; for (AliasElem *ae : notAllDefsSeenAes) { - unionFind.Union(notAllDefsSeenAe->GetClassID(), ae->GetClassID()); + auto idA = notAllDefsSeenAe->GetClassID(); + auto idB = ae->GetClassID(); + if (unionFind.Root(idA) != unionFind.Root(idB)) { + unionFind.Union(idA, idB); + aesToUnionNextLev.insert(id2Elem[unionFind.Root(idA)]); + } } + UnionNextLevelOfAliasOst(aesToUnionNextLev); uint rootIdOfNotAllDefsSeenAe = unionFind.Root(notAllDefsSeenAe->GetClassID()); for (AliasElem *ae : id2Elem) { diff --git a/src/mapleall/maple_me/src/me_alias_class.cpp b/src/mapleall/maple_me/src/me_alias_class.cpp index 029457899a91f4ab08a3b5b1732803abf84d590e..28d468b879dd597a30c28e5c60e0bb5ef0a2ca2c 100644 --- a/src/mapleall/maple_me/src/me_alias_class.cpp +++ b/src/mapleall/maple_me/src/me_alias_class.cpp @@ -67,7 +67,6 @@ void MeAliasClass::DoAliasAnalysis() { if (!MeOption::noTBAA && mirModule.IsJavaModule()) { ReconstructAliasGroups(); } - UnionNextLevelOfAliasOst(); CreateClassSets(); if (enabledDebug) { DumpClassSets();