From c47739b45cad6f075cf4c42420c2c47034ff75d4 Mon Sep 17 00:00:00 2001 From: Momchil Velikov Date: Tue, 25 Oct 2022 18:56:31 +0100 Subject: [PATCH] [FuncSpec] Consider small noinline functions for specialisation Small functions with size under a given threshold are not considered for specialisaion on the presumption that they are easy to inline. This does not apply to `noinline` functions, though. Reviewed By: ChuanqiXu Differential Revision: https://reviews.llvm.org/D135862 --- .../Transforms/IPO/FunctionSpecialization.cpp | 8 ++--- .../FunctionSpecialization/noinline.ll | 35 +++++++++++++++++++ 2 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 llvm/test/Transforms/FunctionSpecialization/noinline.ll diff --git a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp index 9884bdfe18cb..8063378f77b1 100644 --- a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp +++ b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp @@ -552,11 +552,9 @@ private: // inlined so that we shouldn't specialize it. if (Metrics.notDuplicatable || !Metrics.NumInsts.isValid() || (!ForceFunctionSpecialization && - Metrics.NumInsts < SmallFunctionThreshold)) { - InstructionCost C{}; - C.setInvalid(); - return C; - } + !F->hasFnAttribute(Attribute::NoInline) && + Metrics.NumInsts < SmallFunctionThreshold)) + return InstructionCost::getInvalid(); // Otherwise, set the specialization cost to be the cost of all the // instructions in the function and penalty for specializing more functions. diff --git a/llvm/test/Transforms/FunctionSpecialization/noinline.ll b/llvm/test/Transforms/FunctionSpecialization/noinline.ll new file mode 100644 index 000000000000..6c566fcb5738 --- /dev/null +++ b/llvm/test/Transforms/FunctionSpecialization/noinline.ll @@ -0,0 +1,35 @@ +; RUN: opt -S --passes=function-specialization < %s | FileCheck %s +define dso_local i32 @p0(i32 noundef %x) { +entry: + %add = add nsw i32 %x, 1 + ret i32 %add +} + +define dso_local i32 @p1(i32 noundef %x) { +entry: + %sub = add nsw i32 %x, -1 + ret i32 %sub +} + +define internal fastcc i32 @f(i32 noundef %x, ptr nocapture noundef readonly %p) noinline { +entry: + %call = tail call i32 %p(i32 noundef %x) + %add = add nsw i32 %call, %x + ret i32 %add +} + +define dso_local i32 @g0(i32 noundef %x) { +entry: + %call = tail call fastcc i32 @f(i32 noundef %x, ptr noundef nonnull @p0) + ret i32 %call +} + +define dso_local i32 @g1(i32 noundef %x) { +entry: + %call = tail call fastcc i32 @f(i32 noundef %x, ptr noundef nonnull @p1) + ret i32 %call +} + +; Check that a noinline function is specialized, even if it's small. +; CHECK: @f.1 +; CHECK: @f.2