mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-21 03:05:26 -04:00
Recommit r335794 "Add support for generating a call graph profile from Branch Frequency Info." with fix for removed functions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@337140 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -91,6 +91,12 @@ static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags,
|
||||
// ELF
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
|
||||
const TargetMachine &TgtM) {
|
||||
TargetLoweringObjectFile::Initialize(Ctx, TgtM);
|
||||
TM = &TgtM;
|
||||
}
|
||||
|
||||
void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,
|
||||
Module &M) const {
|
||||
auto &C = getContext();
|
||||
@@ -116,15 +122,55 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,
|
||||
StringRef Section;
|
||||
|
||||
GetObjCImageInfo(M, Version, Flags, Section);
|
||||
if (Section.empty())
|
||||
if (!Section.empty()) {
|
||||
auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
|
||||
Streamer.SwitchSection(S);
|
||||
Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
|
||||
Streamer.EmitIntValue(Version, 4);
|
||||
Streamer.EmitIntValue(Flags, 4);
|
||||
Streamer.AddBlankLine();
|
||||
}
|
||||
|
||||
SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
|
||||
M.getModuleFlagsMetadata(ModuleFlags);
|
||||
|
||||
MDNode *CFGProfile = nullptr;
|
||||
|
||||
for (const auto &MFE : ModuleFlags) {
|
||||
StringRef Key = MFE.Key->getString();
|
||||
if (Key == "CG Profile") {
|
||||
CFGProfile = cast<MDNode>(MFE.Val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!CFGProfile)
|
||||
return;
|
||||
|
||||
auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
|
||||
Streamer.SwitchSection(S);
|
||||
Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
|
||||
Streamer.EmitIntValue(Version, 4);
|
||||
Streamer.EmitIntValue(Flags, 4);
|
||||
Streamer.AddBlankLine();
|
||||
auto GetSym = [this](const MDOperand &MDO) -> MCSymbol * {
|
||||
if (!MDO)
|
||||
return nullptr;
|
||||
auto V = cast<ValueAsMetadata>(MDO);
|
||||
const Function *F = cast<Function>(V->getValue());
|
||||
return TM->getSymbol(F);
|
||||
};
|
||||
|
||||
for (const auto &Edge : CFGProfile->operands()) {
|
||||
MDNode *E = cast<MDNode>(Edge);
|
||||
const MCSymbol *From = GetSym(E->getOperand(0));
|
||||
const MCSymbol *To = GetSym(E->getOperand(1));
|
||||
// Skip null functions. This can happen if functions are dead stripped after
|
||||
// the CGProfile pass has been run.
|
||||
if (!From || !To)
|
||||
continue;
|
||||
uint64_t Count = cast<ConstantAsMetadata>(E->getOperand(2))
|
||||
->getValue()
|
||||
->getUniqueInteger()
|
||||
.getZExtValue();
|
||||
Streamer.emitCGProfileEntry(
|
||||
MCSymbolRefExpr::create(From, MCSymbolRefExpr::VK_None, C),
|
||||
MCSymbolRefExpr::create(To, MCSymbolRefExpr::VK_None, C), Count);
|
||||
}
|
||||
}
|
||||
|
||||
MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol(
|
||||
|
||||
Reference in New Issue
Block a user