//===- InlineFunction.cpp - Code to perform function inlining -------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements inlining of a function into a call site, resolving
// parameters and the return value as appropriate.
//
// The code in this file for handling inlines through invoke
// instructions preserves semantics only under some assumptions about
// the behavior of unwinders which correspond to gcc-style libUnwind
// exception personality functions. Eventually the IR will be
// improved to make this unnecessary, but until then, this code is
// marked [LIBUNWIND].
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Intrinsics.h"
#include "llvm/Attributes.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/IRBuilder.h"
using namespace llvm;
bool llvm::InlineFunction(CallInst *CI, InlineFunctionInfo &IFI) {
return InlineFunction(CallSite(CI), IFI);
}
bool llvm::InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI) {
return InlineFunction(CallSite(II), IFI);
}
/// [LIBUNWIND] Find the (possibly absent) call to @llvm.eh.selector in
/// the given landing pad.
static EHSelectorInst *findSelectorForLandingPad(BasicBlock *lpad) {
// The llvm.eh.exception call is required to be in the landing pad.
for (BasicBlock::iterator i = lpad->begin(), e = lpad->end(); i != e; i++) {
EHExceptionInst *exn = dyn_cast<EHExceptionInst>(i);
if (!exn) continue;
EHSelectorInst *selector = 0;
for (Instruction::use_iterator
ui = exn->use_begin(), ue = exn->use_end(); ui != ue; ++ui) {
EHSelectorInst *sel = dyn_cast<EHSelectorInst>(*ui);
if (!sel) continue;
// Immediately accept an eh.selector in the landing pad.
if (sel->getParent() == lpad) return sel;
// Otherwise, use the first selector we see.
if (!selector) selector = sel;
}
return selector;
}
return 0;
}
namespace {
/// A class for recording information about inlining through an invoke.
class InvokeInliningInfo {
BasicBlock *OuterUnwindDest;
EHSelectorInst *OuterSelector;
BasicBlock *InnerUnwindDest;
PHINode *InnerExceptionPHI;
PHINode *InnerSelectorPHI;
SmallVector<Value*, 8> UnwindDestPHIValues;
public:
InvokeInliningInfo(InvokeInst *II) :
OuterUnwindDest(II->getUnwindDest()), OuterSelector(0),
InnerUnwindDest(0), InnerExceptionPHI(0), InnerSelectorPHI(0) {
// If there are PHI nodes in the unwind destination block, we
// need to keep track of which values came into them from the
// invoke before removing the edge from this block.
llvm::BasicBlock *invokeBB = II->getParent();
for (BasicBlock::iterator I = OuterUnwindDest->begin();
isa<PHINode>(I); ++I) {
// Save the value to use for this edge.
PHINode *phi = cast<PHINode>(I);
UnwindDestPHIValues.push_back(phi->getIncomingValueForBlock(invokeBB));
}
}
/// The outer unwind destination is the target of unwind edges
/// introduced for calls within the inlined function.
BasicBlock *getOuterUnwindDest() const {
return OuterUnwindDest;
}
EHSelectorInst *getOuterSelector() {
if (!OuterSelector)
OuterSelector = findSelectorForLandingPad(OuterUnwindDest);
return OuterSelector;
}
BasicBlock *getInnerUnwindDest();
bool forwardEHResume(CallInst *call, BasicBlock *src);
/// Add incoming-PHI values to the unwind destination block for
/// the given basic block, using the values for the original
/// invoke's source block.
void addIncomingPHIValuesFor(BasicBlock *BB) const {
addIncomingPHIValuesForInto(BB, OuterUnwindDest);
}
void addIncomingPHIValuesForInto(BasicBlock *src, BasicBlock *dest) const {
BasicBlock::iterator I = dest->begin();
for (unsigned i = 0, e = UnwindDestPHIValues.size(); i