Skip to content

Commit 071855d

Browse files
[ThinLTO] Fix assembly dumping of vtable type ids (#73997)
With RTTI, a C++ class type info will get two entries in the summary index: a gv and a typeidCompatibleVTable, both sharing the same GUID. Ensure we use different namespaces to generate the entry slot numbers for these two different summary entries.
1 parent 1035cc7 commit 071855d

File tree

2 files changed

+59
-4
lines changed

2 files changed

+59
-4
lines changed

llvm/lib/IR/AsmWriter.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,11 @@ class SlotTracker : public AbstractSlotTrackerStorage {
736736
StringMap<unsigned> TypeIdMap;
737737
unsigned TypeIdNext = 0;
738738

739+
/// TypeIdCompatibleVtableMap - The slot map for type compatible vtable ids
740+
/// used in the summary index.
741+
StringMap<unsigned> TypeIdCompatibleVtableMap;
742+
unsigned TypeIdCompatibleVtableNext = 0;
743+
739744
public:
740745
/// Construct from a module.
741746
///
@@ -779,6 +784,7 @@ class SlotTracker : public AbstractSlotTrackerStorage {
779784
int getModulePathSlot(StringRef Path);
780785
int getGUIDSlot(GlobalValue::GUID GUID);
781786
int getTypeIdSlot(StringRef Id);
787+
int getTypeIdCompatibleVtableSlot(StringRef Id);
782788

783789
/// If you'd like to deal with a function instead of just a module, use
784790
/// this method to get its data into the SlotTracker.
@@ -834,6 +840,7 @@ class SlotTracker : public AbstractSlotTrackerStorage {
834840
inline void CreateModulePathSlot(StringRef Path);
835841
void CreateGUIDSlot(GlobalValue::GUID GUID);
836842
void CreateTypeIdSlot(StringRef Id);
843+
void CreateTypeIdCompatibleVtableSlot(StringRef Id);
837844

838845
/// Add all of the module level global variables (and their initializers)
839846
/// and function declarations, but not the contents of those functions.
@@ -1095,11 +1102,13 @@ int SlotTracker::processIndex() {
10951102
for (auto &GlobalList : *TheIndex)
10961103
CreateGUIDSlot(GlobalList.first);
10971104

1105+
// Start numbering the TypeIdCompatibleVtables after the GUIDs.
1106+
TypeIdCompatibleVtableNext = GUIDNext;
10981107
for (auto &TId : TheIndex->typeIdCompatibleVtableMap())
1099-
CreateGUIDSlot(GlobalValue::getGUID(TId.first));
1108+
CreateTypeIdCompatibleVtableSlot(TId.first);
11001109

1101-
// Start numbering the TypeIds after the GUIDs.
1102-
TypeIdNext = GUIDNext;
1110+
// Start numbering the TypeIds after the TypeIdCompatibleVtables.
1111+
TypeIdNext = TypeIdCompatibleVtableNext;
11031112
for (const auto &TID : TheIndex->typeIds())
11041113
CreateTypeIdSlot(TID.second.first);
11051114

@@ -1232,6 +1241,15 @@ int SlotTracker::getTypeIdSlot(StringRef Id) {
12321241
return I == TypeIdMap.end() ? -1 : (int)I->second;
12331242
}
12341243

1244+
int SlotTracker::getTypeIdCompatibleVtableSlot(StringRef Id) {
1245+
// Check for uninitialized state and do lazy initialization.
1246+
initializeIndexIfNeeded();
1247+
1248+
// Find the TypeIdCompatibleVtable string in the map
1249+
auto I = TypeIdCompatibleVtableMap.find(Id);
1250+
return I == TypeIdCompatibleVtableMap.end() ? -1 : (int)I->second;
1251+
}
1252+
12351253
/// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
12361254
void SlotTracker::CreateModuleSlot(const GlobalValue *V) {
12371255
assert(V && "Can't insert a null Value into SlotTracker!");
@@ -1307,6 +1325,11 @@ void SlotTracker::CreateTypeIdSlot(StringRef Id) {
13071325
TypeIdMap[Id] = TypeIdNext++;
13081326
}
13091327

1328+
/// Create a new slot for the specified Id
1329+
void SlotTracker::CreateTypeIdCompatibleVtableSlot(StringRef Id) {
1330+
TypeIdCompatibleVtableMap[Id] = TypeIdCompatibleVtableNext++;
1331+
}
1332+
13101333
namespace {
13111334
/// Common instances used by most of the printer functions.
13121335
struct AsmWriterContext {
@@ -2955,7 +2978,7 @@ void AssemblyWriter::printModuleSummaryIndex() {
29552978
// Print the TypeIdCompatibleVtableMap entries.
29562979
for (auto &TId : TheIndex->typeIdCompatibleVtableMap()) {
29572980
auto GUID = GlobalValue::getGUID(TId.first);
2958-
Out << "^" << Machine.getGUIDSlot(GUID)
2981+
Out << "^" << Machine.getTypeIdCompatibleVtableSlot(TId.first)
29592982
<< " = typeidCompatibleVTable: (name: \"" << TId.first << "\"";
29602983
printTypeIdCompatibleVtableSummary(TId.second);
29612984
Out << ") ; guid = " << GUID << "\n";
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
;; Test to ensure that the summary is correctly printed when there is both a
2+
;; global variable summary and a vtable typeid summary entry for the same
3+
;; symbol.
4+
5+
; RUN: opt %s -S -module-summary | FileCheck %s
6+
;; Make sure it round trips correctly.
7+
; RUN: opt %s -S -module-summary -o - | llvm-as -o - | llvm-dis -o - | FileCheck %s
8+
9+
;; These summary entries should get numbered differently.
10+
; CHECK: ^2 = gv: (name: "_ZTS1A"
11+
; CHECK: ^6 = typeidCompatibleVTable: (name: "_ZTS1A"
12+
13+
; ModuleID = 'thinlto-vtable-summary2.cc'
14+
source_filename = "thinlto-vtable-summary2.cc"
15+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
16+
target triple = "x86_64-unknown-linux-gnu"
17+
18+
@_ZTV1A = dso_local unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr @_ZTI1A, ptr @_ZN1A3fooEv] }, align 8, !type !0, !type !1
19+
@_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
20+
@_ZTS1A = dso_local constant [3 x i8] c"1A\00", align 1
21+
@_ZTI1A = dso_local constant { ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), ptr @_ZTS1A }, align 8
22+
23+
define dso_local noundef i32 @_ZN1A3fooEv(ptr noundef nonnull align 8 dereferenceable(8) %this) unnamed_addr align 2 {
24+
entry:
25+
%this.addr = alloca ptr, align 8
26+
store ptr %this, ptr %this.addr, align 8
27+
%this1 = load ptr, ptr %this.addr, align 8
28+
ret i32 1
29+
}
30+
31+
!0 = !{i64 16, !"_ZTS1A"}
32+
!1 = !{i64 16, !"_ZTSM1AFivE.virtual"}

0 commit comments

Comments
 (0)