//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
namespace {
struct VISIBILITY_HIDDEN TailCallElim : public FunctionPass {
+ static char ID; // Pass identification, replacement for typeid
+ TailCallElim() : FunctionPass((intptr_t)&ID) {}
+
virtual bool runOnFunction(Function &F);
private:
bool CanMoveAboveCall(Instruction *I, CallInst *CI);
Value *CanTransformAccumulatorRecursion(Instruction *I, CallInst *CI);
};
+ char TailCallElim::ID = 0;
RegisterPass<TailCallElim> X("tailcallelim", "Tail Call Elimination");
}
// If this alloca is in the body of the function, or if it is a variable
// sized allocation, we cannot tail call eliminate calls marked 'tail'
// with this mechanism.
- if (BB != &BB->getParent()->front() ||
+ if (BB != &BB->getParent()->getEntryBlock() ||
!isa<ConstantInt>(AI->getArraySize()))
CannotTCETailMarkedCall = true;
}
if (&BB->front() == Ret) // Make sure there is something before the ret...
return false;
+
+ // If the return is in the entry block, then making this transformation would
+ // turn infinite recursion into an infinite loop. This transformation is ok
+ // in theory, but breaks some code like:
+ // double fabs(double f) { return __builtin_fabs(f); } // a 'fabs' call
+ // disable this xform in this case, because the code generator will lower the
+ // call to fabs into inline code.
+ if (BB == &F->getEntryBlock())
+ return false;
// Scan backwards from the return, checking to see if there is a tail call in
// this block. If so, set CI to it.