#include "llvm/Support/CallSite.h"
using namespace llvm;
-bool llvm::InlineFunction(CallInst *CI, CallGraph *CG, const TargetData *TD) {
- return InlineFunction(CallSite(CI), CG, TD);
+bool llvm::InlineFunction(CallInst *CI, CallGraph *CG, const TargetData *TD,
+ SmallVectorImpl<AllocaInst*> *StaticAllocas) {
+ return InlineFunction(CallSite(CI), CG, TD, StaticAllocas);
}
-bool llvm::InlineFunction(InvokeInst *II, CallGraph *CG, const TargetData *TD) {
- return InlineFunction(CallSite(II), CG, TD);
+bool llvm::InlineFunction(InvokeInst *II, CallGraph *CG, const TargetData *TD,
+ SmallVectorImpl<AllocaInst*> *StaticAllocas) {
+ return InlineFunction(CallSite(II), CG, TD, StaticAllocas);
}
/// HandleCallsInBlockInlinedThroughInvoke - When we inline a basic block into
-/// an invoke, we have to check all of all of the calls that can throw into
+/// an invoke, we have to turn all of the calls that can throw into
/// invokes. This function analyze BB to see if there are any calls, and if so,
/// it rewrites them to be invokes that jump to InvokeDest and fills in the PHI
-/// nodes in that block with the values specified in InvokeDestPHIValues. If
-/// CallerCGN is specified, this function updates the call graph.
+/// nodes in that block with the values specified in InvokeDestPHIValues.
///
static void HandleCallsInBlockInlinedThroughInvoke(BasicBlock *BB,
BasicBlock *InvokeDest,
- const SmallVectorImpl<Value*> &InvokeDestPHIValues,
- CallGraphNode *CallerCGN) {
+ const SmallVectorImpl<Value*> &InvokeDestPHIValues) {
for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ) {
Instruction *I = BBI++;
II->setCallingConv(CI->getCallingConv());
II->setAttributes(CI->getAttributes());
- // Make sure that anything using the call now uses the invoke!
+ // Make sure that anything using the call now uses the invoke! This also
+ // updates the CallGraph if present.
CI->replaceAllUsesWith(II);
- // Update the callgraph if present.
- if (CallerCGN) {
- // We should be able to do this:
- // (*CG)[Caller]->replaceCallSite(CI, II);
- // but that fails if the old call site isn't in the call graph,
- // which, because of LLVM bug 3601, it sometimes isn't.
- for (CallGraphNode::iterator NI = CallerCGN->begin(), NE = CallerCGN->end();
- NI != NE; ++NI) {
- if (NI->first == CI) {
- NI->first = II;
- break;
- }
- }
- }
-
// Delete the unconditional branch inserted by splitBasicBlock
BB->getInstList().pop_back();
Split->getInstList().pop_front(); // Delete the original call
/// block of the inlined code (the last block is the end of the function),
/// and InlineCodeInfo is information about the code that got inlined.
static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
- ClonedCodeInfo &InlinedCodeInfo,
- CallGraph *CG) {
+ ClonedCodeInfo &InlinedCodeInfo) {
BasicBlock *InvokeDest = II->getUnwindDest();
SmallVector<Value*, 8> InvokeDestPHIValues;
return;
}
- CallGraphNode *CallerCGN = 0;
- if (CG) CallerCGN = (*CG)[Caller];
-
for (Function::iterator BB = FirstNewBlock, E = Caller->end(); BB != E; ++BB){
if (InlinedCodeInfo.ContainsCalls)
HandleCallsInBlockInlinedThroughInvoke(BB, InvokeDest,
- InvokeDestPHIValues, CallerCGN);
+ InvokeDestPHIValues);
if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator())) {
// An UnwindInst requires special handling when it gets inlined into an
}
for (; I != E; ++I) {
- const Instruction *OrigCall = I->first.getInstruction();
+ const Value *OrigCall = I->first;
DenseMap<const Value*, Value*>::iterator VMI = ValueMap.find(OrigCall);
// Only copy the edge if the call was inlined!
///
static const DbgRegionEndInst *findFnRegionEndMarker(const Function *F) {
- GlobalVariable *FnStart = NULL;
+ MDNode *FnStart = NULL;
const DbgRegionEndInst *FnEnd = NULL;
for (Function::const_iterator FI = F->begin(), FE =F->end(); FI != FE; ++FI)
for (BasicBlock::const_iterator BI = FI->begin(), BE = FI->end(); BI != BE;
++BI) {
if (FnStart == NULL) {
if (const DbgFuncStartInst *FSI = dyn_cast<DbgFuncStartInst>(BI)) {
- DISubprogram SP(cast<GlobalVariable>(FSI->getSubprogram()));
+ DISubprogram SP(FSI->getSubprogram());
assert (SP.isNull() == false && "Invalid llvm.dbg.func.start");
if (SP.describes(F))
- FnStart = SP.getGV();
+ FnStart = SP.getNode();
}
continue;
}
// exists in the instruction stream. Similiarly this will inline a recursive
// function by one level.
//
-bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD) {
+bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD,
+ SmallVectorImpl<AllocaInst*> *StaticAllocas) {
Instruction *TheCall = CS.getInstruction();
LLVMContext &Context = TheCall->getContext();
assert(TheCall->getParent() && TheCall->getParent()->getParent() &&
!CalledFunc->onlyReadsMemory()) {
const Type *AggTy = cast<PointerType>(I->getType())->getElementType();
const Type *VoidPtrTy =
- PointerType::getUnqual(Type::getInt8Ty(Context));
+ Type::getInt8PtrTy(Context);
// Create the alloca. If we have TargetData, use nice alignment.
unsigned Align = 1;
BI != BE; ++BI) {
if (DbgStopPointInst *DSPI = dyn_cast<DbgStopPointInst>(BI)) {
if (DbgRegionEndInst *NewDREI =
- dyn_cast<DbgRegionEndInst>(DREI->clone(Context)))
+ dyn_cast<DbgRegionEndInst>(DREI->clone()))
NewDREI->insertAfter(DSPI);
break;
}
if (!isa<Constant>(AI->getArraySize()))
continue;
+ // Keep track of the static allocas that we inline into the caller if the
+ // StaticAllocas pointer is non-null.
+ if (StaticAllocas) StaticAllocas->push_back(AI);
+
// Scan for the block of allocas that we can move over, and move them
// all at once.
while (isa<AllocaInst>(I) &&
- isa<Constant>(cast<AllocaInst>(I)->getArraySize()))
+ isa<Constant>(cast<AllocaInst>(I)->getArraySize())) {
+ if (StaticAllocas) StaticAllocas->push_back(cast<AllocaInst>(I));
++I;
+ }
// Transfer all of the allocas over in a block. Using splice means
// that the instructions aren't removed from the symbol table, then
if (InlinedFunctionInfo.ContainsDynamicAllocas) {
Module *M = Caller->getParent();
// Get the two intrinsics we care about.
- Constant *StackSave, *StackRestore;
- StackSave = Intrinsic::getDeclaration(M, Intrinsic::stacksave);
- StackRestore = Intrinsic::getDeclaration(M, Intrinsic::stackrestore);
+ Function *StackSave = Intrinsic::getDeclaration(M, Intrinsic::stacksave);
+ Function *StackRestore=Intrinsic::getDeclaration(M,Intrinsic::stackrestore);
// If we are preserving the callgraph, add edges to the stacksave/restore
// functions for the calls we insert.
CallGraphNode *StackSaveCGN = 0, *StackRestoreCGN = 0, *CallerNode = 0;
if (CG) {
- // We know that StackSave/StackRestore are Function*'s, because they are
- // intrinsics which must have the right types.
- StackSaveCGN = CG->getOrInsertFunction(cast<Function>(StackSave));
- StackRestoreCGN = CG->getOrInsertFunction(cast<Function>(StackRestore));
+ StackSaveCGN = CG->getOrInsertFunction(StackSave);
+ StackRestoreCGN = CG->getOrInsertFunction(StackRestore);
CallerNode = (*CG)[Caller];
}
for (Function::iterator BB = FirstNewBlock, E = Caller->end();
BB != E; ++BB)
if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator())) {
- CallInst::Create(StackRestore, SavedPtr, "", UI);
+ CallInst *CI = CallInst::Create(StackRestore, SavedPtr, "", UI);
+ if (CG) CallerNode->addCalledFunction(CI, StackRestoreCGN);
++NumStackRestores;
}
}
// any inlined 'unwind' instructions into branches to the invoke exception
// destination, and call instructions into invoke instructions.
if (InvokeInst *II = dyn_cast<InvokeInst>(TheCall))
- HandleInlinedInvoke(II, FirstNewBlock, InlinedFunctionInfo, CG);
+ HandleInlinedInvoke(II, FirstNewBlock, InlinedFunctionInfo);
// If we cloned in _exactly one_ basic block, and if that block ends in a
// return instruction, we splice the body of the inlined callee directly into
"Ret value not consistent in function!");
PHI->addIncoming(RI->getReturnValue(), RI->getParent());
}
+
+ // Now that we inserted the PHI, check to see if it has a single value
+ // (e.g. all the entries are the same or undef). If so, remove the PHI so
+ // it doesn't block other optimizations.
+ if (Value *V = PHI->hasConstantValue()) {
+ PHI->replaceAllUsesWith(V);
+ PHI->eraseFromParent();
+ }
}
+
// Add a branch to the merge points and remove return instructions.
for (unsigned i = 0, e = Returns.size(); i != e; ++i) {
ReturnInst *RI = Returns[i];