diff --git a/include/llvm/Analysis/CodeMetrics.h b/include/llvm/Analysis/CodeMetrics.h index 71160783492..03c807cf832 100644 --- a/include/llvm/Analysis/CodeMetrics.h +++ b/include/llvm/Analysis/CodeMetrics.h @@ -16,6 +16,7 @@ #define LLVM_ANALYSIS_CODEMETRICS_H #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/CallSite.h" namespace llvm { class BasicBlock; @@ -29,10 +30,11 @@ namespace llvm { /// \brief Check whether a call will lower to something small. /// - /// This tests checks whether calls to this function will lower to something + /// This tests checks whether this callsite will lower to something /// significantly cheaper than a traditional call, often a single - /// instruction. - bool callIsSmall(const Function *F); + /// instruction. Note that if isInstructionFree(CS.getInstruction()) would + /// return true, so will this function. + bool callIsSmall(ImmutableCallSite CS); /// \brief Utility to calculate the size and a few similar metrics for a set /// of basic blocks. diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h index 691c2d19be9..0cba135222b 100644 --- a/include/llvm/Analysis/InlineCost.h +++ b/include/llvm/Analysis/InlineCost.h @@ -127,10 +127,6 @@ namespace llvm { // adding a replacement API. InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold); }; - - /// callIsSmall - If a call is likely to lower to a single target instruction, - /// or is otherwise deemed small return true. - bool callIsSmall(const Function *Callee); } #endif diff --git a/lib/Analysis/CodeMetrics.cpp b/lib/Analysis/CodeMetrics.cpp index 316e7bc9349..acda34ba14b 100644 --- a/lib/Analysis/CodeMetrics.cpp +++ b/lib/Analysis/CodeMetrics.cpp @@ -22,7 +22,11 @@ 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(const Function *F) { +bool llvm::callIsSmall(ImmutableCallSite CS) { + if (isa(CS.getInstruction())) + return true; + + const Function *F = CS.getCalledFunction(); if (!F) return false; if (F->hasLocalLinkage()) return false; @@ -79,8 +83,24 @@ bool llvm::isInstructionFree(const Instruction *I, const TargetData *TD) { if (const CastInst *CI = dyn_cast(I)) { // Noop casts, including ptr <-> int, don't count. - if (CI->isLosslessCast() || isa(CI) || isa(CI)) + if (CI->isLosslessCast()) return true; + + Value *Op = CI->getOperand(0); + // An inttoptr cast is free so long as the input is a legal integer type + // which doesn't contain values outside the range of a pointer. + if (isa(CI) && TD && + TD->isLegalInteger(Op->getType()->getScalarSizeInBits()) && + Op->getType()->getScalarSizeInBits() <= TD->getPointerSizeInBits()) + return true; + + // A ptrtoint cast is free so long as the result is large enough to store + // the pointer, and a legal integer type. + if (isa(CI) && TD && + TD->isLegalInteger(Op->getType()->getScalarSizeInBits()) && + Op->getType()->getScalarSizeInBits() >= TD->getPointerSizeInBits()) + return true; + // trunc to a native type is free (assuming the target has compare and // shift-right of the same width). if (TD && isa(CI) && @@ -126,7 +146,7 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB, isRecursive = true; } - if (!isa(II) && !callIsSmall(CS.getCalledFunction())) { + if (!callIsSmall(CS)) { // Each argument to a call takes on average one instruction to set up. NumInsts += CS.arg_size(); diff --git a/lib/Analysis/InlineCost.cpp b/lib/Analysis/InlineCost.cpp index 3e3d2ab7538..615a7e6b7e3 100644 --- a/lib/Analysis/InlineCost.cpp +++ b/lib/Analysis/InlineCost.cpp @@ -398,10 +398,7 @@ bool CallAnalyzer::visitPtrToInt(PtrToIntInst &I) { if (lookupSROAArgAndCost(I.getOperand(0), SROAArg, CostIt)) SROAArgValues[&I] = SROAArg; - // A ptrtoint cast is free so long as the result is large enough to store the - // pointer, and a legal integer type. - return TD && TD->isLegalInteger(IntegerSize) && - IntegerSize >= TD->getPointerSizeInBits(); + return isInstructionFree(&I, TD); } bool CallAnalyzer::visitIntToPtr(IntToPtrInst &I) { @@ -428,10 +425,7 @@ bool CallAnalyzer::visitIntToPtr(IntToPtrInst &I) { if (lookupSROAArgAndCost(Op, SROAArg, CostIt)) SROAArgValues[&I] = SROAArg; - // An inttoptr cast is free so long as the input is a legal integer type - // which doesn't contain values outside the range of a pointer. - return TD && TD->isLegalInteger(IntegerSize) && - IntegerSize <= TD->getPointerSizeInBits(); + return isInstructionFree(&I, TD); } bool CallAnalyzer::visitCastInst(CastInst &I) { @@ -445,24 +439,7 @@ bool CallAnalyzer::visitCastInst(CastInst &I) { // Disable SROA in the face of arbitrary casts we don't whitelist elsewhere. disableSROA(I.getOperand(0)); - // No-op casts don't have any cost. - if (I.isLosslessCast()) - return true; - - // trunc to a native type is free (assuming the target has compare and - // shift-right of the same width). - if (TD && isa(I) && - TD->isLegalInteger(TD->getTypeSizeInBits(I.getType()))) - return true; - - // Result of a cmp instruction is often extended (to be used by other - // cmp instructions, logical or return instructions). These are usually - // no-ops on most sane targets. - if (isa(I.getOperand(0))) - return true; - - // Assume the rest of the casts require work. - return false; + return isInstructionFree(&I, TD); } bool CallAnalyzer::visitUnaryInstruction(UnaryInstruction &I) { @@ -636,21 +613,11 @@ bool CallAnalyzer::visitCallSite(CallSite CS) { default: return Base::visitCallSite(CS); - 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::memset: case Intrinsic::memcpy: case Intrinsic::memmove: - case Intrinsic::objectsize: - case Intrinsic::ptr_annotation: - case Intrinsic::var_annotation: - // SROA can usually chew through these intrinsics and they have no cost - // so don't pay the price of analyzing them in detail. - return true; + // SROA can usually chew through these intrinsics, but they aren't free. + return false; } } @@ -662,7 +629,7 @@ bool CallAnalyzer::visitCallSite(CallSite CS) { return false; } - if (!callIsSmall(F)) { + if (!callIsSmall(CS)) { // We account for the average 1 instruction per call argument setup // here. Cost += CS.arg_size() * InlineConstants::InstrCost; @@ -706,6 +673,11 @@ bool CallAnalyzer::visitCallSite(CallSite CS) { } bool CallAnalyzer::visitInstruction(Instruction &I) { + // Some instructions are free. All of the free intrinsics can also be + // handled by SROA, etc. + if (isInstructionFree(&I, TD)) + return true; + // We found something we don't understand or can't handle. Mark any SROA-able // values in the operand list as no longer viable. for (User::op_iterator OI = I.op_begin(), OE = I.op_end(); OI != OE; ++OI) diff --git a/lib/Transforms/Scalar/TailRecursionElimination.cpp b/lib/Transforms/Scalar/TailRecursionElimination.cpp index e21eb9dca27..074d0325d97 100644 --- a/lib/Transforms/Scalar/TailRecursionElimination.cpp +++ b/lib/Transforms/Scalar/TailRecursionElimination.cpp @@ -391,7 +391,7 @@ TailCallElim::FindTRECandidate(Instruction *TI, if (BB == &F->getEntryBlock() && FirstNonDbg(BB->front()) == CI && FirstNonDbg(llvm::next(BB->begin())) == TI && - callIsSmall(F)) { + callIsSmall(CI)) { // A single-block function with just a call and a return. Check that // the arguments match. CallSite::arg_iterator I = CallSite(CI).arg_begin(),