This is an archive of the discontinued LLVM Phabricator instance.

RFC: Interpet {branch_weights 1, 0} as likely/unlikely
AbandonedPublic

Authored by MatzeB on Aug 23 2023, 3:56 PM.

Details

Summary

This changes BranchProbabilityInfo to interpret branch weights metadata having only 1 non-zero entry as "likely"/"unlikely" branches.
Meaning !{"branch_weights", i32 1, i32 0} being an abstract representation of a "likely" branch. The adjustments for the concrete weights of likely/unlikely are moved into BranchProbabilityInfo and are applied when computing the analysis.

Diff Detail

Event Timeline

MatzeB created this revision.Aug 23 2023, 3:56 PM
MatzeB requested review of this revision.Aug 23 2023, 3:56 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 23 2023, 3:57 PM

And here's another straw-man proposal to get a discussion going: Because I am having trouble to say what the difference between branch_weights 1, 0 and llvm.expect even is: This change turns any branch_weights X, 0 or branch_weights 0, X into an abstract representation of likely/unlikely that BranchProbabilityInfo will interpret when computing the analysis...

MatzeB retitled this revision from Interpet {branch_weights 1, 0} as likely/unlikely to RFC: Interpet {branch_weights 1, 0} as likely/unlikely.
mtrofin added a reviewer: xur.Aug 24 2023, 9:49 AM
mtrofin added inline comments.Aug 24 2023, 9:55 AM
llvm/include/llvm/Analysis/BranchProbabilityInfo.h
144

docstring for normalizeLikelyWeights? that's the new thing, right - the other one just moved from ProfDataUtils.h?

llvm/lib/Analysis/BranchProbabilityInfo.cpp
393

What's HadNonZeroWeight gonna do after this loop?

1369

nit: spurious

llvm/test/Transforms/SampleProfile/profile-inference.ll
215

this caught my eye - how did count = 0 get to count = 3?

MatzeB marked an inline comment as done.Aug 24 2023, 10:32 AM
MatzeB added inline comments.
llvm/test/Transforms/SampleProfile/profile-inference.ll
215

This comes from the fact that !{"branch_weights", i32 X, i32 0} gets interpreted as !{"branch_weights", i32 LikelyBranchWeight, i32 1} now. So absolutes like a branch count / block being always zero is no longer the case.

I was contemplating whether there is/should be a difference between a branch reported as 0 by profile information or a branch marked as [[unlikely]]...

I don't know myself whether this change is actually a good idea (so at the moment no plans of landing it). But I thought it would make for an interesting RFC / strawman and elicit comments from people who have worked on profiling in the past.

MatzeB abandoned this revision.Sep 1 2023, 5:18 PM
MatzeB marked an inline comment as done.
wenlei added a comment.Sep 5 2023, 9:51 AM

Meaning !{"branch_weights", i32 1, i32 0} being an abstract representation of a "likely" branch.

In general, an abstract representation should not conflict with a valid concrete representation..

The adjustments for the concrete weights of likely/unlikely are moved into BranchProbabilityInfo and are applied when computing the analysis.

BPI should be an analysis that only consumes branch weights, and I don't particularly like the idea of, oh btw, it will try to canonicalize branch weights when it runs.

If we want to canonicalize likely/unlikely representation for branch weights, we should probably do it elsewhere and make sure it's created that way rather than trying to lazily fix things up on when it is used.

Proper canonicalization is probably a much bigger change, so the next question is, is it worth it?

I can see that a {X,0} and {1,0} are equivalent in terms of branch probabilities, and the use of branch metadata in BranchProbabilityInfo::calcMetadataWeights also confirms that. Is there any practical purpose of this normalization other than clean things up?

There is a subtle difference between {X,0} and {1,0}. A lot of heuristic in PGO likes to +1 to everything to avoid 0s, and {X+1,1} vs {2,1} can be hugely different. Examples are: SampleProfileLoader::generateMDProfMetadata, and BlockFrequencyInfoImplBase::addToDist (though this one should not be impacted by this change as it's on BFI layer)

The other thing is there are some existing inconsistencies as to whether we should care about absolute values of branch weights or not.

  1. For branch instructions, we care about only the distribution, but not the values; for calls however, we do care about the absolute values. And for sample pgo, we annotate branch weights with actual counts, even though the values don't change BPI result. Many people working in sample PGO like to think about branch weights values as a good reference, but their absolute values may not always be meaningful. I know that may have diverged from what the llvm docs say, but that's the status quo.
  1. We also don't attempt to normalize {X*Y, Z*Y} to {X, Z}. If we don't do that, do we actually care about {X,0} and {1,0}, which is special form of the former.

This is already abandoned, so will not further pursue this. But for the discussion:

In general, an abstract representation should not conflict with a valid concrete representation..

In some way this change assumed that 1,0 was not really a valid representation. Because as you point out later sample profile loaders etc. actually trying hard to avoid the ,0 case by adding +1 which feels like people maybe do not want it to be legal and then we could have re-used it :)

Normalization is also an interesting topic and FWIW we do have the BranchProbability used by BPI and MIR-representation that is more normalized (though there is also oddities, like noone forcing them to sum up to "1" in the backend...) Anyway I'll keep mulling over those in the background, as they're mostly just oddities that I cannot understand, but not necessarily a problem.

Because as you point out later sample profile loaders etc. actually trying hard to avoid the ,0 case by adding +1 which feels like people maybe do not want it to be legal and then we could have re-used it :)

Well.. this is a heuristic that is not on for all patch. In the case of sample loader, when profi is on, we don't do the +1 thingy. We also don't do +1 because 0 is invalid. So it holds true that the abstract representation used here conflicts with a valid concrete representation.

Anyway I'll keep mulling over those in the background, as they're mostly just oddities that I cannot understand, but not necessarily a problem.

SG. Unfortunately, some oddities can't be cleaned up easily. We probably have to live with the fact that sometimes we care about the values of branch weights, and sometimes only its distribution..