Skip to content

Commit

Permalink
IR: Fix a race condition in type id clients of ModuleSummaryIndex.
Browse files Browse the repository at this point in the history
Add a const version of the getTypeIdSummary accessor that avoids
mutating the TypeIdMap.

Differential Revision: https://reviews.llvm.org/D31226

llvm-svn: 298531
  • Loading branch information
pcc committed Mar 22, 2017
1 parent 84a6218 commit 9a3f979
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 11 deletions.
13 changes: 12 additions & 1 deletion llvm/include/llvm/IR/ModuleSummaryIndex.h
Expand Up @@ -691,10 +691,21 @@ class ModuleSummaryIndex {
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(),
Expand Down
9 changes: 6 additions & 3 deletions llvm/lib/Transforms/IPO/LowerTypeTests.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
19 changes: 12 additions & 7 deletions llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
Expand Up @@ -1196,9 +1196,14 @@ void DevirtModule::scanTypeCheckedLoadUsers(Function *TypeCheckedLoadFunc) {
}

void DevirtModule::importResolution(VTableSlot Slot, VTableSlotInfo &SlotInfo) {
const WholeProgramDevirtResolution &Res =
Summary->getTypeIdSummary(cast<MDString>(Slot.TypeID)->getString())
.WPDRes[Slot.ByteOffset];
const TypeIdSummary *TidSummary =
Summary->getTypeIdSummary(cast<MDString>(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
Expand Down Expand Up @@ -1354,10 +1359,10 @@ bool DevirtModule::run() {
S.first.ByteOffset)) {
WholeProgramDevirtResolution *Res = nullptr;
if (Action == PassSummaryAction::Export && isa<MDString>(S.first.TypeID))
Res =
&Summary
->getTypeIdSummary(cast<MDString>(S.first.TypeID)->getString())
.WPDRes[S.first.ByteOffset];
Res = &Summary
->getOrInsertTypeIdSummary(
cast<MDString>(S.first.TypeID)->getString())
.WPDRes[S.first.ByteOffset];

if (!trySingleImplDevirt(TargetsForSlot, S.second, Res) &&
tryVirtualConstProp(TargetsForSlot, S.second, Res, S.first))
Expand Down

0 comments on commit 9a3f979

Please sign in to comment.