[llvm-commits] [llvm] r173148 - in /llvm/trunk: include/llvm/Analysis/TargetTransformInfo.h lib/Analysis/CodeMetrics.cpp lib/Analysis/IPA/InlineCost.cpp lib/Analysis/TargetTransformInfo.cpp lib/Transforms/Scalar/TailRecursionElimination.cpp
Hal Finkel
hfinkel at anl.gov
Fri Feb 21 11:50:53 PST 2014
----- Original Message -----
> From: "Arnold Schwaighofer" <aschwaighofer at apple.com>
> To: "Hal Finkel" <hfinkel at anl.gov>
> Cc: "Chandler Carruth" <chandlerc at gmail.com>, llvm-commits at cs.uiuc.edu, "Nadav Rotem" <nrotem at apple.com>, "renato
> golin" <renato.golin at linaro.org>
> Sent: Friday, February 21, 2014 1:47:44 PM
> Subject: Re: [llvm-commits] [llvm] r173148 - in /llvm/trunk: include/llvm/Analysis/TargetTransformInfo.h
> lib/Analysis/CodeMetrics.cpp lib/Analysis/IPA/InlineCost.cpp lib/Analysis/TargetTransformInfo.cpp
> lib/Transforms/Scalar/TailRecursionElimination.cpp
>
>
> On Feb 21, 2014, at 11:34 AM, Hal Finkel <hfinkel at anl.gov> wrote:
>
> > ----- Original Message -----
> >> From: "Chandler Carruth" <chandlerc at gmail.com>
> >> To: llvm-commits at cs.uiuc.edu
> >> Sent: Tuesday, January 22, 2013 5:26:02 AM
> >> Subject: [llvm-commits] [llvm] r173148 - in /llvm/trunk:
> >> include/llvm/Analysis/TargetTransformInfo.h
> >> lib/Analysis/CodeMetrics.cpp lib/Analysis/IPA/InlineCost.cpp
> >> lib/Analysis/TargetTransformInfo.cpp
> >> lib/Transforms/Scalar/TailRecursionElimination.cpp
> >>
> >> Author: chandlerc
> >> Date: Tue Jan 22 05:26:02 2013
> >> New Revision: 173148
> >>
> >> URL: http://llvm.org/viewvc/llvm-project?rev=173148&view=rev
> >> Log:
> >> Begin fleshing out an interface in TTI for modelling the costs of
> >> generic function calls and intrinsics. This is somewhat
> >> overlapping
> >> with
> >> an existing intrinsic cost method, but that one seems targetted at
> >> vector intrinsics. I'll merge them or separate their names and use
> >> cases
> >> in a separate commit.
> >>
> >> This sinks the test of 'callIsSmall' down into TTI where targets
> >> can
> >> control it. The whole thing feels very hack-ish to me though. I've
> >> left
> >> a FIXME comment about the fundamental design problem this
> >> presents.
> >> It
> >> isn't yet clear to me what the users of this function *really*
> >> care
> >> about. I'll have to do more analysis to figure that out. Putting
> >> this
> >> here at least provides it access to proper analysis pass tools and
> >> other
> >> such. It also allows us to more cleanly implement the baseline
> >> cost
> >> interfaces in TTI.
> >>
> >> With this commit, it is now theoretically possible to simplify
> >> much
> >> of
> >> the inline cost analysis's handling of calls by calling through to
> >> this
> >> interface. That conversion will have to happen in subsequent
> >> commits
> >> as
> >> it requires more extensive restructuring of the inline cost
> >> analysis.
> >>
> >> The CodeMetrics class is now really only in the business of
> >> running
> >> over
> >> a block of code and aggregating the metrics on that block of code,
> >> with
> >> the actual cost evaluation done entirely in terms of TTI.
> >
> > Looking at this in detail,
> >
> > + NumInsts += TTI.getUserCost(&*II);
>
> The TTI interface is separated into two sections, a scalar one which
> this calls belongs to and the vectorized section. The calls in the
> vectorized section (getInstructionCost) estimate throughput (or are
> meant to) and the ones in the scalar section (getOperationCost)
> presumably code size.
You're right, thanks! I was just confused :(
-Hal
>
>
> >
> > I'm not sure this is doing what we want. The issue is that the cost
> > model is designed to be used with the vectorizer, and the 'costs'
> > produced by that model don't really measure instructions, or even
> > uop counts, but relative throughput. This means, for example, that
> > if we can dispatch two integer adds per cycle, and 1
> > floating-point add per cycle, then the floating point add will
> > have twice the cost of the integer add (which probably has a cost
> > of 1). But it is not clear to me at all that this is the
> > appropriate measure for inlining and unrolling (especially for
> > unrolling, for OOO cores with loop dispatch buffers, we almost
> > certainly want uop counts).
> >
> > So the question is: what to do about this? The straightforward
> > thing seems to be to add some kind of 'cost-type' to all of the
> > TTI cost APIs. There seem to be three potentially relevant kinds
> > of costs:
> > - Scaled throughput
> > - uop counts
> > - instruction counts (or, perhaps instead: in-memory code size)
> >
> > The advantage of doing this is, for the most part, none of the
> > target independent code would need to care about what kind of cost
> > we needed (because the scalarization logic probably does not
> > care), and just the target parts need to change. But maybe there
> > is a better way. Opinions?
> >
> > -Hal
> >
> >>
> >> Modified:
> >> llvm/trunk/include/llvm/Analysis/TargetTransformInfo.h
> >> llvm/trunk/lib/Analysis/CodeMetrics.cpp
> >> llvm/trunk/lib/Analysis/IPA/InlineCost.cpp
> >> llvm/trunk/lib/Analysis/TargetTransformInfo.cpp
> >> llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp
> >>
> >> Modified: llvm/trunk/include/llvm/Analysis/TargetTransformInfo.h
> >> URL:
> >> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/TargetTransformInfo.h?rev=173148&r1=173147&r2=173148&view=diff
> >> ==============================================================================
> >> --- llvm/trunk/include/llvm/Analysis/TargetTransformInfo.h
> >> (original)
> >> +++ llvm/trunk/include/llvm/Analysis/TargetTransformInfo.h Tue Jan
> >> 22
> >> 05:26:02 2013
> >> @@ -117,6 +117,41 @@
> >> virtual unsigned getGEPCost(const Value *Ptr,
> >> ArrayRef<const Value *> Operands)
> >> const;
> >>
> >> + /// \brief Estimate the cost of a function call when lowered.
> >> + ///
> >> + /// The contract for this is the same as \c getOperationCost
> >> except that it
> >> + /// supports an interface that provides extra information
> >> specific
> >> to call
> >> + /// instructions.
> >> + ///
> >> + /// This is the most basic query for estimating call cost: it
> >> only
> >> knows the
> >> + /// function type and (potentially) the number of arguments at
> >> the
> >> call site.
> >> + /// The latter is only interesting for varargs function types.
> >> + virtual unsigned getCallCost(FunctionType *FTy, int NumArgs =
> >> -1)
> >> const;
> >> +
> >> + /// \brief Estimate the cost of calling a specific function
> >> when
> >> lowered.
> >> + ///
> >> + /// This overload adds the ability to reason about the
> >> particular
> >> function
> >> + /// being called in the event it is a library call with special
> >> lowering.
> >> + virtual unsigned getCallCost(const Function *F, int NumArgs =
> >> -1)
> >> const;
> >> +
> >> + /// \brief Estimate the cost of calling a specific function
> >> when
> >> lowered.
> >> + ///
> >> + /// This overload allows specifying a set of candidate argument
> >> values.
> >> + virtual unsigned getCallCost(const Function *F,
> >> + ArrayRef<const Value *> Arguments)
> >> const;
> >> +
> >> + /// \brief Estimate the cost of an intrinsic when lowered.
> >> + ///
> >> + /// Mirrors the \c getCallCost method but uses an intrinsic
> >> identifier.
> >> + virtual unsigned getIntrinsicCost(Intrinsic::ID IID, Type
> >> *RetTy,
> >> + ArrayRef<Type *> ParamTys)
> >> const;
> >> +
> >> + /// \brief Estimate the cost of an intrinsic when lowered.
> >> + ///
> >> + /// Mirrors the \c getCallCost method but uses an intrinsic
> >> identifier.
> >> + virtual unsigned getIntrinsicCost(Intrinsic::ID IID, Type
> >> *RetTy,
> >> + ArrayRef<const Value *>
> >> Arguments) const;
> >> +
> >> /// \brief Estimate the cost of a given IR user when lowered.
> >> ///
> >> /// This can estimate the cost of either a ConstantExpr or
> >> Instruction when
> >> @@ -134,6 +169,20 @@
> >> /// comments for a detailed explanation of the cost values.
> >> virtual unsigned getUserCost(const User *U) const;
> >>
> >> + /// \brief Test whether calls to a function lower to actual
> >> program function
> >> + /// calls.
> >> + ///
> >> + /// The idea is to test whether the program is likely to
> >> require a
> >> 'call'
> >> + /// instruction or equivalent in order to call the given
> >> function.
> >> + ///
> >> + /// FIXME: It's not clear that this is a good or useful query
> >> API.
> >> Client's
> >> + /// should probably move to simpler cost metrics using the
> >> above.
> >> + /// Alternatively, we could split the cost interface into
> >> distinct
> >> code-size
> >> + /// and execution-speed costs. This would allow modelling the
> >> core
> >> of this
> >> + /// query more accurately as the a call is a single small
> >> instruction, but
> >> + /// incurs significant execution cost.
> >> + virtual bool isLoweredToCall(const Function *F) const;
> >> +
> >> /// @}
> >>
> >> /// \name Scalar Target Information
> >>
> >> Modified: llvm/trunk/lib/Analysis/CodeMetrics.cpp
> >> URL:
> >> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CodeMetrics.cpp?rev=173148&r1=173147&r2=173148&view=diff
> >> ==============================================================================
> >> --- llvm/trunk/lib/Analysis/CodeMetrics.cpp (original)
> >> +++ llvm/trunk/lib/Analysis/CodeMetrics.cpp Tue Jan 22 05:26:02
> >> 2013
> >> @@ -20,41 +20,6 @@
> >>
> >> using namespace llvm;
> >>
> >> -/// callIsSmall - If a call is likely to lower to a single target
> >> instruction,
> >> -/// or is otherwise deemed small return true.
> >> -/// TODO: Perhaps calls like memcpy, strcpy, etc?
> >> -bool llvm::callIsSmall(ImmutableCallSite CS) {
> >> - if (isa<IntrinsicInst>(CS.getInstruction()))
> >> - return true;
> >> -
> >> - const Function *F = CS.getCalledFunction();
> >> - if (!F) return false;
> >> -
> >> - if (F->hasLocalLinkage()) return false;
> >> -
> >> - if (!F->hasName()) return false;
> >> -
> >> - StringRef Name = F->getName();
> >> -
> >> - // These will all likely lower to a single selection DAG node.
> >> - if (Name == "copysign" || Name == "copysignf" || Name ==
> >> "copysignl" ||
> >> - Name == "fabs" || Name == "fabsf" || Name == "fabsl" ||
> >> - Name == "sin" || Name == "sinf" || Name == "sinl" ||
> >> - Name == "cos" || Name == "cosf" || Name == "cosl" ||
> >> - Name == "sqrt" || Name == "sqrtf" || Name == "sqrtl" )
> >> - return true;
> >> -
> >> - // These are all likely to be optimized into something smaller.
> >> - if (Name == "pow" || Name == "powf" || Name == "powl" ||
> >> - Name == "exp2" || Name == "exp2l" || Name == "exp2f" ||
> >> - Name == "floor" || Name == "floorf" || Name == "ceil" ||
> >> - Name == "round" || Name == "ffs" || Name == "ffsl" ||
> >> - Name == "abs" || Name == "labs" || Name == "llabs")
> >> - return true;
> >> -
> >> - return false;
> >> -}
> >> -
> >> /// analyzeBasicBlock - Fill in the current structure with
> >> information gleaned
> >> /// from the specified block.
> >> void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB,
> >> @@ -63,9 +28,6 @@
> >> unsigned NumInstsBeforeThisBB = NumInsts;
> >> for (BasicBlock::const_iterator II = BB->begin(), E = BB->end();
> >> II != E; ++II) {
> >> - if (TargetTransformInfo::TCC_Free == TTI.getUserCost(&*II))
> >> - continue;
> >> -
> >> // Special handling for calls.
> >> if (isa<CallInst>(II) || isa<InvokeInst>(II)) {
> >> ImmutableCallSite CS(cast<Instruction>(II));
> >> @@ -83,12 +45,10 @@
> >> // for that case.
> >> if (F == BB->getParent())
> >> isRecursive = true;
> >> - }
> >> -
> >> - if (!callIsSmall(CS)) {
> >> - // Each argument to a call takes on average one
> >> instruction
> >> to set up.
> >> - NumInsts += CS.arg_size();
> >>
> >> + if (TTI.isLoweredToCall(F))
> >> + ++NumCalls;
> >> + } else {
> >> // We don't want inline asm to count as a call - that
> >> would
> >> prevent loop
> >> // unrolling. The argument setup cost is still real,
> >> though.
> >> if (!isa<InlineAsm>(CS.getCalledValue()))
> >> @@ -112,7 +72,7 @@
> >> if (InvI->hasFnAttr(Attribute::NoDuplicate))
> >> notDuplicatable = true;
> >>
> >> - ++NumInsts;
> >> + NumInsts += TTI.getUserCost(&*II);
> >> }
> >>
> >> if (isa<ReturnInst>(BB->getTerminator()))
> >>
> >> Modified: llvm/trunk/lib/Analysis/IPA/InlineCost.cpp
> >> URL:
> >> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/InlineCost.cpp?rev=173148&r1=173147&r2=173148&view=diff
> >> ==============================================================================
> >> --- llvm/trunk/lib/Analysis/IPA/InlineCost.cpp (original)
> >> +++ llvm/trunk/lib/Analysis/IPA/InlineCost.cpp Tue Jan 22 05:26:02
> >> 2013
> >> @@ -736,7 +736,7 @@
> >> return false;
> >> }
> >>
> >> - if (!callIsSmall(CS)) {
> >> + if (TTI.isLoweredToCall(F)) {
> >> // We account for the average 1 instruction per call
> >> argument
> >> setup
> >> // here.
> >> Cost += CS.arg_size() * InlineConstants::InstrCost;
> >>
> >> Modified: llvm/trunk/lib/Analysis/TargetTransformInfo.cpp
> >> URL:
> >> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/TargetTransformInfo.cpp?rev=173148&r1=173147&r2=173148&view=diff
> >> ==============================================================================
> >> --- llvm/trunk/lib/Analysis/TargetTransformInfo.cpp (original)
> >> +++ llvm/trunk/lib/Analysis/TargetTransformInfo.cpp Tue Jan 22
> >> 05:26:02 2013
> >> @@ -14,6 +14,7 @@
> >> #include "llvm/IR/Instruction.h"
> >> #include "llvm/IR/IntrinsicInst.h"
> >> #include "llvm/IR/Instructions.h"
> >> +#include "llvm/Support/CallSite.h"
> >> #include "llvm/Support/ErrorHandling.h"
> >>
> >> using namespace llvm;
> >> @@ -58,10 +59,39 @@
> >> return PrevTTI->getGEPCost(Ptr, Operands);
> >> }
> >>
> >> +unsigned TargetTransformInfo::getCallCost(FunctionType *FTy,
> >> + int NumArgs) const {
> >> + return PrevTTI->getCallCost(FTy, NumArgs);
> >> +}
> >> +
> >> +unsigned TargetTransformInfo::getCallCost(const Function *F,
> >> + int NumArgs) const {
> >> + return PrevTTI->getCallCost(F, NumArgs);
> >> +}
> >> +
> >> +unsigned TargetTransformInfo::getCallCost(
> >> + const Function *F, ArrayRef<const Value *> Arguments) const {
> >> + return PrevTTI->getCallCost(F, Arguments);
> >> +}
> >> +
> >> +unsigned TargetTransformInfo::getIntrinsicCost(
> >> + Intrinsic::ID IID, Type *RetTy, ArrayRef<Type *> ParamTys)
> >> const
> >> {
> >> + return PrevTTI->getIntrinsicCost(IID, RetTy, ParamTys);
> >> +}
> >> +
> >> +unsigned TargetTransformInfo::getIntrinsicCost(
> >> + Intrinsic::ID IID, Type *RetTy, ArrayRef<const Value *>
> >> Arguments) const {
> >> + return PrevTTI->getIntrinsicCost(IID, RetTy, Arguments);
> >> +}
> >> +
> >> unsigned TargetTransformInfo::getUserCost(const User *U) const {
> >> return PrevTTI->getUserCost(U);
> >> }
> >>
> >> +bool TargetTransformInfo::isLoweredToCall(const Function *F)
> >> const {
> >> + return PrevTTI->isLoweredToCall(F);
> >> +}
> >> +
> >> bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm) const {
> >> return PrevTTI->isLegalAddImmediate(Imm);
> >> }
> >> @@ -179,6 +209,7 @@
> >> virtual void initializePass() {
> >> // Note that this subclass is special, and must *not* call
> >> initializeTTI as
> >> // it does not chain.
> >> + TopTTI = this;
> >> PrevTTI = 0;
> >> DL = getAnalysisIfAvailable<DataLayout>();
> >> }
> >> @@ -257,6 +288,84 @@
> >> return TCC_Free;
> >> }
> >>
> >> + unsigned getCallCost(FunctionType *FTy, int NumArgs = -1) const
> >> {
> >> + assert(FTy && "FunctionType must be provided to this
> >> routine.");
> >> +
> >> + // The target-independent implementation just measures the
> >> size
> >> of the
> >> + // function by approximating that each argument will take on
> >> average one
> >> + // instruction to prepare.
> >> +
> >> + if (NumArgs < 0)
> >> + // Set the argument number to the number of explicit
> >> arguments
> >> in the
> >> + // function.
> >> + NumArgs = FTy->getNumParams();
> >> +
> >> + return TCC_Basic * (NumArgs + 1);
> >> + }
> >> +
> >> + unsigned getCallCost(const Function *F, int NumArgs = -1) const
> >> {
> >> + assert(F && "A concrete function must be provided to this
> >> routine.");
> >> +
> >> + if (NumArgs < 0)
> >> + // Set the argument number to the number of explicit
> >> arguments
> >> in the
> >> + // function.
> >> + NumArgs = F->arg_size();
> >> +
> >> + if (Intrinsic::ID IID = (Intrinsic::ID)F->getIntrinsicID()) {
> >> + FunctionType *FTy = F->getFunctionType();
> >> + SmallVector<Type *, 8> ParamTys(FTy->param_begin(),
> >> FTy->param_end());
> >> + return TopTTI->getIntrinsicCost(IID, FTy->getReturnType(),
> >> ParamTys);
> >> + }
> >> +
> >> + if (!TopTTI->isLoweredToCall(F))
> >> + return TCC_Basic; // Give a basic cost if it will be
> >> lowered
> >> directly.
> >> +
> >> + return TopTTI->getCallCost(F->getFunctionType(), NumArgs);
> >> + }
> >> +
> >> + unsigned getCallCost(const Function *F,
> >> + ArrayRef<const Value *> Arguments) const {
> >> + // Simply delegate to generic handling of the call.
> >> + // FIXME: We should use instsimplify or something else to
> >> catch
> >> calls which
> >> + // will constant fold with these arguments.
> >> + return TopTTI->getCallCost(F, Arguments.size());
> >> + }
> >> +
> >> + unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
> >> + ArrayRef<Type *> ParamTys) const {
> >> + switch (IID) {
> >> + default:
> >> + // Intrinsics rarely (if ever) have normal argument setup
> >> constraints.
> >> + // Model them as having a basic instruction cost.
> >> + // FIXME: This is wrong for libc intrinsics.
> >> + return TCC_Basic;
> >> +
> >> + case Intrinsic::dbg_declare:
> >> + case Intrinsic::dbg_value:
> >> + case Intrinsic::invariant_start:
> >> + case Intrinsic::invariant_end:
> >> + case Intrinsic::lifetime_start:
> >> + case Intrinsic::lifetime_end:
> >> + case Intrinsic::objectsize:
> >> + case Intrinsic::ptr_annotation:
> >> + case Intrinsic::var_annotation:
> >> + // These intrinsics don't actually represent code after
> >> lowering.
> >> + return TCC_Free;
> >> + }
> >> + }
> >> +
> >> + unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
> >> + ArrayRef<const Value *> Arguments)
> >> const
> >> {
> >> + // Delegate to the generic intrinsic handling code. This
> >> mostly
> >> provides an
> >> + // opportunity for targets to (for example) special case the
> >> cost of
> >> + // certain intrinsics based on constants used as arguments.
> >> + SmallVector<Type *, 8> ParamTys;
> >> + ParamTys.reserve(Arguments.size());
> >> + for (unsigned Idx = 0, Size = Arguments.size(); Idx != Size;
> >> ++Idx)
> >> + ParamTys.push_back(Arguments[Idx]->getType());
> >> + return TopTTI->getIntrinsicCost(IID, RetTy, ParamTys);
> >> + }
> >> +
> >> unsigned getUserCost(const User *U) const {
> >> if (isa<PHINode>(U))
> >> return TCC_Free; // Model all PHI nodes as free.
> >> @@ -266,25 +375,21 @@
> >> // folded into their uses via addressing modes.
> >> return GEP->hasAllConstantIndices() ? TCC_Free : TCC_Basic;
> >>
> >> - // If we have a call of an intrinsic we can provide more
> >> detailed analysis
> >> - // by inspecting the particular intrinsic called.
> >> - // FIXME: Hoist this out into a getIntrinsicCost routine.
> >> - if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(U)) {
> >> - switch (II->getIntrinsicID()) {
> >> - default:
> >> - return TCC_Basic;
> >> - case Intrinsic::dbg_declare:
> >> - case Intrinsic::dbg_value:
> >> - case Intrinsic::invariant_start:
> >> - case Intrinsic::invariant_end:
> >> - case Intrinsic::lifetime_start:
> >> - case Intrinsic::lifetime_end:
> >> - case Intrinsic::objectsize:
> >> - case Intrinsic::ptr_annotation:
> >> - case Intrinsic::var_annotation:
> >> - // These intrinsics don't count as size.
> >> - return TCC_Free;
> >> + if (ImmutableCallSite CS = U) {
> >> + const Function *F = CS.getCalledFunction();
> >> + if (!F) {
> >> + // Just use the called value type.
> >> + Type *FTy =
> >> CS.getCalledValue()->getType()->getPointerElementType();
> >> + return TopTTI->getCallCost(cast<FunctionType>(FTy),
> >> CS.arg_size());
> >> }
> >> +
> >> + SmallVector<const Value *, 8> Arguments;
> >> + for (ImmutableCallSite::arg_iterator AI = CS.arg_begin(),
> >> + AE = CS.arg_end();
> >> + AI != AE; ++AI)
> >> + Arguments.push_back(*AI);
> >> +
> >> + return TopTTI->getCallCost(F, Arguments);
> >> }
> >>
> >> if (const CastInst *CI = dyn_cast<CastInst>(U)) {
> >> @@ -301,6 +406,37 @@
> >> U->getOperand(0)->getType() : 0);
> >> }
> >>
> >> + bool isLoweredToCall(const Function *F) const {
> >> + // FIXME: These should almost certainly not be handled here,
> >> and
> >> instead
> >> + // handled with the help of TLI or the target itself. This
> >> was
> >> largely
> >> + // ported from existing analysis heuristics here so that such
> >> refactorings
> >> + // can take place in the future.
> >> +
> >> + if (F->isIntrinsic())
> >> + return false;
> >> +
> >> + if (F->hasLocalLinkage() || !F->hasName())
> >> + return true;
> >> +
> >> + StringRef Name = F->getName();
> >> +
> >> + // These will all likely lower to a single selection DAG
> >> node.
> >> + if (Name == "copysign" || Name == "copysignf" || Name ==
> >> "copysignl" ||
> >> + Name == "fabs" || Name == "fabsf" || Name == "fabsl" ||
> >> Name
> >> == "sin" ||
> >> + Name == "sinf" || Name == "sinl" || Name == "cos" || Name
> >> ==
> >> "cosf" ||
> >> + Name == "cosl" || Name == "sqrt" || Name == "sqrtf" ||
> >> Name
> >> == "sqrtl")
> >> + return false;
> >> +
> >> + // These are all likely to be optimized into something
> >> smaller.
> >> + if (Name == "pow" || Name == "powf" || Name == "powl" || Name
> >> ==
> >> "exp2" ||
> >> + Name == "exp2l" || Name == "exp2f" || Name == "floor" ||
> >> Name ==
> >> + "floorf" || Name == "ceil" || Name == "round" || Name ==
> >> "ffs" ||
> >> + Name == "ffsl" || Name == "abs" || Name == "labs" || Name
> >> ==
> >> "llabs")
> >> + return false;
> >> +
> >> + return true;
> >> + }
> >> +
> >> bool isLegalAddImmediate(int64_t Imm) const {
> >> return false;
> >> }
> >>
> >> Modified:
> >> llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp
> >> URL:
> >> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp?rev=173148&r1=173147&r2=173148&view=diff
> >> ==============================================================================
> >> --- llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp
> >> (original)
> >> +++ llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp
> >> Tue
> >> Jan 22 05:26:02 2013
> >> @@ -58,6 +58,7 @@
> >> #include "llvm/Analysis/InlineCost.h"
> >> #include "llvm/Analysis/InstructionSimplify.h"
> >> #include "llvm/Analysis/Loads.h"
> >> +#include "llvm/Analysis/TargetTransformInfo.h"
> >> #include "llvm/IR/Constants.h"
> >> #include "llvm/IR/DerivedTypes.h"
> >> #include "llvm/IR/Function.h"
> >> @@ -79,11 +80,15 @@
> >>
> >> namespace {
> >> struct TailCallElim : public FunctionPass {
> >> + const TargetTransformInfo *TTI;
> >> +
> >> static char ID; // Pass identification, replacement for typeid
> >> TailCallElim() : FunctionPass(ID) {
> >> initializeTailCallElimPass(*PassRegistry::getPassRegistry());
> >> }
> >>
> >> + virtual void getAnalysisUsage(AnalysisUsage &AU) const;
> >> +
> >> virtual bool runOnFunction(Function &F);
> >>
> >> private:
> >> @@ -109,14 +114,21 @@
> >> }
> >>
> >> char TailCallElim::ID = 0;
> >> -INITIALIZE_PASS(TailCallElim, "tailcallelim",
> >> - "Tail Call Elimination", false, false)
> >> +INITIALIZE_PASS_BEGIN(TailCallElim, "tailcallelim",
> >> + "Tail Call Elimination", false, false)
> >> +INITIALIZE_AG_DEPENDENCY(TargetTransformInfo)
> >> +INITIALIZE_PASS_END(TailCallElim, "tailcallelim",
> >> + "Tail Call Elimination", false, false)
> >>
> >> // Public interface to the TailCallElimination pass
> >> FunctionPass *llvm::createTailCallEliminationPass() {
> >> return new TailCallElim();
> >> }
> >>
> >> +void TailCallElim::getAnalysisUsage(AnalysisUsage &AU) const {
> >> + AU.addRequired<TargetTransformInfo>();
> >> +}
> >> +
> >> /// AllocaMightEscapeToCalls - Return true if this alloca may be
> >> accessed by
> >> /// callees of this function. We only do very simple analysis
> >> right
> >> now, this
> >> /// could be expanded in the future to use mod/ref information for
> >> particular
> >> @@ -151,6 +163,7 @@
> >> // right, so don't even try to convert it...
> >> if (F.getFunctionType()->isVarArg()) return false;
> >>
> >> + TTI = &getAnalysis<TargetTransformInfo>();
> >> BasicBlock *OldEntry = 0;
> >> bool TailCallsAreMarkedTail = false;
> >> SmallVector<PHINode*, 8> ArgumentPHIs;
> >> @@ -391,7 +404,8 @@
> >> if (BB == &F->getEntryBlock() &&
> >> FirstNonDbg(BB->front()) == CI &&
> >> FirstNonDbg(llvm::next(BB->begin())) == TI &&
> >> - callIsSmall(CI)) {
> >> + CI->getCalledFunction() &&
> >> + !TTI->isLoweredToCall(CI->getCalledFunction())) {
> >> // A single-block function with just a call and a return.
> >> Check
> >> that
> >> // the arguments match.
> >> CallSite::arg_iterator I = CallSite(CI).arg_begin(),
> >>
> >>
> >> _______________________________________________
> >> llvm-commits mailing list
> >> llvm-commits at cs.uiuc.edu
> >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> >>
> >
> > --
> > Hal Finkel
> > Assistant Computational Scientist
> > Leadership Computing Facility
> > Argonne National Laboratory
>
>
--
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory
More information about the llvm-commits
mailing list