llvm-project/llvm/lib
Duncan P. N. Exon Smith 3115f75bf8 ValueMapper: Rotate distinct node remapping algorithm
Rotate the algorithm for remapping distinct nodes in order to simplify
how uniquing cycles get resolved.  This removes some of the recursion,
and, most importantly, exposes all uniquing cycles at the top-level.
Besides being a little more efficient -- temporary MDNodes won't live as
long -- the clearer logic should help protect against bugs like those
fixed in r243961 and r243976.

What are uniquing cycles?  Why do they present challenges when remapping
metadata?

    !0 = !{!1}
    !1 = !{!0}

!0 and !1 form a simple uniquing cycle.  When remapping from one
metadata graph to another, every uniquing cycle gets "duplicated"
through a dance:

    !0-temp = !{!1?}     ; map(!0): clone !0, VM[!0] = !0-temp
    !1-temp = !{!0?}     ; ..map(!1): clone !1, VM[!1] = !1-temp
    !1-temp = !{!0-temp} ; ..map(!1): remap !1's operands
    !2      = !{!0-temp} ; ..map(!1): uniquify: !1-temp => !2
    !0-temp = !{!2}      ; map(!0): remap !0's operands
    !3      = !{!2}      ; map(!0): uniquify: !0-temp => !3

    ; Result
    !2 = !{!3}
    !3 = !{!2}

(In the two "uniquify" steps above, the operands of !X-temp are compared
to the operands of !X.  If they're the same, then !X-temp gets RAUW'ed
to !X; if they're different, then !X-temp is promoted to a new unique
node.  The latter case always hits in for uniquing cycles, so we
duplicate all the nodes involved.)

Why is this a problem?  Uniquable Metadata nodes that have temporary
node as transitive operands keep RAUW support until the temporary nodes
get finalized.  With non-cycles, this happens automatically: when a
uniquable node's count of unresolved operands drops to zero, it
immediately sheds its own RAUW support (possibly triggering the same in
any node that references it).  However, uniquing cycles create a
reference cycle, and uniqued nodes that transitively reference a
uniquing cycle are "stuck" in an unresolved state until someone calls
`MDNode::resolveCycles()` on a node in the unresolved subgraph.

Distinct nodes should help here (and mostly do): since they aren't
uniqued anywhere, they are guaranteed not to be RAUW'ed.  They
effectively form a barrier between uniqued nodes, breaking some uniquing
cycles, and shielding uniqued nodes from uniquing cycles.

Unfortunately, with this barrier in place, the unresolved subgraph(s)
can be disjoint from the top-level node.  The mapping algorithm needs to
find at least one representative from each disjoint subgraph.  But which
nodes are *stuck*, and which will get resolved automatically?  And which
nodes are in the unresolved subgraph?  The old logic was conservative.

This commit rotates the logic for distinct nodes, so that we have access
to unresolved nodes at the top-level call to `llvm::MapMetadata()`.
Each time we return to the top-level, we know that all temporaries have
been RAUW'ed away.  Here, it's safe (and necessary) to call
`resolveCycles()` immediately on unresolved operands.

This should also perform better than the old algorithm.  The recursion
stack is shorter, temporary nodes don't live as long, and there are
fewer tracking references to unresolved nodes.  As the debug info graph
introduces more 'distinct' nodes, remapping should incrementally get
cheaper and cheaper.

Aside from possible performance improvements (and reduced cruft in the
`LLVMContext`), there should be no functionality change here.

llvm-svn: 244181
2015-08-05 23:52:42 +00:00
..
Analysis Add a stat to show how often the limit to decompose GEPs in BasicAA is reached. 2015-08-05 23:40:30 +00:00
AsmParser Fix with a bit more care. (but only a bit) 2015-08-03 20:55:00 +00:00
Bitcode DI: Disallow uniquable DICompileUnits 2015-08-03 17:26:41 +00:00
CodeGen If the "CodeView" module flag is set, emit codeview instead of DWARF 2015-08-05 22:26:20 +00:00
DebugInfo [dwarfdump] Ignore scattered relocations for mach-o. 2015-07-31 20:22:50 +00:00
ExecutionEngine -Wdeprecated-clean: Fix cases of violating the rule of 5 in ways that are deprecated in C++11 2015-08-05 20:20:29 +00:00
Fuzzer [libFuzzer] avoid build warnings in non-assert build (useful warning in this case) 2015-08-05 23:44:42 +00:00
IR Add a TrailingObjects template class. 2015-08-05 22:57:34 +00:00
IRReader Return a unique_ptr from getLazyBitcodeModule and parseBitcodeFile. NFC. 2015-06-16 22:27:55 +00:00
LTO Remove access to the DataLayout in the TargetMachine 2015-07-24 16:04:22 +00:00
LibDriver Add support for producing thin archives in llvm-lib. 2015-07-17 16:01:11 +00:00
LineEditor Use ADDITIONAL_HEADER_DIRS in all LLVM CMake projects. 2015-02-11 03:28:02 +00:00
Linker Linker: Move distinct MDNodes instead of cloning 2015-08-03 17:09:38 +00:00
MC Force the MachO generated for Darwin to have VERSION_MIN load command 2015-08-05 15:36:38 +00:00
Object Use early return NFC. 2015-08-03 00:10:33 +00:00
Option Add an ArgList::AddAllArgs that accepts a vector of OptSpecifier. 2015-07-29 17:34:41 +00:00
Passes [PM] Fixup for r231556 where I missed a dependency on intrinsics 2015-03-07 09:08:20 +00:00
ProfileData Revert r240137 (Fixed/added namespace ending comments using clang-tidy. NFC) 2015-06-23 09:49:53 +00:00
Support [YAMLTraits] Use StringRef::copy. No functionality change. 2015-08-05 14:16:38 +00:00
TableGen TableGen: Support folding casts from bits to int 2015-07-31 01:12:06 +00:00
Target x86: NFC remove needless InstrCompiler cast 2015-08-05 23:15:37 +00:00
Transforms ValueMapper: Rotate distinct node remapping algorithm 2015-08-05 23:52:42 +00:00
CMakeLists.txt LibDriver, llvm-lib: introduce. 2015-06-09 21:50:22 +00:00
LLVMBuild.txt Wrap some long lines in LLVMBuild files. NFC 2015-06-12 18:44:57 +00:00
Makefile LibDriver, llvm-lib: introduce. 2015-06-09 21:50:22 +00:00