diff options
author | Michael J. Spencer <bigcheesegs@gmail.com> | 2018-07-16 00:28:24 +0000 |
---|---|---|
committer | Michael J. Spencer <bigcheesegs@gmail.com> | 2018-07-16 00:28:24 +0000 |
commit | 7bb2767fba25313c3c4b002127b5ff35836d0627 (patch) | |
tree | 825f04b575505e72be0010c05b77a6f6003ff54f /llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | |
parent | 8d9d4f94b9882c3107b4bca2dcb652a4d42826b1 (diff) | |
download | bcm5719-llvm-7bb2767fba25313c3c4b002127b5ff35836d0627.tar.gz bcm5719-llvm-7bb2767fba25313c3c4b002127b5ff35836d0627.zip |
Recommit r335794 "Add support for generating a call graph profile from Branch Frequency Info." with fix for removed functions.
llvm-svn: 337140
Diffstat (limited to 'llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp')
-rw-r--r-- | llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 60 |
1 files changed, 53 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index dc29397a343..b726b21f6b9 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -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( |