Skip to content

Commit 131fd59

Browse files
authored
[CFI][ThinLTO] Remove the need for CFI calculating ThinLTO GUIDs (#201370)
CFI does name-based matching. ThinLTO uses a hash over the function name (the "GUID"). As a result of this [RFC](https://discourse.llvm.org/t/rfc-keep-globalvalue-guids-stable/84801) - see also PR #184065 - GUID calculation should be treated as an implementation detail, i.e. passes shouldn't need to re-do / reverse engineer GUIDs. The main reasons CFI is aware of GUIDs is because (1) the CFI functions need to be communicated to ThinLink, as they need to be treated as exports, in `LTO::runThinLTO`; and (2) because CFI needs to check the liveliness of functions referenced in `cfi.functions` metadata, and this check happens via the thinlto export summary (`LowerTypeTestsModule::lower`). To a lesser extent, the optimization in PR #130382 benefits from CFI knowing about GUIDs; however, if this were the only reason, we could make `ValueInfo`s available at that point, which carry names, and perform name-based matching for CFI's needs. This PR lets GUIDs be passed to CFI. The bulk of the change is moving them around as metadata fields. The GUID calculation is hoisted out, but kept the same as before this patch, following that once PR #184065 is relanded it will be switched to the stable mechanism it (PR #184065) introduces. The compile time effects are [here](https://llvm-compile-time-tracker.com/compare.php?from=b29bf9fa25bdb906a61ec361fba68796020cc6b9&to=7bb1c07144e8ccb8a3332e91fc193303acd9439e&stat=instructions:u).
1 parent 6f233ce commit 131fd59

24 files changed

Lines changed: 265 additions & 54 deletions

llvm/include/llvm/IR/AutoUpgrade.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ namespace llvm {
6363
/// module is modified.
6464
LLVM_ABI bool UpgradeModuleFlags(Module &M);
6565

66+
/// Upgrade the cfi.functions metadata node by calculating and inserting
67+
/// the GUID for each function entry if it's missing.
68+
LLVM_ABI bool UpgradeCFIFunctionsMetadata(Module &M);
69+
6670
/// Convert legacy nvvm.annotations metadata to appropriate function
6771
/// attributes.
6872
LLVM_ABI void UpgradeNVVMAnnotations(Module &M);

llvm/include/llvm/IR/ModuleSummaryIndex.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1573,7 +1573,7 @@ class ModuleSummaryIndex {
15731573
// in the way some record are interpreted, like flags for instance.
15741574
// Note that incrementing this may require changes in both BitcodeReader.cpp
15751575
// and BitcodeWriter.cpp.
1576-
static constexpr uint64_t BitcodeSummaryVersion = 13;
1576+
static constexpr uint64_t BitcodeSummaryVersion = 14;
15771577

15781578
// Regular LTO module name for ASM writer
15791579
static constexpr const char *getRegularLTOModuleName() {

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
476476
llvm::UpgradeDebugInfo(*M);
477477

478478
UpgradeModuleFlags(*M);
479+
UpgradeCFIFunctionsMetadata(*M);
479480
UpgradeNVVMAnnotations(*M);
480481
UpgradeSectionAttributes(*M);
481482
copyModuleAttrToFunctions(*M);

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3979,6 +3979,8 @@ Error BitcodeReader::materializeMetadata() {
39793979
}
39803980
}
39813981

3982+
UpgradeCFIFunctionsMetadata(*TheModule);
3983+
39823984
DeferredMetadataInfo.clear();
39833985
return Error::success();
39843986
}
@@ -8149,24 +8151,42 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
81498151

81508152
case bitc::FS_CFI_FUNCTION_DEFS: {
81518153
auto &CfiFunctionDefs = TheIndex.cfiFunctionDefs();
8152-
for (unsigned I = 0; I != Record.size(); I += 2) {
8153-
StringRef Name(Strtab.data() + Record[I],
8154-
static_cast<size_t>(Record[I + 1]));
8155-
GlobalValue::GUID GUID = GlobalValue::getGUIDAssumingExternalLinkage(
8156-
GlobalValue::dropLLVMManglingEscape(Name));
8157-
CfiFunctionDefs.addSymbolWithThinLTOGUID(Name, GUID);
8154+
if (Version < 14) {
8155+
for (unsigned I = 0; I != Record.size(); I += 2) {
8156+
StringRef Name(Strtab.data() + Record[I],
8157+
static_cast<size_t>(Record[I + 1]));
8158+
GlobalValue::GUID GUID = GlobalValue::getGUIDAssumingExternalLinkage(
8159+
GlobalValue::dropLLVMManglingEscape(Name));
8160+
CfiFunctionDefs.addSymbolWithThinLTOGUID(Name, GUID);
8161+
}
8162+
} else {
8163+
for (unsigned I = 0; I != Record.size(); I += 3) {
8164+
GlobalValue::GUID ThinLTOGUID = Record[I];
8165+
StringRef Name(Strtab.data() + Record[I + 1],
8166+
static_cast<size_t>(Record[I + 2]));
8167+
CfiFunctionDefs.addSymbolWithThinLTOGUID(Name, ThinLTOGUID);
8168+
}
81588169
}
81598170
break;
81608171
}
81618172

81628173
case bitc::FS_CFI_FUNCTION_DECLS: {
81638174
auto &CfiFunctionDecls = TheIndex.cfiFunctionDecls();
8164-
for (unsigned I = 0; I != Record.size(); I += 2) {
8165-
StringRef Name(Strtab.data() + Record[I],
8166-
static_cast<size_t>(Record[I + 1]));
8167-
GlobalValue::GUID GUID = GlobalValue::getGUIDAssumingExternalLinkage(
8168-
GlobalValue::dropLLVMManglingEscape(Name));
8169-
CfiFunctionDecls.addSymbolWithThinLTOGUID(Name, GUID);
8175+
if (Version < 14) {
8176+
for (unsigned I = 0; I != Record.size(); I += 2) {
8177+
StringRef Name(Strtab.data() + Record[I],
8178+
static_cast<size_t>(Record[I + 1]));
8179+
GlobalValue::GUID GUID = GlobalValue::getGUIDAssumingExternalLinkage(
8180+
GlobalValue::dropLLVMManglingEscape(Name));
8181+
CfiFunctionDecls.addSymbolWithThinLTOGUID(Name, GUID);
8182+
}
8183+
} else {
8184+
for (unsigned I = 0; I != Record.size(); I += 3) {
8185+
GlobalValue::GUID ThinLTOGUID = Record[I];
8186+
StringRef Name(Strtab.data() + Record[I + 1],
8187+
static_cast<size_t>(Record[I + 2]));
8188+
CfiFunctionDecls.addSymbolWithThinLTOGUID(Name, ThinLTOGUID);
8189+
}
81708190
}
81718191
break;
81728192
}

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5323,21 +5323,23 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
53235323
getReferencedTypeIds(FS, ReferencedTypeIds);
53245324
}
53255325

5326-
SmallVector<StringRef, 4> Functions;
5326+
SmallVector<std::pair<StringRef, GlobalValue::GUID>, 4> Functions;
53275327
auto EmitCfiFunctions = [&](const CfiFunctionIndex &CfiIndex,
53285328
bitc::GlobalValueSummarySymtabCodes Code) {
53295329
if (CfiIndex.empty())
53305330
return;
53315331
for (GlobalValue::GUID GUID : DefOrUseGUIDs) {
53325332
auto Names = CfiIndex.getNamesForGUID(GUID);
5333-
llvm::append_range(Functions, Names);
5333+
for (StringRef Name : Names)
5334+
Functions.push_back({Name, GUID});
53345335
}
53355336
if (Functions.empty())
53365337
return;
53375338
llvm::sort(Functions);
5338-
for (const auto &S : Functions) {
5339-
NameVals.push_back(StrtabBuilder.add(S));
5340-
NameVals.push_back(S.size());
5339+
for (const auto &Record : Functions) {
5340+
NameVals.push_back(Record.second);
5341+
NameVals.push_back(StrtabBuilder.add(Record.first));
5342+
NameVals.push_back(Record.first.size());
53415343
}
53425344
Stream.EmitRecord(Code, NameVals);
53435345
NameVals.clear();

llvm/lib/IR/AutoUpgrade.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "llvm/IR/DebugInfoMetadata.h"
2727
#include "llvm/IR/DiagnosticInfo.h"
2828
#include "llvm/IR/Function.h"
29+
#include "llvm/IR/GlobalValue.h"
2930
#include "llvm/IR/IRBuilder.h"
3031
#include "llvm/IR/InstVisitor.h"
3132
#include "llvm/IR/Instruction.h"
@@ -6359,6 +6360,50 @@ bool llvm::UpgradeModuleFlags(Module &M) {
63596360
return Changed;
63606361
}
63616362

6363+
bool llvm::UpgradeCFIFunctionsMetadata(Module &M) {
6364+
NamedMDNode *CFIConsts = M.getNamedMetadata("cfi.functions");
6365+
// If this metadata has operands, we expect all of them to be either from
6366+
// before or from after the format change handled here, so we can bail out
6367+
// fast if the first (if any) operands is of the new format.
6368+
auto MatchesVersion = [](const MDNode *Op) {
6369+
return Op->getNumOperands() >= 3 &&
6370+
isa<ConstantAsMetadata>(Op->getOperand(2)) &&
6371+
cast<ConstantAsMetadata>(Op->getOperand(2))
6372+
->getType()
6373+
->isIntegerTy(64);
6374+
};
6375+
6376+
if (!CFIConsts || !CFIConsts->getNumOperands() ||
6377+
MatchesVersion(CFIConsts->getOperand(0)))
6378+
return false;
6379+
6380+
bool Changed = false;
6381+
for (unsigned I = 0, E = CFIConsts->getNumOperands(); I != E; ++I) {
6382+
MDNode *Op = CFIConsts->getOperand(I);
6383+
assert(!MatchesVersion(Op) && "Unexpected mix of CFIConstant formats");
6384+
assert(Op->getNumOperands() >= 2 &&
6385+
"Expected at least 2 operands - name and linkage type");
6386+
MDString *NameMD = dyn_cast<MDString>(Op->getOperand(0));
6387+
StringRef Name = NameMD->getString();
6388+
GlobalValue::GUID GUID = GlobalValue::getGUIDAssumingExternalLinkage(
6389+
GlobalValue::dropLLVMManglingEscape(Name));
6390+
6391+
SmallVector<Metadata *, 4> Elts;
6392+
Elts.push_back(Op->getOperand(0));
6393+
Elts.push_back(Op->getOperand(1));
6394+
Elts.push_back(ConstantAsMetadata::get(
6395+
ConstantInt::get(Type::getInt64Ty(M.getContext()), GUID)));
6396+
6397+
for (unsigned J = 2, EJ = Op->getNumOperands(); J != EJ; ++J)
6398+
Elts.push_back(Op->getOperand(J));
6399+
6400+
CFIConsts->setOperand(I, MDNode::get(M.getContext(), Elts));
6401+
Changed = true;
6402+
}
6403+
6404+
return Changed;
6405+
}
6406+
63626407
void llvm::UpgradeSectionAttributes(Module &M) {
63636408
auto TrimSpaces = [](StringRef Section) -> std::string {
63646409
SmallVector<StringRef, 5> Components;

llvm/lib/Transforms/IPO/CrossDSOCFI.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@ void CrossDSOCFI::buildCFICheck(Module &M) {
7373
NamedMDNode *CfiFunctionsMD = M.getNamedMetadata("cfi.functions");
7474
if (CfiFunctionsMD) {
7575
for (auto *Func : CfiFunctionsMD->operands()) {
76-
assert(Func->getNumOperands() >= 2);
77-
for (unsigned I = 2; I < Func->getNumOperands(); ++I)
76+
assert(Func->getNumOperands() >= 3);
77+
assert(isa<ConstantAsMetadata>(Func->getOperand(2)));
78+
for (unsigned I = 3; I < Func->getNumOperands(); ++I)
7879
if (ConstantInt *TypeId =
7980
extractNumericTypeId(cast<MDNode>(Func->getOperand(I).get())))
8081
TypeIds.insert(TypeId->getZExtValue());

llvm/lib/Transforms/IPO/LowerTypeTests.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2213,8 +2213,10 @@ bool LowerTypeTestsModule::lower() {
22132213
->getUniqueInteger()
22142214
.getZExtValue());
22152215
const GlobalValue::GUID GUID =
2216-
GlobalValue::getGUIDAssumingExternalLinkage(
2217-
GlobalValue::dropLLVMManglingEscape(FunctionName));
2216+
cast<ConstantAsMetadata>(FuncMD->getOperand(2))
2217+
->getValue()
2218+
->getUniqueInteger()
2219+
.getZExtValue();
22182220
// Do not emit jumptable entries for functions that are not-live and
22192221
// have no live references (and are not exported with cross-DSO CFI.)
22202222
if (!ExportSummary->isGUIDLive(GUID))
@@ -2285,7 +2287,7 @@ bool LowerTypeTestsModule::lower() {
22852287
F->setLinkage(GlobalValue::ExternalWeakLinkage);
22862288

22872289
F->eraseMetadata(LLVMContext::MD_type);
2288-
for (unsigned I = 2; I < FuncMD->getNumOperands(); ++I)
2290+
for (unsigned I = 3; I < FuncMD->getNumOperands(); ++I)
22892291
F->addMetadata(LLVMContext::MD_type,
22902292
*cast<MDNode>(FuncMD->getOperand(I).get()));
22912293
}

llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,11 @@ void splitAndWriteThinLTOBitcode(
436436
Linkage = CFL_Declaration;
437437
Elts.push_back(ConstantAsMetadata::get(
438438
llvm::ConstantInt::get(Type::getInt8Ty(Ctx), Linkage)));
439+
// TODO: use F->getGUID() once #184065 is relanded.
440+
GlobalValue::GUID GUID = GlobalValue::getGUIDAssumingExternalLinkage(
441+
GlobalValue::dropLLVMManglingEscape(V->getName()));
442+
Elts.push_back(ConstantAsMetadata::get(
443+
llvm::ConstantInt::get(Type::getInt64Ty(Ctx), GUID)));
439444
append_range(Elts, Types);
440445
CfiFunctionMDs.push_back(MDTuple::get(Ctx, Elts));
441446
}
2.01 KB
Binary file not shown.

0 commit comments

Comments
 (0)