Extends the CFGPrinter and CallPrinter with heat colors based on heuristics or profiling information.
The colors can be enabled for CFGPrinter by using the option -cfg-heat-colors for both -dot-cfg[-only] and -view-cfg[-only].
Similarly, the colors can be enabled for CallPrinter by using the option -callgraph-heat-colors for both -dot-callgraph and -view-callgraph.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Some code refactoring was performed, for example, replacing data structures from the C++ STL to equivalent one in LLVM ADT.
include/llvm/Analysis/CFGPrinter.h | ||
---|---|---|
80 ↗ | (On Diff #124217) | getF -> getFunction |
158 ↗ | (On Diff #124217) | Can you commit these format changes separately as NFC? |
255 ↗ | (On Diff #124217) | total may overflow .. |
272 ↗ | (On Diff #124217) | to get edge frequency, what you should do is to: get the edge probability information using BPI, and then multiply it with the source BB's frequency. For edges, the branch probability data is also useful to be displayed. |
279 ↗ | (On Diff #124217) | early return if not? |
lib/Analysis/CFGPrinter.cpp | ||
26 ↗ | (On Diff #124217) | IMO, it is better to make it 'true' by default. |
82 ↗ | (On Diff #124217) | use function level max freq can be misleading. The function itself can be totally cold according to the profile summary. With profile data, it is better to use profile summary data: There are three ranges : hot, medium (between hot and cold), and cold. |
Changes regarding @davidxl comments.
About the edge labels:
The default is to show the branch probability of the edge.
If -cfg-raw-weights=true, then it either displays the old label if it can be acquired from the metadata, otherwise it displays the product of branch probability and the source BB's frequency.
For the last comment about computing the max. freq. based on the function level.
I completely agree that a function level max. freq. can be misleading.
I had originally written my CFGHeatPrinter plugin as a ModulePass, which I believe is better suited for this use case.
I would then compute the heat-ratio of each basic block, based on the basic block with the max. freq. on the module level.
Updates the CFGPrinters to work on a per-module basis.
Because the heat factor of each basic block is computed relative to others within the scope being analysed
if we compute the heat factor relative to the basic block with the maximum frequency within the whole module,
it should provide heat colors more representative to the true block frequencies than if we compute the same values
on a per-function basis.
Ideally, the heat map would be computed using profiling information and considering the whole program (perhaps after linking all modules).
lib/Analysis/CallPrinter.cpp | ||
---|---|---|
58 ↗ | (On Diff #125125) | Consider templatizing this so that it works for LazyCallGraph too. |
201 ↗ | (On Diff #125125) | How about add color attribute to call edges too -- especially when full graph is displayed? |
lib/Analysis/HeatUtils.cpp | ||
64 ↗ | (On Diff #125125) | This is not correct when FullCallGraph is displayed. In that case, you just need to get the callSite instruction and get its parent BB's frequency. |
Fixed function getNumOfCalls for both full and simplified visualization of the call-graph.
Added edge width in both CallPrinter and CFGPrinter based on the edge weight.
I've also performed some small code refactoring.
Fix small code-style standards.
Change option name to -callgraph-weights, instead of -callgraph-estimate-weight, similar to -cfg-weights.
lib/Analysis/CFGPrinter.cpp | ||
---|---|---|
135 ↗ | (On Diff #125434) | Should delete these print functions rather then comment them out . |
Add a minimal option test (new heat-color option) in test/Other/2007-06-05-PassID.ll ?
otherwise LGTM
I kept the print functions as they were already present in the code and this change is not related to the heat colors.
I added the 'override' attribute to the getAnalysisUsage functions in the CallGraph printers.
I also added some small tests to the file test/Other/2007-06-05-PassID.ll.
@rcorcs this has been accepted for quite a while, is there anything preventing integration? I'm looking forward to using colored graphs out of the box.
Minor update to avoid conflict with the latest LLVM release.
Hi, I believe it is ready for integration.
But I don't think I have commit access.
Perhaps someone with access can commit this patch or let me know how I could do it myself.
Thanks!
I've just noticed that last time I uploaded the wrong diff.
This is the actual diff that fixes all conflicts with the latest LLVM version.
Unfortunately I had to revert this (https://reviews.llvm.org/rL336000) since there were several build-bot breaks.
2 were related to Polly which I don't build so I missed that it has a dependency the CFG printer interface. It should be a simple to fix.
The third was a failure on the X86_64-sanitizer fast bot: FAIL: LLVM :: Other/2007-06-05-PassID.ll (20391 of 26226) which I'll have to look at a bit closer.
Shouldnt this be reopened?
Any plans to reintegrate this back - it seems to provide a very useful functionality...
I have fixed the bug that this patch was producing on Polly.
https://reviews.llvm.org/D49154
The bug detected by the sanitizer is being discussed here:
https://reviews.llvm.org/rL336000
Except for the bug detected by the sanitizer, which seems to be related to the old pass manager, this patch is ready to be committed.
Sorry, I had some trouble with my email for a few days and missed that the polly problem has been fixed. The patch I posted in the comment on https://reviews.llvm.org/rL336000 fixes the sanitizer failure, can you update this patch with that change? With that and the polly patch this is ready to be commited again.
@bollu If you have commit access to both polly and llvm you can commit them both? Otherwise we can arrange to commit them at the same time.
Fix of the sanitizer failure as suggested by @sfertile:
https://reviews.llvm.org/rL336000