<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [LTO] Excessive memory usage with IPGO due to Metadata merging"
   href="https://bugs.llvm.org/show_bug.cgi?id=52551">52551</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[LTO] Excessive memory usage with IPGO due to Metadata merging
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Linker
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>Wolfgang_Pieb@playstation.sony.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>When regular LTO is used with IPGO, we're seeing excessive memory usage (4x) at
link (LTO) time compared to just using regular LTO without IPGO. We've traced
it to Metadata merging at the time when all modules are linked into a combined
module.

Specifically, it's module flags that are being merged in the following code
segments in IRLinker::linkModuleFlagsMetadata() in llvm/lib/Linker/IRMover.cpp:

   switch (SrcBehaviorValue) {
    ...
    case Module::Append: {
      MDNode *DstValue = cast<MDNode>(DstOp->getOperand(2));
      MDNode *SrcValue = cast<MDNode>(SrcOp->getOperand(2));
      SmallVector<Metadata *, 8> MDs;
      MDs.reserve(DstValue->getNumOperands() + SrcValue->getNumOperands());
      MDs.append(DstValue->op_begin(), DstValue->op_end());
      MDs.append(SrcValue->op_begin(), SrcValue->op_end());

      replaceDstValue(MDNode::get(DstM.getContext(), MDs));
      break;
     }
     ...

with replaceDstValue() a lambda that replaces an existing MD list node with the
newly created one.

The ModuleFlags in question are the "CG Profile" flags, which seems to be a
list of MD nodes representing all function declarations that have profile
information in the module. The end result is one long list of functions for the
entire combined module, but the list is created one module at a time, so that
each time we link a new module, a new list node is created by copying the
entries of the old one and adding the new ones to it. The old list node is not
deleted.
In one of our licensee's applications, after some time each new list node takes
several MB, and this adds up. Towards the end each new node takes 18MB.

I did some basic instrumentation (i.e. printing out the amount of allocated
memory during module flag linking) and used it with a simple example with just
3 modules, and I got

  Append module flag - before
  Allocating 88
  Allocating 48
  Append module flag - after
  Append module flag - before
  Allocating 112
  Allocating 48
  Append module flag - after
  Append module flag - before
  Allocating 184
  Allocating 48
  Append module flag - after

One can see the growing allocation from 88 to 184 with just 3 modules.

The question arises whether temporary MD nodes are could be used instead so
they can be deleted when a new list node replaces an old one.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>