-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[profcheck] Exclude naked, asm-only functions from profcheck
#168447
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[profcheck] Exclude naked, asm-only functions from profcheck
#168447
Conversation
e677112 to
7605200
Compare
naked functions from profchecknaked, asm-only functions from profcheck
|
@llvm/pr-subscribers-pgo @llvm/pr-subscribers-llvm-transforms Author: Mircea Trofin (mtrofin) ChangesWe can't do anything meaningful to such functions: they aren't optimizable, and even if inlined, they would bring no code open to optimization. Full diff: https://github.com/llvm/llvm-project/pull/168447.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Utils/ProfileVerify.cpp b/llvm/lib/Transforms/Utils/ProfileVerify.cpp
index c7cf8256d393c..ca6bd91b1f530 100644
--- a/llvm/lib/Transforms/Utils/ProfileVerify.cpp
+++ b/llvm/lib/Transforms/Utils/ProfileVerify.cpp
@@ -65,11 +65,26 @@ class ProfileInjector {
ProfileInjector(Function &F, FunctionAnalysisManager &FAM) : F(F), FAM(FAM) {}
bool inject();
};
+
+bool isAsmOnly(const Function &F) {
+ if (!F.hasFnAttribute(Attribute::AttrKind::Naked))
+ return false;
+ for (const auto &BB : F)
+ for (const auto &I : drop_end(BB.instructionsWithoutDebug())) {
+ const auto *CB = dyn_cast<CallBase>(&I);
+ if (!CB || !CB->isInlineAsm())
+ return false;
+ }
+ return true;
+}
} // namespace
// FIXME: currently this injects only for terminators. Select isn't yet
// supported.
bool ProfileInjector::inject() {
+ // skip purely asm functions
+ if (isAsmOnly(F))
+ return false;
// Get whatever branch probability info can be derived from the given IR -
// whether it has or not metadata. The main intention for this pass is to
// ensure that other passes don't drop or "forget" to update MD_prof. We do
@@ -176,6 +191,10 @@ PreservedAnalyses ProfileInjectorPass::run(Function &F,
PreservedAnalyses ProfileVerifierPass::run(Function &F,
FunctionAnalysisManager &FAM) {
+ // skip purely asm functions
+ if (isAsmOnly(F))
+ return PreservedAnalyses::all();
+
const auto EntryCount = F.getEntryCount(/*AllowSynthetic=*/true);
if (!EntryCount) {
auto *MD = F.getMetadata(LLVMContext::MD_prof);
diff --git a/llvm/test/Transforms/PGOProfile/profcheck-exclusions.ll b/llvm/test/Transforms/PGOProfile/profcheck-exclusions.ll
new file mode 100644
index 0000000000000..a2420be4fac30
--- /dev/null
+++ b/llvm/test/Transforms/PGOProfile/profcheck-exclusions.ll
@@ -0,0 +1,10 @@
+; RUN: opt -passes=prof-inject %s -S -o - | FileCheck %s
+; RUN: opt -passes=prof-verify %s --disable-output
+
+
+define void @bar(i1 %c) #0 {
+ ret void
+}
+
+attributes #0 = { naked }
+; CHECK-NOT: !prof
|
🐧 Linux x64 Test Results
|
| bool isAsmOnly(const Function &F) { | ||
| if (!F.hasFnAttribute(Attribute::AttrKind::Naked)) | ||
| return false; | ||
| for (const auto &BB : F) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would just check for the attribute, it's invalid to have anything other than asm in a naked function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought so too initially, but then (1) read https://llvm.org/docs/LangRef.html which just says
This attribute disables prologue / epilogue emission for the function. This can have very system-specific consequences. The arguments of a naked function can not be referenced through IR values.
...which is more permissive; and (2) couldn't find any check in Verifier.cpp that's more than
if (Attrs.hasFnAttr(Attribute::Naked))
for (const Argument &Arg : F.args())
Check(Arg.use_empty(), "cannot use argument of naked function", &Arg);
Maybe there was a subsequent discussion but no doc/verifier update? (Happy to do those separately)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's just saying that some targets might accept more than asm (which I'm not sure is even true). Even if true, that still doesn't necessarily mean that it's valid to inline.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't sound like the extra checks hurt, and they might catch something weird some day.

We can't do anything meaningful to such functions: they aren't optimizable, and even if inlined, they would bring no code open to optimization.