diff options
Diffstat (limited to 'lld/ELF/Driver.cpp')
-rw-r--r-- | lld/ELF/Driver.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 98ec3938635..34bfba8c941 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -679,6 +679,27 @@ static void readCallGraph(MemoryBufferRef MB) { } } +template <class ELFT> static void readCallGraphsFromObjectFiles() { + auto FindSection = [&](const Symbol *Sym) -> const InputSectionBase * { + warnUnorderableSymbol(Sym); + if (const auto *SymD = dyn_cast<Defined>(Sym)) + return dyn_cast_or_null<InputSectionBase>(SymD->Section); + return nullptr; + }; + + for (auto File : ObjectFiles) { + auto *Obj = cast<ObjFile<ELFT>>(File); + for (const Elf_CGProfile_Impl<ELFT> &CGPE : Obj->CGProfile) { + const InputSectionBase *FromSB = + FindSection(&Obj->getSymbol(CGPE.cgp_from)); + const InputSectionBase *ToSB = FindSection(&Obj->getSymbol(CGPE.cgp_to)); + if (!FromSB || !ToSB) + continue; + Config->CallGraphProfile[{FromSB, ToSB}] += CGPE.cgp_weight; + } + } +} + static bool getCompressDebugSections(opt::InputArgList &Args) { StringRef S = Args.getLastArgValue(OPT_compress_debug_sections, "none"); if (S == "none") @@ -1598,6 +1619,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { if (auto *Arg = Args.getLastArg(OPT_call_graph_ordering_file)) if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue())) readCallGraph(*Buffer); + readCallGraphsFromObjectFiles<ELFT>(); // Write the result to the file. writeResult<ELFT>(); |