Problem using BlockFrequencyInfo's getBlockProfileCount

Hey,

I am trying to use the BlockFrequencyInfoWrapperPass to obtain hotness
information in my LLVM pass. Attached is a minimal example of code which
creates a SIGSEGV. The pass calls
AU.addRequired<BlockFrequencyInfoWrapperPass>(); in
getAnalysisUsage(..). The problem exists with changed and unchanged IR.

The binary is instrumented like this: clang input.bc -fprofile-generate
-o output

The binary runs with selected inputs and the profiles are merged:
llvm-profdata merge input.profraw -output=output.prof

Then opt runs with arguments: opt input.bc -o output.bc -load mypass.so
-block-freq -pgo-instr-use -pgo-test-profile-file=output.prof
-profile-sample-accurate -mypass

Is this a bug or am can someone provide an example on how to use
BlockFrequencyInfo correctly?

Example code:

for (auto& F : M) {
if (F.isDeclaration()) {
continue;
}
auto& bfiPass = getAnalysis<BlockFrequencyInfoWrapperPass>(F);
llvm::BlockFrequencyInfo* BFI = &bfiPass.getBFI();

 //Works \- shows all info I want
 BFI\-&gt;print\(llvm::dbgs\(\)\);

 for \(const llvm::BasicBlock&amp; B : F\) \{
     //Fails with SIGSEGV \-&gt; \*getFunction\(\) returns 0xa
     dbgs\(\) &lt;&lt; BFI\-&gt;getBlockProfileCount\(&amp;B\)\.getValueOr\(0\) &lt;&lt; &quot;\\n&quot;;
 \}

}

lib/Analysis/BlockFrequencyInfo.cpp#L211

return BFI->getBlockProfileCount(*getFunction(), BB);

Hey,

I am trying to use the BlockFrequencyInfoWrapperPass to obtain hotness
information in my LLVM pass. Attached is a minimal example of code which
creates a SIGSEGV. The pass calls
AU.addRequired(); in
getAnalysisUsage(…). The problem exists with changed and unchanged IR.

The binary is instrumented like this: clang input.bc -fprofile-generate
-o output

The binary runs with selected inputs and the profiles are merged:
llvm-profdata merge input.profraw -output=output.prof

Then opt runs with arguments: opt input.bc -o output.bc -load mypass.so
-block-freq -pgo-instr-use -pgo-test-profile-file=output.prof
-profile-sample-accurate -mypass

Is this a bug or am can someone provide an example on how to use
BlockFrequencyInfo correctly?

Example code:

for (auto& F : M) {
if (F.isDeclaration()) {
continue;
}
auto& bfiPass = getAnalysis(F);
llvm::BlockFrequencyInfo* BFI = &bfiPass.getBFI();

//Works - shows all info I want
BFI->print(llvm::dbgs());

I don’t know offhand why your code below is segfaulting, but note that BFI->print() will dereference the F pointer just as *getFunction below will. I would look in the debugger to see what the value of F is during print() since it seems to be ok there, and then see if you can figure out where it is changing if it is returning a bad value below.
Teresa

Hey,

I am trying to use the BlockFrequencyInfoWrapperPass to obtain hotness
information in my LLVM pass. Attached is a minimal example of code which
creates a SIGSEGV. The pass calls
AU.addRequired(); in
getAnalysisUsage(…). The problem exists with changed and unchanged IR.

The binary is instrumented like this: clang input.bc -fprofile-generate
-o output

The binary runs with selected inputs and the profiles are merged:
llvm-profdata merge input.profraw -output=output.prof

Then opt runs with arguments: opt input.bc -o output.bc -load mypass.so
-block-freq -pgo-instr-use -pgo-test-profile-file=output.prof
-profile-sample-accurate -mypass

Is this a bug or am can someone provide an example on how to use
BlockFrequencyInfo correctly?

Example code:

for (auto& F : M) {
if (F.isDeclaration()) {
continue;
}
auto& bfiPass = getAnalysis(F);
llvm::BlockFrequencyInfo* BFI = &bfiPass.getBFI();

//Works - shows all info I want
BFI->print(llvm::dbgs());

I don’t know offhand why your code below is segfaulting, but note that BFI->print() will dereference the F pointer just as *getFunction below will. I would look in the debugger to see what the value of F is during print() since it seems to be ok there, and then see if you can figure out where it is changing if it is returning a bad value below.
Teresa

Thanks for the feedback! I’ve tried debugging but this didn’t get me far. I found a different solution. First, you’re right that my code is correct. The problem existed elsewhere.
I’ve upgraded to the latest LLVM 8 commit and - after recompiling my projects - the above code executed without segfaults. Going back to my LLVM 7.01 source build, and again I could no longer observe any segfaults. I know that one of my projects was compiled with clang 7, while LLVM build from source was done with the system’s default gcc/g++ 8. Not sure if combining differently compiled libraries is considered UB in C++, but after using the same compiler for both parts errors stopped occurring.