Skip to content

Commit 5178af2

Browse files
committed
Use single BlocksToIgnore and update comments
1 parent aa85400 commit 5178af2

File tree

3 files changed

+31
-22
lines changed

3 files changed

+31
-22
lines changed

llvm/include/llvm/Analysis/EHUtils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ namespace llvm {
1616
/// Compute a list of blocks that are only reachable via EH paths.
1717
template <typename FunctionT, typename BlockT>
1818
static void computeEHOnlyBlocks(FunctionT &F, DenseSet<BlockT *> &EHBlocks) {
19+
assert(EHBlocks.empty() && "Output set should be empty");
1920
// A block can be unknown if its not reachable from anywhere
2021
// EH if its only reachable from start blocks via some path through EH pads
2122
// NonEH if it's reachable from Non EH blocks as well.

llvm/include/llvm/Transforms/IPO/SampleProfileProbe.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,8 @@ class SampleProfileProber {
8282
uint32_t getBlockId(const BasicBlock *BB) const;
8383
uint32_t getCallsiteId(const Instruction *Call) const;
8484
void findInvokeNormalDests(DenseSet<BasicBlock *> &InvokeNormalDests);
85-
void computeCFGHash(const DenseSet<BasicBlock *> &InvokeNormalDests,
86-
const DenseSet<BasicBlock *> &KnownColdBlocks);
87-
void computeProbeIdForBlocks(const DenseSet<BasicBlock *> &InvokeNormalDests,
88-
const DenseSet<BasicBlock *> &KnownColdBlocks);
85+
void computeCFGHash(const DenseSet<BasicBlock *> &BlocksToIgnore);
86+
void computeProbeIdForBlocks(const DenseSet<BasicBlock *> &BlocksToIgnore);
8987
void computeProbeIdForCallsites();
9088

9189
Function *F;

llvm/lib/Transforms/IPO/SampleProfileProbe.cpp

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -174,14 +174,23 @@ SampleProfileProber::SampleProfileProber(Function &Func,
174174
CallProbeIds.clear();
175175
LastProbeId = (uint32_t)PseudoProbeReservedId::Last;
176176

177-
DenseSet<BasicBlock *> InvokeNormalDests;
178-
findInvokeNormalDests(InvokeNormalDests);
179-
DenseSet<BasicBlock *> KnownColdBlocks;
180-
computeEHOnlyBlocks(*F, KnownColdBlocks);
181-
182-
computeProbeIdForBlocks(InvokeNormalDests, KnownColdBlocks);
177+
DenseSet<BasicBlock *> BlocksToIgnore;
178+
// Ignore the cold EH blocks. This will reduce IR size as
179+
// well as the binary size while retaining the profile quality.
180+
computeEHOnlyBlocks(*F, BlocksToIgnore);
181+
// While optimizing nounwind attribute, the frondend may generate unstable IR,
182+
// e.g. some versions are optimized with the call-to-invoke conversion, while
183+
// other versions do not. This discrepancy in probe ID could cause profile
184+
// mismatching issues. To make the probe ID consistent, we can ignore all the
185+
// EH flows. Specifically, we can ignore the normal dest block which
186+
// originating from the same block as the call/invoke block and the unwind
187+
// dest block(computed in computeEHOnlyBlocks), which is a cold block. It
188+
// doesn't affect the profile quality.
189+
findInvokeNormalDests(BlocksToIgnore);
190+
191+
computeProbeIdForBlocks(BlocksToIgnore);
183192
computeProbeIdForCallsites();
184-
computeCFGHash(InvokeNormalDests, KnownColdBlocks);
193+
computeCFGHash(BlocksToIgnore);
185194
}
186195

187196
void SampleProfileProber::findInvokeNormalDests(
@@ -198,16 +207,18 @@ void SampleProfileProber::findInvokeNormalDests(
198207
// preceded by the number of indirect calls.
199208
// This is derived from FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash().
200209
void SampleProfileProber::computeCFGHash(
201-
const DenseSet<BasicBlock *> &InvokeNormalDests,
202-
const DenseSet<BasicBlock *> &KnownColdBlocks) {
210+
const DenseSet<BasicBlock *> &BlocksToIgnore) {
203211
std::vector<uint8_t> Indexes;
204212
JamCRC JC;
205213
for (auto &BB : *F) {
206-
// Skip the EH flow blocks.
207-
if (InvokeNormalDests.contains(&BB) || KnownColdBlocks.contains(&BB))
214+
if (BlocksToIgnore.contains(&BB))
208215
continue;
209-
210-
// Find the original successors by skipping the EH flow succs.
216+
// To keep the CFG Hash consistent before and after the call-to-invoke
217+
// conversion, we need to compute the hash using the original call BB's
218+
// successors for the invoke BB. As the current invoke BB's
219+
// successors(normal dest and unwind dest) are ignored, we keep searching to
220+
// find the leaf normal dest, the leaf's successors are the original call's
221+
// successors.
211222
auto *BBPtr = &BB;
212223
auto *TI = BBPtr->getTerminator();
213224
while (auto *II = dyn_cast<InvokeInst>(TI)) {
@@ -217,6 +228,8 @@ void SampleProfileProber::computeCFGHash(
217228

218229
for (BasicBlock *Succ : successors(BBPtr)) {
219230
auto Index = getBlockId(Succ);
231+
assert(Index &&
232+
"Ignored block(zero ID) should not be used for hash computation");
220233
for (int J = 0; J < 4; J++)
221234
Indexes.push_back((uint8_t)(Index >> (J * 8)));
222235
}
@@ -237,12 +250,9 @@ void SampleProfileProber::computeCFGHash(
237250
}
238251

239252
void SampleProfileProber::computeProbeIdForBlocks(
240-
const DenseSet<BasicBlock *> &InvokeNormalDests,
241-
const DenseSet<BasicBlock *> &KnownColdBlocks) {
242-
// Insert pseudo probe to non-cold blocks only. This will reduce IR size as
243-
// well as the binary size while retaining the profile quality.
253+
const DenseSet<BasicBlock *> &BlocksToIgnore) {
244254
for (auto &BB : *F) {
245-
if (InvokeNormalDests.contains(&BB) || KnownColdBlocks.contains(&BB))
255+
if (BlocksToIgnore.contains(&BB))
246256
continue;
247257
BlockProbeIds[&BB] = ++LastProbeId;
248258
}

0 commit comments

Comments
 (0)