This is an archive of the discontinued LLVM Phabricator instance.

Add new interfaces to MBB for manipulating successors with probabilities instead of weights.
ClosedPublic

Authored by congh on Oct 20 2015, 11:06 AM.

Details

Summary

The patch in http://reviews.llvm.org/D13745 is broken into four parts:

  1. New interfaces without functional changes.
  2. Use new interfaces in SelectionDAG, while in other passes treat probabilities as weights.
  3. Use new interfaces in all other passes.
  4. Remove old interfaces.

This the first patch above.

Diff Detail

Repository
rL LLVM

Event Timeline

congh updated this revision to Diff 37897.Oct 20 2015, 11:06 AM
congh retitled this revision from to Add new interfaces to MBB for manipulating successors with probabilities instead of weights..
congh updated this object.
congh added reviewers: dexonsmith, manmanren, davidxl.
congh added a subscriber: llvm-commits.
davidxl added inline comments.Oct 20 2015, 11:48 AM
lib/CodeGen/MachineBasicBlock.cpp
526 ↗(On Diff #37897)

zero is a valid probability, so do not use to signal 'unknown'

I think we should define a special const BP value to represent 'unknown' BP (which is different from default 1/N). This is doable as the our choice of denominator is 1<<31, so a larger than 1<<1 nominator can be picked to represent the special reserved value

529 ↗(On Diff #37897)

When Probs.empty() is false, shall we assert that Prob must be known?

551 ↗(On Diff #37897)

normalization needed or it is premature to do normalization now? It is probably the later as this is low level interface with very little context.

617 ↗(On Diff #37897)

oldWI --> oldPI

618 ↗(On Diff #37897)

why += not = ?

1153 ↗(On Diff #37897)

document that default probability is returned when there is no information.

1172 ↗(On Diff #37897)

Why the behavior here is different from addSuccessor where only 'unknown' probs are ignored.

congh marked 2 inline comments as done.Oct 20 2015, 2:34 PM
congh added inline comments.
lib/CodeGen/MachineBasicBlock.cpp
526 ↗(On Diff #37897)

Right. I have created such an unknown probability by using UINT32_MAX as the numerator.

I think we can always keep unknown probabilities in the list and when getSuccProb() is called to get the probability of a successor, and the returned probability is unknown, we can calculate a "default" value on the fly, which is (1-P) / N, where P is the sum of all known probabilities, and N is the number of unknown probabilities. What do you think?

529 ↗(On Diff #37897)

If we want to use the unknown probability to represent a "default" probability then we cannot make this assertion here. Unless we create another interface which is used to add successor when the probability is unknown (which is not added here as it will conflict with the one that already exists with second argument having a default value). I think a good idea is this interface should be always called with a known probability.

551 ↗(On Diff #37897)

Yes, it seems the normalization should be called explicitly by the user of this interface. One way to validate BPI is check if the sum of successors' probabilities is around 1 for all blocks, so we can get warnings if the user forget to normalize probabilities.

618 ↗(On Diff #37897)

Here New is already a successor and this function behaves like merging two successors into one. That is why += is used.

1172 ↗(On Diff #37897)

I have added an assertion checking Prob is not unknown. We should not allow unknown probability to be used here.

congh updated this revision to Diff 37936.Oct 20 2015, 3:13 PM

Update the patch according to David's comment.

davidxl added inline comments.Oct 20 2015, 5:22 PM
lib/CodeGen/MachineBasicBlock.cpp
527 ↗(On Diff #37936)

I think it is better to assert Successors.size() is 0 here. Under what situation can have mixed 'known' and 'known' probabilities?

1164 ↗(On Diff #37936)

Is it up to the user to decide whether a default value should be returned?

1167 ↗(On Diff #37936)

How is this possible? Should be it asserted that Prob is Known?

1191 ↗(On Diff #37936)

my question is addSuccessor interface will allocate Prob vector if Prob is known, but the behavior here is different.

congh added inline comments.Oct 20 2015, 5:42 PM
lib/CodeGen/MachineBasicBlock.cpp
527 ↗(On Diff #37936)

As we have concluded before, currently the unknown weight and default weight are both added through the same interface, and it is impossible to differentiate them. I suggest for addSuccessor() of weight version we can split it into two interfaces:

  1. addSuccessorWithWeight(MBB *succ, uint32_t weight = 0);

This one is used when the weight is known, and we use 0 as a default weight. When this interface is called, the weight list should always have the same size of successor list.

  1. addSuccessor(MBB *succ);

This one is used when the weight is unknown (BPI is unavailable). When this interface is called, the weight list should always be empty.

We can introduce similar interfaces for probability version.

1164 ↗(On Diff #37936)

Should the user know that the returned probability is an unknown one? It is like an undefined behavior and here we just give it a definition.

1167 ↗(On Diff #37936)

As I suggested before, we can keep all unknown probabilities (which is used to represent default probabilities) in MBB and return a "default" value on the fly.

1191 ↗(On Diff #37936)

When setSuccProbability() is called, the user must have known a known probability otherwise why he would like to call this function? That is why we need to check that the passed in probability is known.

davidxl added inline comments.Oct 21 2015, 9:58 AM
lib/CodeGen/MachineBasicBlock.cpp
527 ↗(On Diff #37936)

Can you elaborate on why two use cases can not be differentiated? It seems that the unknown BP should only be used when BPI == 0 (i.e. when Optimization level == 0).

529 ↗(On Diff #37936)

For the new interfaces, I think we should enforce the policy:

  1. do not mix unknown and known branch probabilities
  2. unknown branch probability is only used (in constructor/setter) when optimization is disabled.
  3. when optimization is not disabled, known BP should be used always -- even though there exist client code that does not provide the information -- the implementation can choose to use the 1/N default
  1. the public BP getter interfaces should never return unknown BP (private ones can if needed)

How does that sound?

1164 ↗(On Diff #37936)

Ok -- i guess the direct caller of this function does not have any better info.

1167 ↗(On Diff #37936)

See my comments above. If we don't ever mix unknown and known BP, there is no need to store any unknown BPs.

1191 ↗(On Diff #37936)

but why return when Prob is empty?

congh added inline comments.Oct 21 2015, 10:57 AM
lib/CodeGen/MachineBasicBlock.cpp
527 ↗(On Diff #37936)

Consider this scenario: we first add a successor with a known (precalculated) probability 1/2, then add another successor with the default probability. Now as N=2, it is assigned with 1/2. Then we add the third successor with the default probability. Now the sum of the other two successors' probabilities is already 1, so we can normalize them. But we could not recover the probability of the first successor to 1/2 anymore, which is a precalculated one and should not be changed later. This is the tricky situation. If we record those two default probabilities as unknown, we could calculated them on the fly (then the probabilities of three successors will be 1/2, 1/4, 1/4, which is more reasonable), and everything will be ok.

529 ↗(On Diff #37936)

Please check my example above. However, I need to confirm that that situation happens. I could make a patch to differentiate addSuccessor() with known/default weights and with unknown weights, and then check if calls of this function have mixed known and default weights.

1191 ↗(On Diff #37936)

The input is an iterator and when prob list is empty, we can do nothing (we cannot find the corresponding BP for the given successor). setEdgeWeight has the similar behavior.
So you are thinking about the case that all successors have default weights and then the weight list can be empty, right? I think this could happen... and this is why we need to follow the rule that the weight list is empty only if BPI is unavailable.

davidxl added inline comments.Oct 21 2015, 1:28 PM
lib/CodeGen/MachineBasicBlock.cpp
527 ↗(On Diff #37936)

In the long run, we should fix those client code that provides default probability as many as we can. As it stands today, it is garbage-in and garbage-out situation -- we don't need to pretend one handling is better than the other.

The profile sanity tool we plan to have in the future is supposed to detect problems like this.

congh updated this revision to Diff 38578.Oct 27 2015, 11:48 AM

Update the patch after the patch http://reviews.llvm.org/D13908 is checked in.

davidxl added inline comments.Nov 4 2015, 9:37 AM
lib/CodeGen/MachineBasicBlock.cpp
1173 ↗(On Diff #38578)

With the latest change, is it (i.e prob.isUnknown()) possible now? If not, do an assertion.

congh updated this revision to Diff 39216.Nov 4 2015, 10:39 AM

Update the patch according to David's comment.

congh marked an inline comment as done.Nov 4 2015, 10:40 AM
congh added inline comments.
lib/CodeGen/MachineBasicBlock.cpp
1173 ↗(On Diff #39216)

OK. Let's not allow unknown probabilities in the list now. Done.

davidxl edited edge metadata.Nov 4 2015, 10:46 AM

LGTM. Looking forward to followup patches to remove weight based interfaces. (may revisit the unknown BP handling in those patches).

This revision was automatically updated to reflect the committed changes.