[LLVMdev] FoldingSetNodeID operations inefficiency
Roman Levenstein
romixlev at yahoo.com
Wed Apr 23 03:22:53 PDT 2008
Hi,
While profiling LLVM using my test-cases with huge MBBs, I noticed that
FoldingSetNodeID operations (ComputeHash,insertion,etc) may become
really inefficient for the nodes, which have very many operands.
I can give you an example of what is meant by "very many". In my
test-case (you can fetch it from here
http://llvm.org/bugs/attachment.cgi?id=1275), which is just one HUGE MBB
with tens of thousends of instructions, there is a TokenFactor node N
that has ... 3200 operands! (These operands are PendingLoads created by
the SelectionDAGLowering::getLoadFrom and then copied into the
TokenFactor node by SelectionDAGLowering::getRoot called from the
SelectionDAGLowering::visitStore).
During the code selection phase, the SelectionDAG::ReplaceAllUsesWith is
called many times and in many cases it tried to update this node, by
replacing some of its 3200 operands by a different operand. After each
such operand replacement, this snippen of code is typically executed
(see SelectionDAG.cpp):
// Now that we have modified U, add it back to the CSE maps.
// If it already exists there, recursively merge the results together.
if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) {
ReplaceAllUsesWith(U, Existing, UpdateListener);
// U is now dead. Inform the listener if it exists and delete it.
if (UpdateListener)
UpdateListener->NodeDeleted(U);
DeleteNodeNotInCSEMaps(U);
} else {
// If the node doesn't already exist, we updated it.
// Inform a listener if it exists.
if (UpdateListener)
UpdateListener->NodeUpdated(U);
}
So, basically CSE map should be updated. To achieve that, a hash of the
updated node N is computed (and its internal FoldingSetNodeID::Bits
array contains about 6400 elements!) and the node is replaced.
My observation shows that amount of FoldingSetNodeID operations on this
node N is almost quadratic. It manifests itself by consuming about 20%
of the compilation time only for these operations.
Question:
Does anyone see an opportunity to solve this issue?
My current ideas are:
- avoid recomputation of the hash values for nodes that were not
changed since the hash was computed last time
- do some sort of lazy CSE maps update. Accumulate operand changes for
a given node and then do only one update. But I don't see yet, how it
can be done practically
- Optimize the SelectionDAG::ReplaceAllUsesWith to do bulk updates,
i.e. updating many user nodes of the given node at once or updating all
operands of the given node at once. Again, I don't see how to do it
practically.
- May be the issue is related to the strange TokenFactor node with the
3200 operands. May be creation of the node with so many operands can be
avoided?
Any ideas are appriciated!
-Roman
Lesen Sie Ihre E-Mails jetzt einfach von unterwegs.
www.yahoo.de/go
More information about the llvm-dev
mailing list