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-02-22 16:16:46 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       54145 : void TypeFinder::run(const Module &M, bool onlyNamed) {
      33       54145 :   OnlyNamed = onlyNamed;
      34             : 
      35             :   // Get types from global variables.
      36      141791 :   for (const auto &G : M.globals()) {
      37       87646 :     incorporateType(G.getType());
      38       87646 :     if (G.hasInitializer())
      39       73951 :       incorporateValue(G.getInitializer());
      40             :   }
      41             : 
      42             :   // Get types from aliases.
      43       55367 :   for (const auto &A : M.aliases()) {
      44        1222 :     incorporateType(A.getType());
      45             :     if (const Value *Aliasee = A.getAliasee())
      46        1222 :       incorporateValue(Aliasee);
      47             :   }
      48             : 
      49             :   // Get types from functions.
      50             :   SmallVector<std::pair<unsigned, MDNode *>, 4> MDForInst;
      51     1171511 :   for (const Function &FI : M) {
      52     1117366 :     incorporateType(FI.getType());
      53             : 
      54     2245376 :     for (const Use &U : FI.operands())
      55        5322 :       incorporateValue(U.get());
      56             : 
      57             :     // First incorporate the arguments.
      58     3542086 :     for (const auto &A : FI.args())
      59     2424720 :       incorporateValue(&A);
      60             : 
      61     2341458 :     for (const BasicBlock &BB : FI)
      62     7118737 :       for (const Instruction &I : BB) {
      63             :         // Incorporate the type of the instruction.
      64     5894645 :         incorporateType(I.getType());
      65             : 
      66             :         // Incorporate non-instruction operand types. (We are incorporating all
      67             :         // instructions with this loop.)
      68    31538970 :         for (const auto &O : I.operands())
      69    19749680 :           if (&*O && !isa<Instruction>(&*O))
      70     5739395 :             incorporateValue(&*O);
      71             : 
      72             :         // Incorporate types hiding in metadata.
      73             :         I.getAllMetadataOtherThanDebugLoc(MDForInst);
      74     6640409 :         for (const auto &MD : MDForInst)
      75      372882 :           incorporateMDNode(MD.second);
      76             :         MDForInst.clear();
      77             :       }
      78             :   }
      79             : 
      80       74050 :   for (const auto &NMD : M.named_metadata())
      81       52147 :     for (const auto &MDOp : NMD.operands())
      82       32242 :       incorporateMDNode(MDOp);
      83       54145 : }
      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     7910917 : void TypeFinder::incorporateType(Type *Ty) {
      94             :   // Check to see if we've already visited this type.
      95     7910917 :   if (!VisitedTypes.insert(Ty).second)
      96     6940807 :     return;
      97             : 
      98             :   SmallVector<Type *, 4> TypeWorklist;
      99      970110 :   TypeWorklist.push_back(Ty);
     100             :   do {
     101     2140681 :     Ty = TypeWorklist.pop_back_val();
     102             : 
     103             :     // If this is a structure or opaque type, add a name for the type.
     104     2140681 :     if (StructType *STy = dyn_cast<StructType>(Ty))
     105       61032 :       if (!OnlyNamed || STy->hasName())
     106       60979 :         StructTypes.push_back(STy);
     107             : 
     108             :     // Add all unvisited subtypes to worklist for processing
     109     2140681 :     for (Type::subtype_reverse_iterator I = Ty->subtype_rbegin(),
     110             :                                         E = Ty->subtype_rend();
     111     5700718 :          I != E; ++I)
     112     3560037 :       if (VisitedTypes.insert(*I).second)
     113     1170571 :         TypeWorklist.push_back(*I);
     114     2140681 :   } 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     8792462 : void TypeFinder::incorporateValue(const Value *V) {
     122     8792462 :   if (const auto *M = dyn_cast<MetadataAsValue>(V)) {
     123       14618 :     if (const auto *N = dyn_cast<MDNode>(M->getMetadata()))
     124        9625 :       return incorporateMDNode(N);
     125             :     if (const auto *MDV = dyn_cast<ValueAsMetadata>(M->getMetadata()))
     126        4725 :       return incorporateValue(MDV->getValue());
     127             :     return;
     128             :   }
     129             : 
     130     8777844 :   if (!isa<Constant>(V) || isa<GlobalValue>(V)) return;
     131             : 
     132             :   // Already visited?
     133     3330514 :   if (!VisitedConstants.insert(V).second)
     134             :     return;
     135             : 
     136             :   // Check this type.
     137      810038 :   incorporateType(V->getType());
     138             : 
     139             :   // If this is an instruction, we incorporate it separately.
     140     1620076 :   if (isa<Instruction>(V))
     141             :     return;
     142             : 
     143             :   // Look in operands for types.
     144             :   const User *U = cast<User>(V);
     145     1546462 :   for (const auto &I : U->operands())
     146      368212 :     incorporateValue(&*I);
     147             : }
     148             : 
     149             : /// incorporateMDNode - This method is used to walk the operands of an MDNode to
     150             : /// find types hiding within.
     151      649476 : void TypeFinder::incorporateMDNode(const MDNode *V) {
     152             :   // Already visited?
     153      649476 :   if (!VisitedMetadata.insert(V).second)
     154             :     return;
     155             : 
     156             :   // Look in operands for types.
     157     1432648 :   for (Metadata *Op : V->operands()) {
     158      552660 :     if (!Op)
     159       43269 :       continue;
     160      234727 :     if (auto *N = dyn_cast<MDNode>(Op)) {
     161      234727 :       incorporateMDNode(N);
     162      234727 :       continue;
     163             :     }
     164      174915 :     if (auto *C = dyn_cast<ConstantAsMetadata>(Op)) {
     165      174915 :       incorporateValue(C->getValue());
     166      174915 :       continue;
     167             :     }
     168             :   }
     169             : }

Generated by: LCOV version 1.13