LCOV - code coverage report
Current view: top level - lib/IR - TypeFinder.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 62 64 96.9 %
Date: 2018-07-13 00:08:38 Functions: 4 5 80.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- TypeFinder.cpp - Implement the TypeFinder class --------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file implements the TypeFinder class for the IR library.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #include "llvm/IR/TypeFinder.h"
      15             : #include "llvm/ADT/SmallVector.h"
      16             : #include "llvm/IR/BasicBlock.h"
      17             : #include "llvm/IR/Constant.h"
      18             : #include "llvm/IR/DerivedTypes.h"
      19             : #include "llvm/IR/Function.h"
      20             : #include "llvm/IR/Instruction.h"
      21             : #include "llvm/IR/Metadata.h"
      22             : #include "llvm/IR/Module.h"
      23             : #include "llvm/IR/Type.h"
      24             : #include "llvm/IR/Use.h"
      25             : #include "llvm/IR/User.h"
      26             : #include "llvm/IR/Value.h"
      27             : #include "llvm/Support/Casting.h"
      28             : #include <utility>
      29             : 
      30             : using namespace llvm;
      31             : 
      32       18224 : void TypeFinder::run(const Module &M, bool onlyNamed) {
      33       18224 :   OnlyNamed = onlyNamed;
      34             : 
      35             :   // Get types from global variables.
      36      101928 :   for (const auto &G : M.globals()) {
      37       83704 :     incorporateType(G.getType());
      38       83704 :     if (G.hasInitializer())
      39       72932 :       incorporateValue(G.getInitializer());
      40             :   }
      41             : 
      42             :   // Get types from aliases.
      43       19478 :   for (const auto &A : M.aliases()) {
      44        1254 :     incorporateType(A.getType());
      45             :     if (const Value *Aliasee = A.getAliasee())
      46        1254 :       incorporateValue(Aliasee);
      47             :   }
      48             : 
      49             :   // Get types from functions.
      50             :   SmallVector<std::pair<unsigned, MDNode *>, 4> MDForInst;
      51      220703 :   for (const Function &FI : M) {
      52      202479 :     incorporateType(FI.getType());
      53             : 
      54      416026 :     for (const Use &U : FI.operands())
      55        5535 :       incorporateValue(U.get());
      56             : 
      57             :     // First incorporate the arguments.
      58      522335 :     for (const auto &A : FI.args())
      59      319857 :       incorporateValue(&A);
      60             : 
      61      497651 :     for (const BasicBlock &BB : FI)
      62     2486957 :       for (const Instruction &I : BB) {
      63             :         // Incorporate the type of the instruction.
      64     2191785 :         incorporateType(I.getType());
      65             : 
      66             :         // Incorporate non-instruction operand types. (We are incorporating all
      67             :         // instructions with this loop.)
      68    11469400 :         for (const auto &O : I.operands())
      69     7085830 :           if (&*O && !isa<Instruction>(&*O))
      70     1637680 :             incorporateValue(&*O);
      71             : 
      72             :         // Incorporate types hiding in metadata.
      73             :         I.getAllMetadataOtherThanDebugLoc(MDForInst);
      74     2350501 :         for (const auto &MD : MDForInst)
      75       79358 :           incorporateMDNode(MD.second);
      76             :         MDForInst.clear();
      77             :       }
      78             :   }
      79             : 
      80       38451 :   for (const auto &NMD : M.named_metadata())
      81       52771 :     for (const auto &MDOp : NMD.operands())
      82       32544 :       incorporateMDNode(MDOp);
      83       18224 : }
      84             : 
      85           0 : void TypeFinder::clear() {
      86             :   VisitedConstants.clear();
      87             :   VisitedTypes.clear();
      88             :   StructTypes.clear();
      89           0 : }
      90             : 
      91             : /// incorporateType - This method adds the type to the list of used structures
      92             : /// if it's not in there already.
      93     2762291 : void TypeFinder::incorporateType(Type *Ty) {
      94             :   // Check to see if we've already visited this type.
      95     2762292 :   if (!VisitedTypes.insert(Ty).second)
      96     2549276 :     return;
      97             : 
      98             :   SmallVector<Type *, 4> TypeWorklist;
      99      213016 :   TypeWorklist.push_back(Ty);
     100             :   do {
     101      463470 :     Ty = TypeWorklist.pop_back_val();
     102             : 
     103             :     // If this is a structure or opaque type, add a name for the type.
     104      463470 :     if (StructType *STy = dyn_cast<StructType>(Ty))
     105       41212 :       if (!OnlyNamed || STy->hasName())
     106       41159 :         StructTypes.push_back(STy);
     107             : 
     108             :     // Add all unvisited subtypes to worklist for processing
     109      463470 :     for (Type::subtype_reverse_iterator I = Ty->subtype_rbegin(),
     110             :                                         E = Ty->subtype_rend();
     111     1109822 :          I != E; ++I)
     112      646352 :       if (VisitedTypes.insert(*I).second)
     113      250454 :         TypeWorklist.push_back(*I);
     114      463469 :   } while (!TypeWorklist.empty());
     115             : }
     116             : 
     117             : /// incorporateValue - This method is used to walk operand lists finding types
     118             : /// hiding in constant expressions and other operands that won't be walked in
     119             : /// other ways.  GlobalValues, basic blocks, instructions, and inst operands are
     120             : /// all explicitly enumerated.
     121     2398365 : void TypeFinder::incorporateValue(const Value *V) {
     122     2398365 :   if (const auto *M = dyn_cast<MetadataAsValue>(V)) {
     123       16462 :     if (const auto *N = dyn_cast<MDNode>(M->getMetadata()))
     124       10873 :       return incorporateMDNode(N);
     125             :     if (const auto *MDV = dyn_cast<ValueAsMetadata>(M->getMetadata()))
     126        5322 :       return incorporateValue(MDV->getValue());
     127             :     return;
     128             :   }
     129             : 
     130     2381903 :   if (!isa<Constant>(V) || isa<GlobalValue>(V)) return;
     131             : 
     132             :   // Already visited?
     133     1272689 :   if (!VisitedConstants.insert(V).second)
     134             :     return;
     135             : 
     136             :   // Check this type.
     137      283070 :   incorporateType(V->getType());
     138             : 
     139             :   // If this is an instruction, we incorporate it separately.
     140      566140 :   if (isa<Instruction>(V))
     141             :     return;
     142             : 
     143             :   // Look in operands for types.
     144             :   const User *U = cast<User>(V);
     145      848040 :   for (const auto &I : U->operands())
     146      282485 :     incorporateValue(&*I);
     147             : }
     148             : 
     149             : /// incorporateMDNode - This method is used to walk the operands of an MDNode to
     150             : /// find types hiding within.
     151      214045 : void TypeFinder::incorporateMDNode(const MDNode *V) {
     152             :   // Already visited?
     153      214045 :   if (!VisitedMetadata.insert(V).second)
     154             :     return;
     155             : 
     156             :   // Look in operands for types.
     157      718460 :   for (Metadata *Op : V->operands()) {
     158      275165 :     if (!Op)
     159       47207 :       continue;
     160       91270 :     if (auto *N = dyn_cast<MDNode>(Op)) {
     161       91270 :       incorporateMDNode(N);
     162       91270 :       continue;
     163             :     }
     164       73300 :     if (auto *C = dyn_cast<ConstantAsMetadata>(Op)) {
     165       73300 :       incorporateValue(C->getValue());
     166       73300 :       continue;
     167             :     }
     168             :   }
     169             : }

Generated by: LCOV version 1.13