diff --git a/src/mapleall/maple_me/include/alias_class.h b/src/mapleall/maple_me/include/alias_class.h index 53b3556ec42a2a397d4884ffeb89c1cbe018c188..97594707647855c1b221488b1e34472f432ea0f4 100644 --- a/src/mapleall/maple_me/include/alias_class.h +++ b/src/mapleall/maple_me/include/alias_class.h @@ -188,6 +188,7 @@ class AliasClass : public AnalysisResult { void SetPtrOpndNextLevNADS(const BaseNode &opnd, AliasElem *aliasElem, bool hasNoPrivateDefEffect); void SetPtrOpndsNextLevNADS(unsigned int start, unsigned int end, MapleVector &opnds, bool hasNoPrivateDefEffect); + void ApplyUnionForFieldsInAggCopy(const OriginalSt *lhsost, const OriginalSt *rhsost); void ApplyUnionForDassignCopy(const AliasElem &lhsAe, const AliasElem *rhsAe, const BaseNode &rhs); void CreateMirroringAliasElems(const OriginalSt *ost1, OriginalSt *ost2); AliasElem *FindOrCreateDummyNADSAe(); diff --git a/src/mapleall/maple_me/include/orig_symbol.h b/src/mapleall/maple_me/include/orig_symbol.h index c97d769ae4092adbc4eb683bbbd105fe9aeabaf8..da4db3493b4514f3d2756c348c48b5d642144ead 100644 --- a/src/mapleall/maple_me/include/orig_symbol.h +++ b/src/mapleall/maple_me/include/orig_symbol.h @@ -50,12 +50,7 @@ class OriginalSt { return GlobalTables::GetGsymTable().GetModule()->CurFunction()->GetPregTab()->PregFromPregIdx(symOrPreg.pregIdx); } - const MIRSymbol *GetMIRSymbol() const { - ASSERT(ostType == kSymbolOst, "OriginalSt must be SymbolOst"); - return symOrPreg.mirSt; - } - - MIRSymbol *GetMIRSymbol() { + MIRSymbol *GetMIRSymbol() const { ASSERT(ostType == kSymbolOst, "OriginalSt must be SymbolOst"); return symOrPreg.mirSt; } @@ -343,7 +338,9 @@ class OriginalStTable { MIRModule &mirModule; MapleVector originalStVector; // the vector that map a OriginalSt's index to its pointer // mir symbol to original table, this only exists for no-original variables. + public: MapleUnorderedMap mirSt2Ost; + private: MapleUnorderedMap preg2Ost; // mir type to virtual variables in original table. this only exists for no-original variables. MapleMap pType2Ost; diff --git a/src/mapleall/maple_me/include/ssa_tab.h b/src/mapleall/maple_me/include/ssa_tab.h index 346610c5b7abeed1e558136d57edda5cdf07f52f..c6d2256a5ce007aa8176ba1228fc918cbe04827b 100644 --- a/src/mapleall/maple_me/include/ssa_tab.h +++ b/src/mapleall/maple_me/include/ssa_tab.h @@ -83,7 +83,7 @@ class SSATab : public AnalysisResult { } OriginalSt *GetSymbolOriginalStFromID(OStIdx id) { OriginalSt *ost = originalStTable.GetOriginalStFromID(id); - ASSERT(ost->IsSymbolOst(), "GetSymbolOriginalStFromid: id has wrong ost type"); + ASSERT(ost->IsSymbolOst() || ost->GetIndirectLev() > 0, "GetSymbolOriginalStFromid: id has wrong ost type"); return ost; } diff --git a/src/mapleall/maple_me/src/alias_class.cpp b/src/mapleall/maple_me/src/alias_class.cpp index 675db0e9d04df234a06c1f88feb162c58f1e42f5..52908322047ec1704a839192986380e62451765f 100644 --- a/src/mapleall/maple_me/src/alias_class.cpp +++ b/src/mapleall/maple_me/src/alias_class.cpp @@ -306,12 +306,106 @@ void AliasClass::SetNotAllDefsSeenForMustDefs(const StmtNode &callas) { } } +// given a struct/union assignment, regard it as if the fields that appear +// in the code are also assigned +void AliasClass::ApplyUnionForFieldsInAggCopy(const OriginalSt *lhsost, const OriginalSt *rhsost) { + if (lhsost->GetIndirectLev() == 0 && rhsost->GetIndirectLev() == 0) { + MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(lhsost->GetTyIdx()); + MIRStructType *mirStructType = static_cast(mirType); + uint32 numFieldIDs = mirStructType->NumberOfFieldIDs(); + for (uint32 fieldID = 1; fieldID <= numFieldIDs; fieldID++) { + MIRType *fieldType = mirStructType->GetFieldType(fieldID); + if (!IsPotentialAddress(fieldType->GetPrimType(), &mirModule)) { + continue; + } + MapleUnorderedMap &mirSt2Ost = ssaTab.GetOriginalStTable().mirSt2Ost; + auto lhsit = mirSt2Ost.find(SymbolFieldPair(lhsost->GetMIRSymbol()->GetStIdx(), fieldID)); + auto rhsit = mirSt2Ost.find(SymbolFieldPair(rhsost->GetMIRSymbol()->GetStIdx(), fieldID)); + if (lhsit == mirSt2Ost.end() && rhsit == mirSt2Ost.end()) { + continue; + } + // the OriginalSt of at least one side has appearance in code + OriginalSt *lhsFieldOst = nullptr; + OriginalSt *rhsFieldOst = nullptr; + if (lhsit == mirSt2Ost.end()) { + // create a new OriginalSt for lhs field + lhsFieldOst = ssaTab.GetOriginalStTable().CreateSymbolOriginalSt(*lhsost->GetMIRSymbol(), lhsost->GetPuIdx(), fieldID); + osym2Elem.push_back(nullptr); + ssaTab.GetVersionStTable().CreateZeroVersionSt(lhsFieldOst); + + rhsFieldOst = ssaTab.GetOriginalStFromID(rhsit->second); + } else { + lhsFieldOst = ssaTab.GetOriginalStFromID(lhsit->second); + + if (rhsit == mirSt2Ost.end()) { + // create a new OriginalSt for rhs field + rhsFieldOst = ssaTab.GetOriginalStTable().CreateSymbolOriginalSt(*rhsost->GetMIRSymbol(), rhsost->GetPuIdx(), fieldID); + osym2Elem.push_back(nullptr); + ssaTab.GetVersionStTable().CreateZeroVersionSt(rhsFieldOst); + } else { + rhsFieldOst = ssaTab.GetOriginalStFromID(rhsit->second); + } + } + AliasElem *aeOfLHSField = FindOrCreateAliasElem(*lhsFieldOst); + AliasElem *aeOfRHSField = FindOrCreateAliasElem(*rhsFieldOst); + unionFind.Union(aeOfLHSField->id, aeOfRHSField->id); + } + } else if (lhsost->GetIndirectLev() == 0) { + // make any field in this struct that has appeared NADS + MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(lhsost->GetTyIdx()); + MIRStructType *mirStructType = static_cast(mirType); + uint32 numFieldIDs = mirStructType->NumberOfFieldIDs(); + for (uint32 fieldID = 1; fieldID <= numFieldIDs; fieldID++) { + MIRType *fieldType = mirStructType->GetFieldType(fieldID); + if (!IsPotentialAddress(fieldType->GetPrimType(), &mirModule)) { + continue; + } + MapleUnorderedMap &mirSt2Ost = ssaTab.GetOriginalStTable().mirSt2Ost; + auto it = mirSt2Ost.find(SymbolFieldPair(lhsost->GetMIRSymbol()->GetStIdx(), fieldID)); + if (it == mirSt2Ost.end()) { + continue; + } + OriginalSt *lhsFieldOst = ssaTab.GetOriginalStFromID(it->second); + AliasElem *aeOfLHSField = FindOrCreateAliasElem(*lhsFieldOst); + aeOfLHSField->SetNotAllDefsSeen(true); + } + } else { // rhsost->GetIndirectLev() == 0) + // make any field in this struct that has appeared NADS + MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(rhsost->GetTyIdx()); + MIRStructType *mirStructType = static_cast(mirType); + uint32 numFieldIDs = mirStructType->NumberOfFieldIDs(); + for (uint32 fieldID = 1; fieldID <= numFieldIDs; fieldID++) { + MIRType *fieldType = mirStructType->GetFieldType(fieldID); + if (!IsPotentialAddress(fieldType->GetPrimType(), &mirModule)) { + continue; + } + MapleUnorderedMap &mirSt2Ost = ssaTab.GetOriginalStTable().mirSt2Ost; + auto it = mirSt2Ost.find(SymbolFieldPair(rhsost->GetMIRSymbol()->GetStIdx(), fieldID)); + if (it == mirSt2Ost.end()) { + continue; + } + OriginalSt *rhsFieldOst = ssaTab.GetOriginalStFromID(it->second); + AliasElem *aeOfrHSField = FindOrCreateAliasElem(*rhsFieldOst); + aeOfrHSField->SetNotAllDefsSeen(true); + } + } +} + void AliasClass::ApplyUnionForDassignCopy(const AliasElem &lhsAe, const AliasElem *rhsAe, const BaseNode &rhs) { if (rhsAe == nullptr || rhsAe->GetOriginalSt().GetIndirectLev() > 0 || rhsAe->IsNotAllDefsSeen()) { AliasElem *aliasElem = FindAliasElem(lhsAe.GetOriginalSt()); aliasElem->SetNextLevNotAllDefsSeen(true); return; } + if (mirModule.IsCModule()) { + TyIdx lhsTyIdx = lhsAe.GetOriginalSt().GetTyIdx(); + TyIdx rhsTyIdx = rhsAe->GetOriginalSt().GetTyIdx(); + MIRType *rhsType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(rhsTyIdx); + if (lhsTyIdx == rhsTyIdx && + (rhsType->GetKind() == kTypeStruct || rhsType->GetKind() == kTypeUnion)) { + ApplyUnionForFieldsInAggCopy(&lhsAe.GetOriginalSt(), &rhsAe->GetOriginalSt()); + } + } if (!IsPotentialAddress(rhs.GetPrimType(), &mirModule) || kOpcodeInfo.NotPure(rhs.GetOpCode()) || HasMallocOpnd(&rhs) ||