summaryrefslogtreecommitdiff
path: root/lld/ELF/Driver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/Driver.cpp')
-rw-r--r--lld/ELF/Driver.cpp22
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>();