2007-06-19 22:29:02 +00:00
|
|
|
//===- InlinerPass.h - Code common to all inliners --------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-29 19:59:42 +00:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2007-06-19 22:29:02 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file defines a simple policy-based bottom-up inliner. This file
|
|
|
|
// implements all of the boring mechanics of the bottom-up inlining, while the
|
|
|
|
// subclass determines WHAT to inline, which is the much more interesting
|
|
|
|
// component.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2009-08-27 04:32:07 +00:00
|
|
|
#ifndef LLVM_TRANSFORMS_IPO_INLINERPASS_H
|
|
|
|
#define LLVM_TRANSFORMS_IPO_INLINERPASS_H
|
2007-06-19 22:29:02 +00:00
|
|
|
|
2013-01-07 15:26:48 +00:00
|
|
|
#include "llvm/Analysis/CallGraphSCCPass.h"
|
2007-06-19 22:29:02 +00:00
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
class CallSite;
|
2012-10-08 16:38:25 +00:00
|
|
|
class DataLayout;
|
2009-08-27 04:32:07 +00:00
|
|
|
class InlineCost;
|
|
|
|
template<class PtrType, unsigned SmallSize>
|
|
|
|
class SmallPtrSet;
|
2007-06-19 22:29:02 +00:00
|
|
|
|
|
|
|
/// Inliner - This class contains all of the helper code which is used to
|
2008-10-29 01:02:02 +00:00
|
|
|
/// perform the inlining operations that do not depend on the policy.
|
2007-06-19 22:29:02 +00:00
|
|
|
///
|
|
|
|
struct Inliner : public CallGraphSCCPass {
|
2010-08-06 18:33:48 +00:00
|
|
|
explicit Inliner(char &ID);
|
2012-02-25 02:56:01 +00:00
|
|
|
explicit Inliner(char &ID, int Threshold, bool InsertLifetime);
|
2007-06-19 22:29:02 +00:00
|
|
|
|
|
|
|
/// getAnalysisUsage - For this class, we declare that we require and preserve
|
|
|
|
/// the call graph. If the derived class implements this method, it should
|
|
|
|
/// always explicitly call the implementation here.
|
2014-03-05 09:10:37 +00:00
|
|
|
void getAnalysisUsage(AnalysisUsage &Info) const override;
|
2007-06-19 22:29:02 +00:00
|
|
|
|
|
|
|
// Main run interface method, this implements the interface required by the
|
|
|
|
// Pass class.
|
2014-03-05 09:10:37 +00:00
|
|
|
bool runOnSCC(CallGraphSCC &SCC) override;
|
2007-06-19 22:29:02 +00:00
|
|
|
|
2012-12-04 05:41:27 +00:00
|
|
|
using llvm::Pass::doFinalization;
|
2007-06-19 22:29:02 +00:00
|
|
|
// doFinalization - Remove now-dead linkonce functions at the end of
|
|
|
|
// processing to avoid breaking the SCC traversal.
|
2014-03-05 09:10:37 +00:00
|
|
|
bool doFinalization(CallGraph &CG) override;
|
2007-06-19 22:29:02 +00:00
|
|
|
|
|
|
|
/// This method returns the value specified by the -inline-threshold value,
|
|
|
|
/// specified on the command line. This is typically not directly needed.
|
|
|
|
///
|
|
|
|
unsigned getInlineThreshold() const { return InlineThreshold; }
|
|
|
|
|
2010-01-20 17:51:28 +00:00
|
|
|
/// Calculate the inline threshold for given Caller. This threshold is lower
|
2010-02-06 01:16:28 +00:00
|
|
|
/// 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.
|
2010-01-20 17:51:28 +00:00
|
|
|
///
|
2010-02-06 01:16:28 +00:00
|
|
|
unsigned getInlineThreshold(CallSite CS) const;
|
2010-01-20 17:51:28 +00:00
|
|
|
|
2007-06-19 22:29:02 +00:00
|
|
|
/// getInlineCost - This method must be implemented by the subclass to
|
|
|
|
/// determine the cost of inlining the specified call site. If the cost
|
|
|
|
/// returned is greater than the current inline threshold, the call site is
|
|
|
|
/// not inlined.
|
|
|
|
///
|
2008-10-30 19:26:59 +00:00
|
|
|
virtual InlineCost getInlineCost(CallSite CS) = 0;
|
2007-06-19 22:29:02 +00:00
|
|
|
|
Start removing the use of an ad-hoc 'never inline' set and instead
directly query the function information which this set was representing.
This simplifies the interface of the inline cost analysis, and makes the
always-inline pass significantly more efficient.
Previously, always-inline would first make a single set of every
function in the module *except* those marked with the always-inline
attribute. It would then query this set at every call site to see if the
function was a member of the set, and if so, refuse to inline it. This
is quite wasteful. Instead, simply check the function attribute directly
when looking at the callsite.
The normal inliner also had similar redundancy. It added every function
in the module with the noinline attribute to its set to ignore, even
though inside the cost analysis function we *already tested* the
noinline attribute and produced the same result.
The only tricky part of removing this is that we have to be able to
correctly remove only the functions inlined by the always-inline pass
when finalizing, which requires a bit of a hack. Still, much less of
a hack than the set of all non-always-inline functions was. While I was
touching this function, I switched a heavy-weight set to a vector with
sort+unique. The algorithm already had a two-phase insert and removal
pattern, we were just needlessly paying the uniquing cost on every
insert.
This probably speeds up some compiles by a small amount (-O0 compiles
with lots of always-inline, so potentially heavy libc++ users), but I've
not tried to measure it.
I believe there is no functional change here, but yell if you spot one.
None are intended.
Finally, the direction this is going in is to greatly simplify the
inline cost query interface so that we can replace its implementation
with a much more clever one. Along the way, all the APIs get simplified,
so it seems incrementally good.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152903 91177308-0d34-0410-b5e6-96231b3b80d8
2012-03-16 06:10:13 +00:00
|
|
|
/// removeDeadFunctions - Remove dead functions.
|
|
|
|
///
|
|
|
|
/// This also includes a hack in the form of the 'AlwaysInlineOnly' flag
|
|
|
|
/// which restricts it to deleting functions with an 'AlwaysInline'
|
|
|
|
/// attribute. This is useful for the InlineAlways pass that only wants to
|
|
|
|
/// deal with that subset of the functions.
|
|
|
|
bool removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly = false);
|
|
|
|
|
2007-06-19 22:29:02 +00:00
|
|
|
private:
|
|
|
|
// InlineThreshold - Cache the value here for easy access.
|
|
|
|
unsigned InlineThreshold;
|
2008-10-29 01:02:02 +00:00
|
|
|
|
2012-02-25 02:56:01 +00:00
|
|
|
// InsertLifetime - Insert @llvm.lifetime intrinsics.
|
|
|
|
bool InsertLifetime;
|
|
|
|
|
2008-10-29 01:02:02 +00:00
|
|
|
/// shouldInline - Return true if the inliner should attempt to
|
|
|
|
/// inline at the given CallSite.
|
|
|
|
bool shouldInline(CallSite CS);
|
2007-06-19 22:29:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // End llvm namespace
|
|
|
|
|
|
|
|
#endif
|