mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
Reintroduce the InlineHint function attribute.
This time it's for real! I am going to hook this up in the frontends as well. The inliner has some experimental heuristics for dealing with the inline hint. When given a -respect-inlinehint option, functions marked with the inline keyword are given a threshold just above the default for -O3. We need some experiments to determine if that is the right thing to do. llvm-svn: 95466
This commit is contained in:
parent
60fb5a2446
commit
83ebc265b3
@ -93,6 +93,7 @@ module Attribute = struct
|
||||
| Noredzone
|
||||
| Noimplicitfloat
|
||||
| Naked
|
||||
| Inlinehint
|
||||
end
|
||||
|
||||
module Icmp = struct
|
||||
|
@ -143,6 +143,7 @@ module Attribute : sig
|
||||
| Noredzone
|
||||
| Noimplicitfloat
|
||||
| Naked
|
||||
| Inlinehint
|
||||
end
|
||||
|
||||
(** The predicate for an integer comparison ([icmp]) instruction.
|
||||
|
@ -1083,6 +1083,11 @@ define void @f() optsize { ... }
|
||||
function into callers whenever possible, ignoring any active inlining size
|
||||
threshold for this caller.</dd>
|
||||
|
||||
<dt><tt><b>inlinehint</b></tt></dt>
|
||||
<dd>This attribute indicates that the source code contained a hint that inlining
|
||||
this function is desirable (such as the "inline" keyword in C/C++). It
|
||||
is just a hint; it imposes no requirements on the inliner.</dd>
|
||||
|
||||
<dt><tt><b>noinline</b></tt></dt>
|
||||
<dd>This attribute indicates that the inliner should never inline this
|
||||
function in any situation. This attribute may not be used together with
|
||||
|
@ -118,7 +118,8 @@ typedef enum {
|
||||
LLVMNoCaptureAttribute = 1<<21,
|
||||
LLVMNoRedZoneAttribute = 1<<22,
|
||||
LLVMNoImplicitFloatAttribute = 1<<23,
|
||||
LLVMNakedAttribute = 1<<24
|
||||
LLVMNakedAttribute = 1<<24,
|
||||
LLVMInlineHintAttribute = 1<<25
|
||||
} LLVMAttribute;
|
||||
|
||||
typedef enum {
|
||||
|
@ -58,6 +58,8 @@ const Attributes NoRedZone = 1<<22; /// disable redzone
|
||||
const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point
|
||||
/// instructions.
|
||||
const Attributes Naked = 1<<24; ///< Naked function
|
||||
const Attributes InlineHint = 1<<25; ///< source said inlining was
|
||||
///desirable
|
||||
|
||||
/// @brief Attributes that only apply to function parameters.
|
||||
const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
|
||||
@ -66,7 +68,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
|
||||
/// be used on return values or function parameters.
|
||||
const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
|
||||
NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq |
|
||||
NoRedZone | NoImplicitFloat | Naked;
|
||||
NoRedZone | NoImplicitFloat | Naked | InlineHint;
|
||||
|
||||
/// @brief Parameter attributes that do not apply to vararg call arguments.
|
||||
const Attributes VarArgsIncompatible = StructRet;
|
||||
|
@ -52,10 +52,11 @@ struct Inliner : public CallGraphSCCPass {
|
||||
unsigned getInlineThreshold() const { return InlineThreshold; }
|
||||
|
||||
/// Calculate the inline threshold for given Caller. This threshold is lower
|
||||
/// if Caller is marked with OptimizeForSize and -inline-threshold is not
|
||||
/// given on the comand line.
|
||||
/// if the caller is marked with OptimizeForSize and -inline-threshold is not
|
||||
/// given on the comand line. It is higher if the callee is marked with the
|
||||
/// inlinehint attribute.
|
||||
///
|
||||
unsigned getInlineThreshold(Function* Caller) const;
|
||||
unsigned getInlineThreshold(CallSite CS) const;
|
||||
|
||||
/// getInlineCost - This method must be implemented by the subclass to
|
||||
/// determine the cost of inlining the specified call site. If the cost
|
||||
|
@ -558,6 +558,7 @@ lltok::Kind LLLexer::LexIdentifier() {
|
||||
KEYWORD(readnone);
|
||||
KEYWORD(readonly);
|
||||
|
||||
KEYWORD(inlinehint);
|
||||
KEYWORD(noinline);
|
||||
KEYWORD(alwaysinline);
|
||||
KEYWORD(optsize);
|
||||
|
@ -947,6 +947,7 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {
|
||||
case lltok::kw_noinline: Attrs |= Attribute::NoInline; break;
|
||||
case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break;
|
||||
case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break;
|
||||
case lltok::kw_inlinehint: Attrs |= Attribute::InlineHint; break;
|
||||
case lltok::kw_alwaysinline: Attrs |= Attribute::AlwaysInline; break;
|
||||
case lltok::kw_optsize: Attrs |= Attribute::OptimizeForSize; break;
|
||||
case lltok::kw_ssp: Attrs |= Attribute::StackProtect; break;
|
||||
|
@ -85,6 +85,7 @@ namespace lltok {
|
||||
kw_readnone,
|
||||
kw_readonly,
|
||||
|
||||
kw_inlinehint,
|
||||
kw_noinline,
|
||||
kw_alwaysinline,
|
||||
kw_optsize,
|
||||
|
@ -470,6 +470,7 @@ namespace {
|
||||
HANDLE_ATTR(Nest);
|
||||
HANDLE_ATTR(ReadNone);
|
||||
HANDLE_ATTR(ReadOnly);
|
||||
HANDLE_ATTR(InlineHint);
|
||||
HANDLE_ATTR(NoInline);
|
||||
HANDLE_ATTR(AlwaysInline);
|
||||
HANDLE_ATTR(OptimizeForSize);
|
||||
|
@ -41,6 +41,16 @@ static cl::opt<int>
|
||||
InlineLimit("inline-threshold", cl::Hidden, cl::init(225), cl::ZeroOrMore,
|
||||
cl::desc("Control the amount of inlining to perform (default = 225)"));
|
||||
|
||||
static cl::opt<bool>
|
||||
RespectHint("respect-inlinehint", cl::Hidden,
|
||||
cl::desc("Respect the inlinehint attribute"));
|
||||
|
||||
// Threshold to use when inlinehint is given.
|
||||
const int HintThreshold = 300;
|
||||
|
||||
// Threshold to use when optsize is specified (and there is no -inline-limit).
|
||||
const int OptSizeThreshold = 75;
|
||||
|
||||
Inliner::Inliner(void *ID)
|
||||
: CallGraphSCCPass(ID), InlineThreshold(InlineLimit) {}
|
||||
|
||||
@ -172,13 +182,21 @@ static bool InlineCallIfPossible(CallSite CS, CallGraph &CG,
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned Inliner::getInlineThreshold(Function* Caller) const {
|
||||
unsigned Inliner::getInlineThreshold(CallSite CS) const {
|
||||
// Listen to inlinehint when -respect-inlinehint is given.
|
||||
Function *Callee = CS.getCalledFunction();
|
||||
if (RespectHint && Callee && !Callee->isDeclaration() &&
|
||||
Callee->hasFnAttr(Attribute::InlineHint))
|
||||
return HintThreshold;
|
||||
|
||||
// Listen to optsize when -inline-limit is not given.
|
||||
Function *Caller = CS.getCaller();
|
||||
if (Caller && !Caller->isDeclaration() &&
|
||||
Caller->hasFnAttr(Attribute::OptimizeForSize) &&
|
||||
InlineLimit.getNumOccurrences() == 0)
|
||||
return 75;
|
||||
else
|
||||
return InlineThreshold;
|
||||
return OptSizeThreshold;
|
||||
|
||||
return InlineThreshold;
|
||||
}
|
||||
|
||||
/// shouldInline - Return true if the inliner should attempt to inline
|
||||
@ -200,7 +218,7 @@ bool Inliner::shouldInline(CallSite CS) {
|
||||
|
||||
int Cost = IC.getValue();
|
||||
Function *Caller = CS.getCaller();
|
||||
int CurrentThreshold = getInlineThreshold(Caller);
|
||||
int CurrentThreshold = getInlineThreshold(CS);
|
||||
float FudgeFactor = getInlineFudgeFactor(CS);
|
||||
if (Cost >= (int)(CurrentThreshold * FudgeFactor)) {
|
||||
DEBUG(dbgs() << " NOT Inlining: cost=" << Cost
|
||||
@ -236,8 +254,7 @@ bool Inliner::shouldInline(CallSite CS) {
|
||||
|
||||
outerCallsFound = true;
|
||||
int Cost2 = IC2.getValue();
|
||||
Function *Caller2 = CS2.getCaller();
|
||||
int CurrentThreshold2 = getInlineThreshold(Caller2);
|
||||
int CurrentThreshold2 = getInlineThreshold(CS2);
|
||||
float FudgeFactor2 = getInlineFudgeFactor(CS2);
|
||||
|
||||
if (Cost2 >= (int)(CurrentThreshold2 * FudgeFactor2))
|
||||
|
@ -56,6 +56,8 @@ std::string Attribute::getAsString(Attributes Attrs) {
|
||||
Result += "optsize ";
|
||||
if (Attrs & Attribute::NoInline)
|
||||
Result += "noinline ";
|
||||
if (Attrs & Attribute::InlineHint)
|
||||
Result += "inlinehint ";
|
||||
if (Attrs & Attribute::AlwaysInline)
|
||||
Result += "alwaysinline ";
|
||||
if (Attrs & Attribute::StackProtect)
|
||||
|
@ -161,6 +161,7 @@ FuncAttr ::= noreturn
|
||||
| signext
|
||||
| readnone
|
||||
| readonly
|
||||
| inlinehint
|
||||
| noinline
|
||||
| alwaysinline
|
||||
| optsize
|
||||
|
@ -51,7 +51,7 @@ syn keyword llvmKeyword volatile fastcc coldcc cc ccc
|
||||
syn keyword llvmKeyword x86_stdcallcc x86_fastcallcc
|
||||
syn keyword llvmKeyword signext zeroext inreg sret nounwind noreturn
|
||||
syn keyword llvmKeyword nocapture byval nest readnone readonly noalias
|
||||
syn keyword llvmKeyword noinline alwaysinline optsize ssp sspreq
|
||||
syn keyword llvmKeyword inlinehint noinline alwaysinline optsize ssp sspreq
|
||||
syn keyword llvmKeyword noredzone noimplicitfloat naked
|
||||
syn keyword llvmKeyword module asm align tail to
|
||||
syn keyword llvmKeyword addrspace section alias sideeffect c gc
|
||||
|
Loading…
Reference in New Issue
Block a user