1234285Sdim//===- CodeMetrics.cpp - Code cost measurements ---------------------------===// 2234285Sdim// 3234285Sdim// The LLVM Compiler Infrastructure 4234285Sdim// 5234285Sdim// This file is distributed under the University of Illinois Open Source 6234285Sdim// License. See LICENSE.TXT for details. 7234285Sdim// 8234285Sdim//===----------------------------------------------------------------------===// 9234285Sdim// 10234285Sdim// This file implements code cost measurement utilities. 11234285Sdim// 12234285Sdim//===----------------------------------------------------------------------===// 13234285Sdim 14234285Sdim#include "llvm/Analysis/CodeMetrics.h" 15249423Sdim#include "llvm/Analysis/TargetTransformInfo.h" 16249423Sdim#include "llvm/IR/DataLayout.h" 17249423Sdim#include "llvm/IR/Function.h" 18249423Sdim#include "llvm/IR/IntrinsicInst.h" 19234285Sdim#include "llvm/Support/CallSite.h" 20234285Sdim 21234285Sdimusing namespace llvm; 22234285Sdim 23234285Sdim/// analyzeBasicBlock - Fill in the current structure with information gleaned 24234285Sdim/// from the specified block. 25234285Sdimvoid CodeMetrics::analyzeBasicBlock(const BasicBlock *BB, 26249423Sdim const TargetTransformInfo &TTI) { 27234285Sdim ++NumBlocks; 28234285Sdim unsigned NumInstsBeforeThisBB = NumInsts; 29234285Sdim for (BasicBlock::const_iterator II = BB->begin(), E = BB->end(); 30234285Sdim II != E; ++II) { 31234285Sdim // Special handling for calls. 32234285Sdim if (isa<CallInst>(II) || isa<InvokeInst>(II)) { 33234285Sdim ImmutableCallSite CS(cast<Instruction>(II)); 34234285Sdim 35234285Sdim if (const Function *F = CS.getCalledFunction()) { 36234285Sdim // If a function is both internal and has a single use, then it is 37234285Sdim // extremely likely to get inlined in the future (it was probably 38234285Sdim // exposed by an interleaved devirtualization pass). 39234285Sdim if (!CS.isNoInline() && F->hasInternalLinkage() && F->hasOneUse()) 40234285Sdim ++NumInlineCandidates; 41234285Sdim 42234285Sdim // If this call is to function itself, then the function is recursive. 43234285Sdim // Inlining it into other functions is a bad idea, because this is 44234285Sdim // basically just a form of loop peeling, and our metrics aren't useful 45234285Sdim // for that case. 46234285Sdim if (F == BB->getParent()) 47234285Sdim isRecursive = true; 48234285Sdim 49249423Sdim if (TTI.isLoweredToCall(F)) 50249423Sdim ++NumCalls; 51249423Sdim } else { 52234285Sdim // We don't want inline asm to count as a call - that would prevent loop 53234285Sdim // unrolling. The argument setup cost is still real, though. 54234285Sdim if (!isa<InlineAsm>(CS.getCalledValue())) 55234285Sdim ++NumCalls; 56234285Sdim } 57234285Sdim } 58234285Sdim 59234285Sdim if (const AllocaInst *AI = dyn_cast<AllocaInst>(II)) { 60234285Sdim if (!AI->isStaticAlloca()) 61234285Sdim this->usesDynamicAlloca = true; 62234285Sdim } 63234285Sdim 64234285Sdim if (isa<ExtractElementInst>(II) || II->getType()->isVectorTy()) 65234285Sdim ++NumVectorInsts; 66234285Sdim 67249423Sdim if (const CallInst *CI = dyn_cast<CallInst>(II)) 68249423Sdim if (CI->hasFnAttr(Attribute::NoDuplicate)) 69249423Sdim notDuplicatable = true; 70249423Sdim 71249423Sdim if (const InvokeInst *InvI = dyn_cast<InvokeInst>(II)) 72249423Sdim if (InvI->hasFnAttr(Attribute::NoDuplicate)) 73249423Sdim notDuplicatable = true; 74249423Sdim 75249423Sdim NumInsts += TTI.getUserCost(&*II); 76234285Sdim } 77234285Sdim 78234285Sdim if (isa<ReturnInst>(BB->getTerminator())) 79234285Sdim ++NumRets; 80234285Sdim 81234285Sdim // We never want to inline functions that contain an indirectbr. This is 82234285Sdim // incorrect because all the blockaddress's (in static global initializers 83234285Sdim // for example) would be referring to the original function, and this indirect 84234285Sdim // jump would jump from the inlined copy of the function into the original 85234285Sdim // function which is extremely undefined behavior. 86234285Sdim // FIXME: This logic isn't really right; we can safely inline functions 87234285Sdim // with indirectbr's as long as no other function or global references the 88234285Sdim // blockaddress of a block within the current function. And as a QOI issue, 89234285Sdim // if someone is using a blockaddress without an indirectbr, and that 90234285Sdim // reference somehow ends up in another function or global, we probably 91234285Sdim // don't want to inline this function. 92249423Sdim notDuplicatable |= isa<IndirectBrInst>(BB->getTerminator()); 93234285Sdim 94234285Sdim // Remember NumInsts for this BB. 95234285Sdim NumBBInsts[BB] = NumInsts - NumInstsBeforeThisBB; 96234285Sdim} 97