[PATCH] ValueMapper: Rewrite Mapper::mapMetadata without recursion
Duncan P. N. Exon Smith via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 5 13:33:42 PDT 2016
> On 2016-Apr-05, at 11:39, Mehdi Amini <mehdi.amini at apple.com> wrote:
>
>>
>> On Apr 3, 2016, at 10:51 PM, Duncan P. N. Exon Smith <dexonsmith at apple.com> wrote:
>>
>> This commit completely rewrites Mapper::mapMetadata (the implementation
>> of llvm::MapMetadata) using an iterative algorithm. The guts of the new
>> algorithm are in MDNodeMapper::map, the entry function in a new class.
>>
>> Previously, Mapper::mapMetadata performed a recursive exploration of the
>> graph with eager "just in case there's a reason" malloc traffic.
>>
>> The new algorithm has these benefits:
>>
>> - New nodes and temporaries are not created eagerly.
>> - Uniquing cycles are not duplicated (see new unit test).
>> - No recursion.
>>
>> Given a node to map, it does this:
>>
>> 1. Use a worklist to perform a post-order traversal of the transitively
>> referenced unmapped nodes.
>>
>> 2. Track which nodes will change operands, and which will have new
>> addresses in the mapped scheme. Propagate the changes through the
>> POT until fixed point, to pick up uniquing cycles that need to
>> change.
>>
>> 3. Map all the distinct nodes without touching their operands. If
>> RF_MoveDistinctMetadata, they get mapped to themselves; otherwise,
>> they get mapped to clones.
>>
>> 4. Map the uniqued nodes (bottom-up), lazily creating temporaries for
>> forward references as needed.
>>
>> 5. Remap the operands of the distinct nodes.
>>
>> MapMetadata barely shows up in the profiles of llvm-link I've looked at
>> with the new algorithm.
>>
>> It would be nice to break the strange remaining recursion on the Value
>> side: MapValue => materializeInitFor => RemapInstruction => MapValue. I
>> think we could do this by somehow leaking (at least an opaque version
>> of) the "Mapper" context into the API, perhaps by sending a callback
>> function to materializeInitFor.
>>
>>
>> <0001-ValueMapper-Rewrite-Mapper-mapMetadata-without-re-v1.patch>
>
>
>
> The CPU profiling does not show a great improvement (~10-15%), because to many map query I think.
> The memory profile is better with close to 50% less persistent memory, 33% less transient memory, but also a lot less transient memory allocations.
> On my example there were 2.5M allocations before and now there are only 266k allocations! A lot let stressful for the memory subsystem :)
FYI, Mehdi and I looked at this at his desk, and it dropped from 2.5M down
to 26k, about 100x fewer.
> On the code itself now, MDNodeMapper::map() is fairly clear but for the interaction between createPOT() and propagateChangedOperands().
> The former says it is doing "a traversal of the unmapped subgraph, checking for changed operands”, which make it surprising that you need propagateChangedOperands() afterward.
I cleaned up the comment a little. It does check for changed
operands, which maybe is a bit confusing.
> Below just two nits:
Committed r265456. I thought I remembered an LGTM here, but looking
again I don't see it; sorry for jumping the gun :(. (I can revert?)
>
> + assert(!(M.Flags & RF_NoModuleLevelChanges) &&
> + "MDNodeMapper::map assumes module-level changes");
>
>
> I think the string is wrong, it should be: "MDNodeMapper::map assumes NO module-level changes”.
The string is correct. There's a double negation in the assertion.
>
>
> + /// \post Data::HasChangedAddress == RF_MoveDistinctMDs if N.isDistinct().
>
> But the code is:
>
> + D.HasChangedAddress = !(M.Flags & RF_MoveDistinctMDs) && N.isDistinct();
>
> Which does not seem to match the comment, I think the comment is wrong and should be:
>
> + /// \post Data::HasChangedAddress == !RF_MoveDistinctMDs if N.isDistinct().
Nice catch. Fixed!
>
>
>
>
>
> —
> Mehdi
More information about the llvm-commits
mailing list