LLVM API Documentation
00001 //===- CodeMetrics.cpp - Code cost measurements ---------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements code cost measurement utilities. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/Analysis/AssumptionTracker.h" 00015 #include "llvm/Analysis/CodeMetrics.h" 00016 #include "llvm/Analysis/LoopInfo.h" 00017 #include "llvm/Analysis/TargetTransformInfo.h" 00018 #include "llvm/Analysis/ValueTracking.h" 00019 #include "llvm/IR/CallSite.h" 00020 #include "llvm/IR/DataLayout.h" 00021 #include "llvm/IR/Function.h" 00022 #include "llvm/IR/IntrinsicInst.h" 00023 #include "llvm/Support/Debug.h" 00024 00025 #define DEBUG_TYPE "code-metrics" 00026 00027 using namespace llvm; 00028 00029 static void completeEphemeralValues(SmallVector<const Value *, 16> &WorkSet, 00030 SmallPtrSetImpl<const Value*> &EphValues) { 00031 SmallPtrSet<const Value *, 32> Visited; 00032 00033 // Make sure that all of the items in WorkSet are in our EphValues set. 00034 EphValues.insert(WorkSet.begin(), WorkSet.end()); 00035 00036 // Note: We don't speculate PHIs here, so we'll miss instruction chains kept 00037 // alive only by ephemeral values. 00038 00039 while (!WorkSet.empty()) { 00040 const Value *V = WorkSet.pop_back_val(); 00041 if (!Visited.insert(V)) 00042 continue; 00043 00044 // If all uses of this value are ephemeral, then so is this value. 00045 bool FoundNEUse = false; 00046 for (const User *I : V->users()) 00047 if (!EphValues.count(I)) { 00048 FoundNEUse = true; 00049 break; 00050 } 00051 00052 if (FoundNEUse) 00053 continue; 00054 00055 EphValues.insert(V); 00056 DEBUG(dbgs() << "Ephemeral Value: " << *V << "\n"); 00057 00058 if (const User *U = dyn_cast<User>(V)) 00059 for (const Value *J : U->operands()) { 00060 if (isSafeToSpeculativelyExecute(J)) 00061 WorkSet.push_back(J); 00062 } 00063 } 00064 } 00065 00066 // Find all ephemeral values. 00067 void CodeMetrics::collectEphemeralValues(const Loop *L, AssumptionTracker *AT, 00068 SmallPtrSetImpl<const Value*> &EphValues) { 00069 SmallVector<const Value *, 16> WorkSet; 00070 00071 for (auto &I : AT->assumptions(L->getHeader()->getParent())) { 00072 // Filter out call sites outside of the loop so we don't to a function's 00073 // worth of work for each of its loops (and, in the common case, ephemeral 00074 // values in the loop are likely due to @llvm.assume calls in the loop). 00075 if (!L->contains(I->getParent())) 00076 continue; 00077 00078 WorkSet.push_back(I); 00079 } 00080 00081 completeEphemeralValues(WorkSet, EphValues); 00082 } 00083 00084 void CodeMetrics::collectEphemeralValues(const Function *F, AssumptionTracker *AT, 00085 SmallPtrSetImpl<const Value*> &EphValues) { 00086 SmallVector<const Value *, 16> WorkSet; 00087 00088 for (auto &I : AT->assumptions(const_cast<Function*>(F))) 00089 WorkSet.push_back(I); 00090 00091 completeEphemeralValues(WorkSet, EphValues); 00092 } 00093 00094 /// analyzeBasicBlock - Fill in the current structure with information gleaned 00095 /// from the specified block. 00096 void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB, 00097 const TargetTransformInfo &TTI, 00098 SmallPtrSetImpl<const Value*> &EphValues) { 00099 ++NumBlocks; 00100 unsigned NumInstsBeforeThisBB = NumInsts; 00101 for (BasicBlock::const_iterator II = BB->begin(), E = BB->end(); 00102 II != E; ++II) { 00103 // Skip ephemeral values. 00104 if (EphValues.count(II)) 00105 continue; 00106 00107 // Special handling for calls. 00108 if (isa<CallInst>(II) || isa<InvokeInst>(II)) { 00109 ImmutableCallSite CS(cast<Instruction>(II)); 00110 00111 if (const Function *F = CS.getCalledFunction()) { 00112 // If a function is both internal and has a single use, then it is 00113 // extremely likely to get inlined in the future (it was probably 00114 // exposed by an interleaved devirtualization pass). 00115 if (!CS.isNoInline() && F->hasInternalLinkage() && F->hasOneUse()) 00116 ++NumInlineCandidates; 00117 00118 // If this call is to function itself, then the function is recursive. 00119 // Inlining it into other functions is a bad idea, because this is 00120 // basically just a form of loop peeling, and our metrics aren't useful 00121 // for that case. 00122 if (F == BB->getParent()) 00123 isRecursive = true; 00124 00125 if (TTI.isLoweredToCall(F)) 00126 ++NumCalls; 00127 } else { 00128 // We don't want inline asm to count as a call - that would prevent loop 00129 // unrolling. The argument setup cost is still real, though. 00130 if (!isa<InlineAsm>(CS.getCalledValue())) 00131 ++NumCalls; 00132 } 00133 } 00134 00135 if (const AllocaInst *AI = dyn_cast<AllocaInst>(II)) { 00136 if (!AI->isStaticAlloca()) 00137 this->usesDynamicAlloca = true; 00138 } 00139 00140 if (isa<ExtractElementInst>(II) || II->getType()->isVectorTy()) 00141 ++NumVectorInsts; 00142 00143 if (const CallInst *CI = dyn_cast<CallInst>(II)) 00144 if (CI->cannotDuplicate()) 00145 notDuplicatable = true; 00146 00147 if (const InvokeInst *InvI = dyn_cast<InvokeInst>(II)) 00148 if (InvI->cannotDuplicate()) 00149 notDuplicatable = true; 00150 00151 NumInsts += TTI.getUserCost(&*II); 00152 } 00153 00154 if (isa<ReturnInst>(BB->getTerminator())) 00155 ++NumRets; 00156 00157 // We never want to inline functions that contain an indirectbr. This is 00158 // incorrect because all the blockaddress's (in static global initializers 00159 // for example) would be referring to the original function, and this indirect 00160 // jump would jump from the inlined copy of the function into the original 00161 // function which is extremely undefined behavior. 00162 // FIXME: This logic isn't really right; we can safely inline functions 00163 // with indirectbr's as long as no other function or global references the 00164 // blockaddress of a block within the current function. And as a QOI issue, 00165 // if someone is using a blockaddress without an indirectbr, and that 00166 // reference somehow ends up in another function or global, we probably 00167 // don't want to inline this function. 00168 notDuplicatable |= isa<IndirectBrInst>(BB->getTerminator()); 00169 00170 // Remember NumInsts for this BB. 00171 NumBBInsts[BB] = NumInsts - NumInstsBeforeThisBB; 00172 }