mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-04-14 21:51:19 +00:00

the sum of the edge weights not overflowing uint32, and crashed when they did. This is generally safe as BranchProbabilityInfo tries to provide this guarantee. However, the CFG can get modified during codegen in a way that grows the *sum* of the edge weights. This doesn't seem unreasonable (imagine just adding more blocks all with the default weight of 16), but it is hard to come up with a case that actually triggers 32-bit overflow. Fortuately, the single-source GCC build is good at this. The solution isn't very pretty, but its no worse than the previous code. We're already summing all of the edge weights on each query, we can sum them, check for an overflow, compute a scale, and sum them again. I've included a *greatly* reduced test case out of the GCC source that triggers it. It's a pretty lame test, as it clearly is just barely triggering the overflow. I'd like to have something that is much more definitive, but I don't understand the fundamental pattern that triggers an explosion in the edge weight sums. The buggy code is duplicated within this file. I'll colapse them into a single implementation in a subsequent commit. llvm-svn: 144526
84 lines
3.2 KiB
C++
84 lines
3.2 KiB
C++
|
|
//==- MachineBranchProbabilityInfo.h - Machine Branch Probability Analysis -==//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This pass is used to evaluate branch probabilties on machine basic blocks.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H
|
|
#define LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H
|
|
|
|
#include "llvm/Pass.h"
|
|
#include "llvm/Support/BranchProbability.h"
|
|
#include <climits>
|
|
|
|
namespace llvm {
|
|
|
|
class raw_ostream;
|
|
class MachineBasicBlock;
|
|
|
|
class MachineBranchProbabilityInfo : public ImmutablePass {
|
|
|
|
// Default weight value. Used when we don't have information about the edge.
|
|
// TODO: DEFAULT_WEIGHT makes sense during static predication, when none of
|
|
// the successors have a weight yet. But it doesn't make sense when providing
|
|
// weight to an edge that may have siblings with non-zero weights. This can
|
|
// be handled various ways, but it's probably fine for an edge with unknown
|
|
// weight to just "inherit" the non-zero weight of an adjacent successor.
|
|
static const uint32_t DEFAULT_WEIGHT = 16;
|
|
|
|
// Get sum of the block successors' weights, potentially scaling them to fit
|
|
// within 32-bits. If scaling is required, sets Scale based on the necessary
|
|
// adjustment. Any edge weights used with the sum should be divided by Scale.
|
|
uint32_t getSumForBlock(MachineBasicBlock *MBB, uint32_t &Scale) const;
|
|
|
|
public:
|
|
static char ID;
|
|
|
|
MachineBranchProbabilityInfo() : ImmutablePass(ID) {
|
|
PassRegistry &Registry = *PassRegistry::getPassRegistry();
|
|
initializeMachineBranchProbabilityInfoPass(Registry);
|
|
}
|
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const {
|
|
AU.setPreservesAll();
|
|
}
|
|
|
|
// Return edge weight. If we don't have any informations about it - return
|
|
// DEFAULT_WEIGHT.
|
|
uint32_t getEdgeWeight(MachineBasicBlock *Src, MachineBasicBlock *Dst) const;
|
|
|
|
// A 'Hot' edge is an edge which probability is >= 80%.
|
|
bool isEdgeHot(MachineBasicBlock *Src, MachineBasicBlock *Dst) const;
|
|
|
|
// Return a hot successor for the block BB or null if there isn't one.
|
|
MachineBasicBlock *getHotSucc(MachineBasicBlock *MBB) const;
|
|
|
|
// Return a probability as a fraction between 0 (0% probability) and
|
|
// 1 (100% probability), however the value is never equal to 0, and can be 1
|
|
// only iff SRC block has only one successor.
|
|
// NB: This routine's complexity is linear on the number of successors of
|
|
// Src. Querying sequentially for each successor's probability is a quadratic
|
|
// query pattern.
|
|
BranchProbability getEdgeProbability(MachineBasicBlock *Src,
|
|
MachineBasicBlock *Dst) const;
|
|
|
|
// Print value between 0 (0% probability) and 1 (100% probability),
|
|
// however the value is never equal to 0, and can be 1 only iff SRC block
|
|
// has only one successor.
|
|
raw_ostream &printEdgeProbability(raw_ostream &OS, MachineBasicBlock *Src,
|
|
MachineBasicBlock *Dst) const;
|
|
};
|
|
|
|
}
|
|
|
|
|
|
#endif
|