From 9a3f97977f388cf76161ec0c87e0a70e49caa4ec Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Wed, 22 Mar 2017 18:04:39 +0000 Subject: [PATCH] IR: Fix a race condition in type id clients of ModuleSummaryIndex. Add a const version of the getTypeIdSummary accessor that avoids mutating the TypeIdMap. Differential Revision: https://reviews.llvm.org/D31226 llvm-svn: 298531 --- llvm/include/llvm/IR/ModuleSummaryIndex.h | 13 ++++++++++++- llvm/lib/Transforms/IPO/LowerTypeTests.cpp | 9 ++++++--- llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp | 19 ++++++++++++------- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/llvm/include/llvm/IR/ModuleSummaryIndex.h b/llvm/include/llvm/IR/ModuleSummaryIndex.h index 10d6ccf..f1e87df 100644 --- a/llvm/include/llvm/IR/ModuleSummaryIndex.h +++ b/llvm/include/llvm/IR/ModuleSummaryIndex.h @@ -691,10 +691,21 @@ public: return TypeIdMap; } - TypeIdSummary &getTypeIdSummary(StringRef TypeId) { + /// This accessor should only be used when exporting because it can mutate the + /// map. + TypeIdSummary &getOrInsertTypeIdSummary(StringRef TypeId) { return TypeIdMap[TypeId]; } + /// This returns either a pointer to the type id summary (if present in the + /// summary map) or null (if not present). This may be used when importing. + const TypeIdSummary *getTypeIdSummary(StringRef TypeId) const { + auto I = TypeIdMap.find(TypeId); + if (I == TypeIdMap.end()) + return nullptr; + return &I->second; + } + /// Remove entries in the GlobalValueMap that have empty summaries due to the /// eager nature of map entry creation during VST parsing. These would /// also be suppressed during combined index generation in mergeFrom(), diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp index 8a623825..062b872 100644 --- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp +++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp @@ -265,7 +265,7 @@ class LowerTypeTestsModule { /// regular LTO or the regular LTO phase of ThinLTO), or indirectly using type /// identifier summaries and external symbol references (in ThinLTO backends). struct TypeIdLowering { - TypeTestResolution::Kind TheKind; + TypeTestResolution::Kind TheKind = TypeTestResolution::Unsat; /// All except Unsat: the start address within the combined global. Constant *OffsetedGlobal; @@ -700,7 +700,7 @@ void LowerTypeTestsModule::buildBitSetsFromGlobalVariables( /// information about the type identifier. void LowerTypeTestsModule::exportTypeId(StringRef TypeId, const TypeIdLowering &TIL) { - TypeTestResolution &TTRes = Summary->getTypeIdSummary(TypeId).TTRes; + TypeTestResolution &TTRes = Summary->getOrInsertTypeIdSummary(TypeId).TTRes; TTRes.TheKind = TIL.TheKind; auto ExportGlobal = [&](StringRef Name, Constant *C) { @@ -738,7 +738,10 @@ void LowerTypeTestsModule::exportTypeId(StringRef TypeId, LowerTypeTestsModule::TypeIdLowering LowerTypeTestsModule::importTypeId(StringRef TypeId) { - TypeTestResolution &TTRes = Summary->getTypeIdSummary(TypeId).TTRes; + const TypeIdSummary *TidSummary = Summary->getTypeIdSummary(TypeId); + if (!TidSummary) + return {}; // Unsat: no globals match this type id. + const TypeTestResolution &TTRes = TidSummary->TTRes; TypeIdLowering TIL; TIL.TheKind = TTRes.TheKind; diff --git a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp index ba44921d..68d7bd5 100644 --- a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp +++ b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp @@ -1196,9 +1196,14 @@ void DevirtModule::scanTypeCheckedLoadUsers(Function *TypeCheckedLoadFunc) { } void DevirtModule::importResolution(VTableSlot Slot, VTableSlotInfo &SlotInfo) { - const WholeProgramDevirtResolution &Res = - Summary->getTypeIdSummary(cast(Slot.TypeID)->getString()) - .WPDRes[Slot.ByteOffset]; + const TypeIdSummary *TidSummary = + Summary->getTypeIdSummary(cast(Slot.TypeID)->getString()); + if (!TidSummary) + return; + auto ResI = TidSummary->WPDRes.find(Slot.ByteOffset); + if (ResI == TidSummary->WPDRes.end()) + return; + const WholeProgramDevirtResolution &Res = ResI->second; if (Res.TheKind == WholeProgramDevirtResolution::SingleImpl) { // The type of the function in the declaration is irrelevant because every @@ -1354,10 +1359,10 @@ bool DevirtModule::run() { S.first.ByteOffset)) { WholeProgramDevirtResolution *Res = nullptr; if (Action == PassSummaryAction::Export && isa(S.first.TypeID)) - Res = - &Summary - ->getTypeIdSummary(cast(S.first.TypeID)->getString()) - .WPDRes[S.first.ByteOffset]; + Res = &Summary + ->getOrInsertTypeIdSummary( + cast(S.first.TypeID)->getString()) + .WPDRes[S.first.ByteOffset]; if (!trySingleImplDevirt(TargetsForSlot, S.second, Res) && tryVirtualConstProp(TargetsForSlot, S.second, Res, S.first)) -- 2.7.4