blob: 071727f055f9a8747f186daeebc110addfb799ac [file] [log] [blame]
Jordan Rose25c04002012-08-17 02:11:35 +00001Inlining
2========
3
Ted Kremenek77df8d92012-08-22 01:20:05 +00004 -analyzer-ipa=none - All inlining is disabled. This is the only mode available
5 in LLVM 3.1 and earlier and in Xcode 4.3 and earlier.
6
7 -analyzer-ipa=basic-inlining - Turns on inlining for C functions, C++ static
8 member functions, and blocks -- essentially, the calls that behave like
9 simple C function calls. This is essentially the mode used in Xcode 4.4.
10
11 -analyzer-ipa=inlining - Turns on inlining when we can confidently find the
12 function/method body corresponding to the call. (C functions, static
13 functions, devirtualized C++ methods, Objective-C class methods, Objective-C
14 instance methods when ExprEngine is confident about the dynamic type of the
15 instance).
16
17 -analyzer-ipa=dynamic - Inline instance methods for which the type is
18 determined at runtime and we are not 100% sure that our type info is
19 correct. For virtual calls, inline the most plausible definition.
20
21 -analyzer-ipa=dynamic-bifurcate - Same as -analyzer-ipa=dynamic, but the path
22 is split. We inline on one branch and do not inline on the other. This mode
23 does not drop the coverage in cases when the parent class has code that is
Jordan Rosef01ef1052012-08-22 17:13:27 +000024 only exercised when some of its methods are overridden.
Jordan Rose25c04002012-08-17 02:11:35 +000025
Jordan Rosec568e2f2012-08-21 21:44:21 +000026Currently, -analyzer-ipa=basic-inlining is the default mode.
Jordan Rose25c04002012-08-17 02:11:35 +000027
28Basics of Implementation
29-----------------------
30
Ted Kremenek77df8d92012-08-22 01:20:05 +000031The low-level mechanism of inlining a function is handled in
32ExprEngine::inlineCall and ExprEngine::processCallExit.
Jordan Rose25c04002012-08-17 02:11:35 +000033
Ted Kremenek77df8d92012-08-22 01:20:05 +000034If the conditions are right for inlining, a CallEnter node is created and added
35to the analysis work list. The CallEnter node marks the change to a new
36LocationContext representing the called function, and its state includes the
37contents of the new stack frame. When the CallEnter node is actually processed,
38its single successor will be a edge to the first CFG block in the function.
39
40Exiting an inlined function is a bit more work, fortunately broken up into
41reasonable steps:
42
431. The CoreEngine realizes we're at the end of an inlined call and generates a
44 CallExitBegin node.
45
462. ExprEngine takes over (in processCallExit) and finds the return value of the
47 function, if it has one. This is bound to the expression that triggered the
48 call. (In the case of calls without origin expressions, such as destructors,
49 this step is skipped.)
50
513. Dead symbols and bindings are cleaned out from the state, including any local
52 bindings.
53
544. A CallExitEnd node is generated, which marks the transition back to the
55 caller's LocationContext.
56
575. Custom post-call checks are processed and the final nodes are pushed back
58 onto the work list, so that evaluation of the caller can continue.
Jordan Rose25c04002012-08-17 02:11:35 +000059
60Retry Without Inlining
Ted Kremenek77df8d92012-08-22 01:20:05 +000061----------------------
62
Jordan Rosef01ef1052012-08-22 17:13:27 +000063In some cases, we would like to retry analysis without inlining a particular
Ted Kremenek77df8d92012-08-22 01:20:05 +000064call.
65
Jordan Rosef01ef1052012-08-22 17:13:27 +000066Currently, we use this technique to recover coverage in case we stop
Ted Kremenek77df8d92012-08-22 01:20:05 +000067analyzing a path due to exceeding the maximum block count inside an inlined
68function.
69
70When this situation is detected, we walk up the path to find the first node
71before inlining was started and enqueue it on the WorkList with a special
72ReplayWithoutInlining bit added to it (ExprEngine::replayWithoutInlining). The
73path is then re-analyzed from that point without inlining that particular call.
74
75Deciding When to Inline
Jordan Rose25c04002012-08-17 02:11:35 +000076-----------------------
77
Ted Kremenek77df8d92012-08-22 01:20:05 +000078In general, the analyzer attempts to inline as much as possible, since it
79provides a better summary of what actually happens in the program. There are
80some cases, however, where the analyzer chooses not to inline:
Jordan Rose25c04002012-08-17 02:11:35 +000081
Ted Kremenek77df8d92012-08-22 01:20:05 +000082- If there is no definition available for the called function or method. In
83 this case, there is no opportunity to inline.
84
Jordan Rosef01ef1052012-08-22 17:13:27 +000085- If the CFG cannot be constructed for a called function, or the liveness
Ted Kremenek77df8d92012-08-22 01:20:05 +000086 cannot be computed. These are prerequisites for analyzing a function body,
87 with or without inlining.
88
89- If the LocationContext chain for a given ExplodedNode reaches a maximum cutoff
90 depth. This prevents unbounded analysis due to infinite recursion, but also
91 serves as a useful cutoff for performance reasons.
92
93- If the function is variadic. This is not a hard limitation, but an engineering
94 limitation.
95
96 Tracked by: <rdar://problem/12147064> Support inlining of variadic functions
97
Jordan Rosef01ef1052012-08-22 17:13:27 +000098- In C++, constructors are not inlined unless the destructor call will be
99 processed by the ExprEngine. Thus, if the CFG was built without nodes for
100 implicit destructors, or if the destructors for the given object are not
Jordan Rose7103d2d2012-08-27 18:39:16 +0000101 represented in the CFG, the constructor will not be inlined. (As an exception,
102 constructors for objects with trivial constructors can still be inlined.)
Jordan Rosef01ef1052012-08-22 17:13:27 +0000103 See "C++ Caveats" below.
Ted Kremenek77df8d92012-08-22 01:20:05 +0000104
Jordan Rose7103d2d2012-08-27 18:39:16 +0000105- In C++, ExprEngine does not inline custom implementations of operator 'new'
Jordan Rose6fe4dfb2012-08-27 18:39:22 +0000106 or operator 'delete', nor does it inline the constructors and destructors
107 associated with these. See "C++ Caveats" below.
Jordan Rose7103d2d2012-08-27 18:39:16 +0000108
Ted Kremenek77df8d92012-08-22 01:20:05 +0000109- Calls resulting in "dynamic dispatch" are specially handled. See more below.
110
Jordan Rosef01ef1052012-08-22 17:13:27 +0000111- The FunctionSummaries map stores additional information about declarations,
112 some of which is collected at runtime based on previous analyses.
113 We do not inline functions which were not profitable to inline in a different
114 context (for example, if the maximum block count was exceeded; see
115 "Retry Without Inlining").
Jordan Rose25c04002012-08-17 02:11:35 +0000116
117
Ted Kremenek77df8d92012-08-22 01:20:05 +0000118Dynamic Calls and Devirtualization
Jordan Rose25c04002012-08-17 02:11:35 +0000119----------------------------------
Jordan Rose25c04002012-08-17 02:11:35 +0000120
Ted Kremenek77df8d92012-08-22 01:20:05 +0000121"Dynamic" calls are those that are resolved at runtime, such as C++ virtual
122method calls and Objective-C message sends. Due to the path-sensitive nature of
Jordan Rosef01ef1052012-08-22 17:13:27 +0000123the analysis, the analyzer may be able to reason about the dynamic type of the
Ted Kremenek77df8d92012-08-22 01:20:05 +0000124object whose method is being called and thus "devirtualize" the call.
Jordan Rose25c04002012-08-17 02:11:35 +0000125
Ted Kremenek77df8d92012-08-22 01:20:05 +0000126This path-sensitive devirtualization occurs when the analyzer can determine what
127method would actually be called at runtime. This is possible when the type
Jordan Rosef01ef1052012-08-22 17:13:27 +0000128information is constrained enough for a simulated C++/Objective-C object that
129the analyzer can make such a decision.
Jordan Rose25c04002012-08-17 02:11:35 +0000130
Ted Kremenek77df8d92012-08-22 01:20:05 +0000131 == DynamicTypeInfo ==
Jordan Rose25c04002012-08-17 02:11:35 +0000132
Jordan Rosef01ef1052012-08-22 17:13:27 +0000133As the analyzer analyzes a path, it may accrue information to refine the
134knowledge about the type of an object. This can then be used to make better
135decisions about the target method of a call.
Jordan Rose25c04002012-08-17 02:11:35 +0000136
Ted Kremenek77df8d92012-08-22 01:20:05 +0000137Such type information is tracked as DynamicTypeInfo. This is path-sensitive
138data that is stored in ProgramState, which defines a mapping from MemRegions to
139an (optional) DynamicTypeInfo.
140
141If no DynamicTypeInfo has been explicitly set for a MemRegion, it will be lazily
142inferred from the region's type or associated symbol. Information from symbolic
143regions is weaker than from true typed regions.
144
145 EXAMPLE: A C++ object declared "A obj" is known to have the class 'A', but a
146 reference "A &ref" may dynamically be a subclass of 'A'.
147
148The DynamicTypePropagation checker gathers and propagates DynamicTypeInfo,
149updating it as information is observed along a path that can refine that type
150information for a region.
151
152 WARNING: Not all of the existing analyzer code has been retrofitted to use
153 DynamicTypeInfo, nor is it universally appropriate. In particular,
154 DynamicTypeInfo always applies to a region with all casts stripped
Jordan Rosef01ef1052012-08-22 17:13:27 +0000155 off, but sometimes the information provided by casts can be useful.
Ted Kremenek77df8d92012-08-22 01:20:05 +0000156
157
Jordan Rosef01ef1052012-08-22 17:13:27 +0000158 == RuntimeDefinition ==
Ted Kremenek77df8d92012-08-22 01:20:05 +0000159
Jordan Rosef01ef1052012-08-22 17:13:27 +0000160The basis of devirtualization is CallEvent's getRuntimeDefinition() method,
161which returns a RuntimeDefinition object. When asked to provide a definition,
162the CallEvents for dynamic calls will use the DynamicTypeInfo in their
163ProgramState to attempt to devirtualize the call. In the case of no dynamic
164dispatch, or perfectly constrained devirtualization, the resulting
165RuntimeDefinition contains a Decl corresponding to the definition of the called
166function, and RuntimeDefinition::mayHaveOtherDefinitions will return FALSE.
Ted Kremenek77df8d92012-08-22 01:20:05 +0000167
Jordan Rosef01ef1052012-08-22 17:13:27 +0000168In the case of dynamic dispatch where our information is not perfect, CallEvent
169can make a guess, but RuntimeDefinition::mayHaveOtherDefinitions will return
170TRUE. The RuntimeDefinition object will then also include a MemRegion
171corresponding to the object being called (i.e., the "receiver" in Objective-C
172parlance), which ExprEngine uses to decide whether or not the call should be
173inlined.
174
175 == Inlining Dynamic Calls ==
176
177The -analyzer-ipa option has five different modes: none, basic-inlining,
178inlining, dynamic, and dynamic-bifurcate. Under -analyzer-ipa=dynamic, all
179dynamic calls are inlined, whether we are certain or not that this will actually
180be the definition used at runtime. Under -analyzer-ipa=inlining, only
181"near-perfect" devirtualized calls are inlined*, and other dynamic calls are
182evaluated conservatively (as if no definition were available).
Ted Kremenek77df8d92012-08-22 01:20:05 +0000183
184* Currently, no Objective-C messages are not inlined under
185 -analyzer-ipa=inlining, even if we are reasonably confident of the type of the
186 receiver. We plan to enable this once we have tested our heuristics more
187 thoroughly.
188
189The last option, -analyzer-ipa=dynamic-bifurcate, behaves similarly to
190"dynamic", but performs a conservative invalidation in the general virtual case
191in *addition* to inlining. The details of this are discussed below.
Jordan Rose25c04002012-08-17 02:11:35 +0000192
Jordan Rosef01ef1052012-08-22 17:13:27 +0000193As stated above, -analyzer-ipa=basic-inlining does not inline any C++ member
194functions or Objective-C method calls, even if they are non-virtual or can be
195safely devirtualized.
196
197
Jordan Rose25c04002012-08-17 02:11:35 +0000198Bifurcation
199-----------
Jordan Rose25c04002012-08-17 02:11:35 +0000200
Ted Kremenek77df8d92012-08-22 01:20:05 +0000201ExprEngine::BifurcateCall implements the -analyzer-ipa=dynamic-bifurcate
202mode.
Jordan Rose25c04002012-08-17 02:11:35 +0000203
Jordan Rosef01ef1052012-08-22 17:13:27 +0000204When a call is made on an object with imprecise dynamic type information
Anna Zaks2eed8cc2012-08-22 05:38:38 +0000205(RuntimeDefinition::mayHaveOtherDefinitions() evaluates to TRUE), ExprEngine
Jordan Rosef01ef1052012-08-22 17:13:27 +0000206bifurcates the path and marks the object's region (retrieved from the
207RuntimeDefinition object) with a path-sensitive "mode" in the ProgramState.
Ted Kremenek77df8d92012-08-22 01:20:05 +0000208
209Currently, there are 2 modes:
210
211 DynamicDispatchModeInlined - Models the case where the dynamic type information
Anna Zaks2eed8cc2012-08-22 05:38:38 +0000212 of the receiver (MemoryRegion) is assumed to be perfectly constrained so
213 that a given definition of a method is expected to be the code actually
214 called. When this mode is set, ExprEngine uses the Decl from
215 RuntimeDefinition to inline any dynamically dispatched call sent to this
216 receiver because the function definition is considered to be fully resolved.
Ted Kremenek77df8d92012-08-22 01:20:05 +0000217
218 DynamicDispatchModeConservative - Models the case where the dynamic type
Anna Zaks2eed8cc2012-08-22 05:38:38 +0000219 information is assumed to be incorrect, for example, implies that the method
220 definition is overriden in a subclass. In such cases, ExprEngine does not
221 inline the methods sent to the receiver (MemoryRegion), even if a candidate
222 definition is available. This mode is conservative about simulating the
223 effects of a call.
Ted Kremenek77df8d92012-08-22 01:20:05 +0000224
Anna Zaks2eed8cc2012-08-22 05:38:38 +0000225Going forward along the symbolic execution path, ExprEngine consults the mode
226of the receiver's MemRegion to make decisions on whether the calls should be
227inlined or not, which ensures that there is at most one split per region.
Ted Kremenek77df8d92012-08-22 01:20:05 +0000228
229At a high level, "bifurcation mode" allows for increased semantic coverage in
230cases where the parent method contains code which is only executed when the
231class is subclassed. The disadvantages of this mode are a (considerable?)
232performance hit and the possibility of false positives on the path where the
233conservative mode is used.
Jordan Rose25c04002012-08-17 02:11:35 +0000234
235Objective-C Message Heuristics
236------------------------------
Jordan Rose25c04002012-08-17 02:11:35 +0000237
Anna Zaks2eed8cc2012-08-22 05:38:38 +0000238ExprEngine relies on a set of heuristics to partition the set of Objective-C
239method calls into those that require bifurcation and those that do not. Below
240are the cases when the DynamicTypeInfo of the object is considered precise
Ted Kremenek77df8d92012-08-22 01:20:05 +0000241(cannot be a subclass):
242
243 - If the object was created with +alloc or +new and initialized with an -init
244 method.
245
246 - If the calls are property accesses using dot syntax. This is based on the
247 assumption that children rarely override properties, or do so in an
248 essentially compatible way.
249
250 - If the class interface is declared inside the main source file. In this case
251 it is unlikely that it will be subclassed.
252
253 - If the method is not declared outside of main source file, either by the
254 receiver's class or by any superclasses.
Jordan Rose25c04002012-08-17 02:11:35 +0000255
Jordan Rosef01ef1052012-08-22 17:13:27 +0000256C++ Caveats
Jordan Rose25c04002012-08-17 02:11:35 +0000257--------------------
Jordan Rose25c04002012-08-17 02:11:35 +0000258
Ted Kremenek77df8d92012-08-22 01:20:05 +0000259C++11 [class.cdtor]p4 describes how the vtable of an object is modified as it is
260being constructed or destructed; that is, the type of the object depends on
261which base constructors have been completed. This is tracked using
262DynamicTypeInfo in the DynamicTypePropagation checker.
Jordan Rose25c04002012-08-17 02:11:35 +0000263
Ted Kremenek77df8d92012-08-22 01:20:05 +0000264There are several limitations in the current implementation:
Jordan Rose25c04002012-08-17 02:11:35 +0000265
Jordan Rosef01ef1052012-08-22 17:13:27 +0000266- Temporaries are poorly modeled right now because we're not confident in the
267 placement of their destructors in the CFG. We currently won't inline their
Jordan Rose7103d2d2012-08-27 18:39:16 +0000268 constructors unless the destructor is trivial, and don't process their
269 destructors at all, not even to invalidate the region.
Jordan Rose25c04002012-08-17 02:11:35 +0000270
Jordan Rosef01ef1052012-08-22 17:13:27 +0000271- 'new' is poorly modeled due to some nasty CFG/design issues. This is tracked
272 in PR12014. 'delete' is not modeled at all.
Ted Kremenek77df8d92012-08-22 01:20:05 +0000273
274- Arrays of objects are modeled very poorly right now. ExprEngine currently
Jordan Rosef01ef1052012-08-22 17:13:27 +0000275 only simulates the first constructor and first destructor. Because of this,
Ted Kremenek77df8d92012-08-22 01:20:05 +0000276 ExprEngine does not inline any constructors or destructors for arrays.
Jordan Rose25c04002012-08-17 02:11:35 +0000277
Jordan Rosef01ef1052012-08-22 17:13:27 +0000278
Jordan Rose25c04002012-08-17 02:11:35 +0000279CallEvent
Jordan Rosef01ef1052012-08-22 17:13:27 +0000280=========
Jordan Rose25c04002012-08-17 02:11:35 +0000281
Ted Kremenek77df8d92012-08-22 01:20:05 +0000282A CallEvent represents a specific call to a function, method, or other body of
283code. It is path-sensitive, containing both the current state (ProgramStateRef)
284and stack space (LocationContext), and provides uniform access to the argument
285values and return type of a call, no matter how the call is written in the
286source or what sort of code body is being invoked.
Jordan Rose25c04002012-08-17 02:11:35 +0000287
Ted Kremenek77df8d92012-08-22 01:20:05 +0000288 NOTE: For those familiar with Cocoa, CallEvent is roughly equivalent to
289 NSInvocation.
Jordan Rose25c04002012-08-17 02:11:35 +0000290
Ted Kremenek77df8d92012-08-22 01:20:05 +0000291CallEvent should be used whenever there is logic dealing with function calls
292that does not care how the call occurred.
Jordan Rose25c04002012-08-17 02:11:35 +0000293
Ted Kremenek77df8d92012-08-22 01:20:05 +0000294Examples include checking that arguments satisfy preconditions (such as
295__attribute__((nonnull))), and attempting to inline a call.
296
297CallEvents are reference-counted objects managed by a CallEventManager. While
298there is no inherent issue with persisting them (say, in a ProgramState's GDM),
299they are intended for short-lived use, and can be recreated from CFGElements or
Jordan Rosef01ef1052012-08-22 17:13:27 +0000300non-top-level StackFrameContexts fairly easily.