mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-30 15:10:33 +00:00
Add an interface to scale the frequencies of a set of blocks.
The scaling is done with reference to the the new frequency of a reference block. Differential Revision: https://reviews.llvm.org/D28535 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292507 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
02d80d355e
commit
d91b01bb76
@ -73,6 +73,12 @@ public:
|
||||
// Set the frequency of the given basic block.
|
||||
void setBlockFreq(const BasicBlock *BB, uint64_t Freq);
|
||||
|
||||
/// Set the frequency of \p ReferenceBB to \p Freq and scale the frequencies
|
||||
/// of the blocks in \p BlocksToScale such that their frequencies relative
|
||||
/// to \p ReferenceBB remain unchanged.
|
||||
void setBlockFreqAndScale(const BasicBlock *ReferenceBB, uint64_t Freq,
|
||||
SmallPtrSetImpl<BasicBlock *> &BlocksToScale);
|
||||
|
||||
/// calculate - compute block frequency info for the given function.
|
||||
void calculate(const Function &F, const BranchProbabilityInfo &BPI,
|
||||
const LoopInfo &LI);
|
||||
|
@ -180,6 +180,28 @@ void BlockFrequencyInfo::setBlockFreq(const BasicBlock *BB, uint64_t Freq) {
|
||||
BFI->setBlockFreq(BB, Freq);
|
||||
}
|
||||
|
||||
void BlockFrequencyInfo::setBlockFreqAndScale(
|
||||
const BasicBlock *ReferenceBB, uint64_t Freq,
|
||||
SmallPtrSetImpl<BasicBlock *> &BlocksToScale) {
|
||||
assert(BFI && "Expected analysis to be available");
|
||||
// Use 128 bits APInt to avoid overflow.
|
||||
APInt NewFreq(128, Freq);
|
||||
APInt OldFreq(128, BFI->getBlockFreq(ReferenceBB).getFrequency());
|
||||
APInt BBFreq(128, 0);
|
||||
for (auto *BB : BlocksToScale) {
|
||||
BBFreq = BFI->getBlockFreq(BB).getFrequency();
|
||||
// Multiply first by NewFreq and then divide by OldFreq
|
||||
// to minimize loss of precision.
|
||||
BBFreq *= NewFreq;
|
||||
// udiv is an expensive operation in the general case. If this ends up being
|
||||
// a hot spot, one of the options proposed in
|
||||
// https://reviews.llvm.org/D28535#650071 could be used to avoid this.
|
||||
BBFreq = BBFreq.udiv(OldFreq);
|
||||
BFI->setBlockFreq(BB, BBFreq.getLimitedValue());
|
||||
}
|
||||
BFI->setBlockFreq(ReferenceBB, Freq);
|
||||
}
|
||||
|
||||
/// Pop up a ghostview window with the current block frequency propagation
|
||||
/// rendered using dot.
|
||||
void BlockFrequencyInfo::view() const {
|
||||
|
@ -80,6 +80,14 @@ TEST_F(BlockFrequencyInfoTest, Basic) {
|
||||
EXPECT_EQ(BFI.getBlockProfileCount(BB3).getValue(), UINT64_C(100));
|
||||
EXPECT_EQ(BFI.getBlockProfileCount(BB1).getValue(), 100 * BB1Freq / BB0Freq);
|
||||
EXPECT_EQ(BFI.getBlockProfileCount(BB2).getValue(), 100 * BB2Freq / BB0Freq);
|
||||
|
||||
// Scale the frequencies of BB0, BB1 and BB2 by a factor of two.
|
||||
SmallPtrSet<BasicBlock *, 4> BlocksToScale({BB1, BB2});
|
||||
BFI.setBlockFreqAndScale(&BB0, BB0Freq * 2, BlocksToScale);
|
||||
EXPECT_EQ(BFI.getBlockFreq(&BB0).getFrequency(), 2 * BB0Freq);
|
||||
EXPECT_EQ(BFI.getBlockFreq(BB1).getFrequency(), 2 * BB1Freq);
|
||||
EXPECT_EQ(BFI.getBlockFreq(BB2).getFrequency(), 2 * BB2Freq);
|
||||
EXPECT_EQ(BFI.getBlockFreq(BB3).getFrequency(), BB3Freq);
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
Loading…
Reference in New Issue
Block a user