llvm.org GIT mirror llvm / 570a4a5
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95466 91177308-0d34-0410-b5e6-96231b3b80d8 Jakob Stoklund Olesen 9 years ago
14 changed file(s) with 48 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
9292 | Noredzone
9393 | Noimplicitfloat
9494 | Naked
95 | Inlinehint
9596 end
9697
9798 module Icmp = struct
142142 | Noredzone
143143 | Noimplicitfloat
144144 | Naked
145 | Inlinehint
145146 end
146147
147148 (** The predicate for an integer comparison ([icmp]) instruction.
10821082 function into callers whenever possible, ignoring any active inlining size
10831083 threshold for this caller.
10841084
1085
inlinehint
1086
This attribute indicates that the source code contained a hint that inlining
1087 this function is desirable (such as the "inline" keyword in C/C++). It
1088 is just a hint; it imposes no requirements on the inliner.
1089
10851090
noinline
10861091
This attribute indicates that the inliner should never inline this
10871092 function in any situation. This attribute may not be used together with
5757 const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point
5858 /// instructions.
5959 const Attributes Naked = 1<<24; ///< Naked function
60 const Attributes InlineHint = 1<<25; ///< source said inlining was
61 ///desirable
6062
6163 /// @brief Attributes that only apply to function parameters.
6264 const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
6567 /// be used on return values or function parameters.
6668 const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
6769 NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq |
68 NoRedZone | NoImplicitFloat | Naked;
70 NoRedZone | NoImplicitFloat | Naked | InlineHint;
6971
7072 /// @brief Parameter attributes that do not apply to vararg call arguments.
7173 const Attributes VarArgsIncompatible = StructRet;
5151 unsigned getInlineThreshold() const { return InlineThreshold; }
5252
5353 /// Calculate the inline threshold for given Caller. This threshold is lower
54 /// if Caller is marked with OptimizeForSize and -inline-threshold is not
55 /// given on the comand line.
54 /// if the caller is marked with OptimizeForSize and -inline-threshold is not
55 /// given on the comand line. It is higher if the callee is marked with the
56 /// inlinehint attribute.
5657 ///
57 unsigned getInlineThreshold(Function* Caller) const;
58 unsigned getInlineThreshold(CallSite CS) const;
5859
5960 /// getInlineCost - This method must be implemented by the subclass to
6061 /// determine the cost of inlining the specified call site. If the cost
117117 LLVMNoCaptureAttribute = 1<<21,
118118 LLVMNoRedZoneAttribute = 1<<22,
119119 LLVMNoImplicitFloatAttribute = 1<<23,
120 LLVMNakedAttribute = 1<<24
120 LLVMNakedAttribute = 1<<24,
121 LLVMInlineHintAttribute = 1<<25
121122 } LLVMAttribute;
122123
123124 typedef enum {
557557 KEYWORD(readnone);
558558 KEYWORD(readonly);
559559
560 KEYWORD(inlinehint);
560561 KEYWORD(noinline);
561562 KEYWORD(alwaysinline);
562563 KEYWORD(optsize);
946946 case lltok::kw_noinline: Attrs |= Attribute::NoInline; break;
947947 case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break;
948948 case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break;
949 case lltok::kw_inlinehint: Attrs |= Attribute::InlineHint; break;
949950 case lltok::kw_alwaysinline: Attrs |= Attribute::AlwaysInline; break;
950951 case lltok::kw_optsize: Attrs |= Attribute::OptimizeForSize; break;
951952 case lltok::kw_ssp: Attrs |= Attribute::StackProtect; break;
8484 kw_readnone,
8585 kw_readonly,
8686
87 kw_inlinehint,
8788 kw_noinline,
8889 kw_alwaysinline,
8990 kw_optsize,
469469 HANDLE_ATTR(Nest);
470470 HANDLE_ATTR(ReadNone);
471471 HANDLE_ATTR(ReadOnly);
472 HANDLE_ATTR(InlineHint);
472473 HANDLE_ATTR(NoInline);
473474 HANDLE_ATTR(AlwaysInline);
474475 HANDLE_ATTR(OptimizeForSize);
4040 InlineLimit("inline-threshold", cl::Hidden, cl::init(225), cl::ZeroOrMore,
4141 cl::desc("Control the amount of inlining to perform (default = 225)"));
4242
43 static cl::opt
44 RespectHint("respect-inlinehint", cl::Hidden,
45 cl::desc("Respect the inlinehint attribute"));
46
47 // Threshold to use when inlinehint is given.
48 const int HintThreshold = 300;
49
50 // Threshold to use when optsize is specified (and there is no -inline-limit).
51 const int OptSizeThreshold = 75;
52
4353 Inliner::Inliner(void *ID)
4454 : CallGraphSCCPass(ID), InlineThreshold(InlineLimit) {}
4555
171181 return true;
172182 }
173183
174 unsigned Inliner::getInlineThreshold(Function* Caller) const {
184 unsigned Inliner::getInlineThreshold(CallSite CS) const {
185 // Listen to inlinehint when -respect-inlinehint is given.
186 Function *Callee = CS.getCalledFunction();
187 if (RespectHint && Callee && !Callee->isDeclaration() &&
188 Callee->hasFnAttr(Attribute::InlineHint))
189 return HintThreshold;
190
191 // Listen to optsize when -inline-limit is not given.
192 Function *Caller = CS.getCaller();
175193 if (Caller && !Caller->isDeclaration() &&
176194 Caller->hasFnAttr(Attribute::OptimizeForSize) &&
177195 InlineLimit.getNumOccurrences() == 0)
178 return 75;
179 else
180 return InlineThreshold;
196 return OptSizeThreshold;
197
198 return InlineThreshold;
181199 }
182200
183201 /// shouldInline - Return true if the inliner should attempt to inline
199217
200218 int Cost = IC.getValue();
201219 Function *Caller = CS.getCaller();
202 int CurrentThreshold = getInlineThreshold(Caller);
220 int CurrentThreshold = getInlineThreshold(CS);
203221 float FudgeFactor = getInlineFudgeFactor(CS);
204222 if (Cost >= (int)(CurrentThreshold * FudgeFactor)) {
205223 DEBUG(dbgs() << " NOT Inlining: cost=" << Cost
235253
236254 outerCallsFound = true;
237255 int Cost2 = IC2.getValue();
238 Function *Caller2 = CS2.getCaller();
239 int CurrentThreshold2 = getInlineThreshold(Caller2);
256 int CurrentThreshold2 = getInlineThreshold(CS2);
240257 float FudgeFactor2 = getInlineFudgeFactor(CS2);
241258
242259 if (Cost2 >= (int)(CurrentThreshold2 * FudgeFactor2))
5555 Result += "optsize ";
5656 if (Attrs & Attribute::NoInline)
5757 Result += "noinline ";
58 if (Attrs & Attribute::InlineHint)
59 Result += "inlinehint ";
5860 if (Attrs & Attribute::AlwaysInline)
5961 Result += "alwaysinline ";
6062 if (Attrs & Attribute::StackProtect)
160160 | signext
161161 | readnone
162162 | readonly
163 | inlinehint
163164 | noinline
164165 | alwaysinline
165166 | optsize
5050 syn keyword llvmKeyword x86_stdcallcc x86_fastcallcc
5151 syn keyword llvmKeyword signext zeroext inreg sret nounwind noreturn
5252 syn keyword llvmKeyword nocapture byval nest readnone readonly noalias
53 syn keyword llvmKeyword noinline alwaysinline optsize ssp sspreq
53 syn keyword llvmKeyword inlinehint noinline alwaysinline optsize ssp sspreq
5454 syn keyword llvmKeyword noredzone noimplicitfloat naked
5555 syn keyword llvmKeyword module asm align tail to
5656 syn keyword llvmKeyword addrspace section alias sideeffect c gc