#define DEBUG_TYPE "inline"
#include "llvm/Transforms/IPO.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/InlineCost.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Transforms/IPO/InlinerPass.h"
using namespace llvm;
namespace {
class AlwaysInliner : public Inliner {
InlineCostAnalysis *ICA;
public:
AlwaysInliner() : Inliner(ID, -2000000000, true), ICA(0) {
initializeAlwaysInlinerPass(*PassRegistry::getPassRegistry());
}
AlwaysInliner(bool InsertLifetime)
: Inliner(ID, -2000000000, InsertLifetime), ICA(0) {
initializeAlwaysInlinerPass(*PassRegistry::getPassRegistry());
}
static char ID;
virtual InlineCost getInlineCost(CallSite CS);
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual bool runOnSCC(CallGraphSCC &SCC);
using llvm::Pass::doFinalization;
virtual bool doFinalization(CallGraph &CG) {
return removeDeadFunctions(CG, true);
}
};
}
char AlwaysInliner::ID = 0;
INITIALIZE_PASS_BEGIN(AlwaysInliner, "always-inline",
"Inliner for always_inline functions", false, false)
INITIALIZE_AG_DEPENDENCY(CallGraph)
INITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis)
INITIALIZE_PASS_END(AlwaysInliner, "always-inline",
"Inliner for always_inline functions", false, false)
Pass *llvm::createAlwaysInlinerPass() { return new AlwaysInliner(); }
Pass *llvm::createAlwaysInlinerPass(bool InsertLifetime) {
return new AlwaysInliner(InsertLifetime);
}
InlineCost AlwaysInliner::getInlineCost(CallSite CS) {
Function *Callee = CS.getCalledFunction();
if (Callee && !Callee->isDeclaration() &&
Callee->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
Attribute::AlwaysInline) &&
ICA->isInlineViable(*Callee))
return InlineCost::getAlways();
return InlineCost::getNever();
}
bool AlwaysInliner::runOnSCC(CallGraphSCC &SCC) {
ICA = &getAnalysis<InlineCostAnalysis>();
return Inliner::runOnSCC(SCC);
}
void AlwaysInliner::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<InlineCostAnalysis>();
Inliner::getAnalysisUsage(AU);
}