LLVM API Documentation

CodeMetrics.cpp
Go to the documentation of this file.
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 }