zcov: / lib/Module/InstructionInfoTable.cpp


Files: 1 Branches Taken: 58.9% 53 / 90
Generated: 2009-05-17 22:47 Branches Executed: 66.7% 60 / 90
Line Coverage: 95.6% 86 / 90


Programs: 1 Runs 371


       1                 : #include "klee/Internal/Module/InstructionInfoTable.h"
       2                 : 
       3                 : #include "llvm/Function.h"
       4                 : #include "llvm/Instructions.h"
       5                 : #include "llvm/IntrinsicInst.h"
       6                 : #include "llvm/Linker.h"
       7                 : #include "llvm/Module.h"
       8                 : #include "llvm/Assembly/AsmAnnotationWriter.h"
       9                 : #include "llvm/Support/CFG.h"
      10                 : #include "llvm/Support/InstIterator.h"
      11                 : #include "llvm/Support/raw_ostream.h"
      12                 : #include "llvm/Analysis/ValueTracking.h"
      13                 : 
      14                 : #include <map>
      15                 : #include <iostream>
      16                 : #include <fstream>
      17                 : #include <sstream>
      18                 : #include <string>
      19                 : 
      20                 : #include "klee/Internal/FIXME/sugar.h"
      21                 : 
      22                 : using namespace llvm;
      23                 : using namespace klee;
      24                 : 
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                      103: branch 6 taken
      25              309: class InstructionToLineAnnotator : public llvm::AssemblyAnnotationWriter {
      26                 : public:
      27            92853:   void emitInstructionAnnot(const Instruction *i, llvm::raw_ostream &os) {
      28            92853:     os << "%%%" << (uintptr_t) i;
      29            92853:   }
      30                 : };
      31                 :         
      32                 : static void buildInstructionToLineMap(Module *m,
      33              103:                                       std::map<const Instruction*, unsigned> &out) {  
      34                 :   InstructionToLineAnnotator a;
      35              103:   std::ostringstream buffer;
      36              103:   m->print(buffer, &a);
      37              103:   std::string str = buffer.str();
      38                 :   const char *s;
      39                 : 
      40              103:   unsigned line = 1;
                 11612873: branch 0 taken
                      103: branch 1 taken
      41         11612976:   for (s=str.c_str(); *s; s++) {
                   124270: branch 0 taken
                 11488603: branch 1 taken
      42         11612873:     if (*s=='\n') {
      43           124270:       line++;
                    92853: branch 0 taken
                    31417: branch 1 taken
                    92853: branch 2 taken
                        0: branch 3 not taken
                    92853: branch 4 taken
                        0: branch 5 not taken
      44           124270:       if (s[1]=='%' && s[2]=='%' && s[3]=='%') {
      45            92853:         s += 4;
      46                 :         char *end;
      47            92853:         unsigned long long value = strtoull(s, &end, 10);
                    92853: branch 0 taken
                        0: branch 1 not taken
      48            92853:         if (end!=s) {
      49            92853:           out.insert(std::make_pair((const Instruction*) value, line));
      50                 :         }
      51            92853:         s = end;
      52                 :       }
      53                 :     }
      54              103:   }
      55              103: }
      56                 : 
      57             1382: static std::string getDSPIPath(DbgStopPointInst *dspi) {
      58                 :   std::string dir, file;
      59             1382:   bool res = GetConstantStringInfo(dspi->getDirectory(), dir);
                        0: branch 0 not taken
                     1382: branch 1 taken
      60             1382:   assert(res && "GetConstantStringInfo failed");
      61             1382:   res = GetConstantStringInfo(dspi->getFileName(), file);
                        0: branch 0 not taken
                     1382: branch 1 taken
      62             1382:   assert(res && "GetConstantStringInfo failed");
                        0: branch 0 not taken
                     1382: branch 1 taken
      63             1382:   if (dir.empty()) {
      64                0:     return file;
                        0: branch 1 not taken
                     1382: branch 2 taken
      65             2764:   } else if (*dir.rbegin() == '/') {
      66                0:     return dir + file;
      67                 :   } else {
      68             2764:     return dir + "/" + file;
      69             1382:   }
      70                 : }
      71                 : 
      72              103: InstructionInfoTable::InstructionInfoTable(Module *m) 
      73              412:   : dummyString(""), dummyInfo(0, dummyString, 0, 0) {
      74              103:   unsigned id = 0;
      75                 :   std::map<const Instruction*, unsigned> lineTable;
      76              103:   buildInstructionToLineMap(m, lineTable);
      77                 : 
                     1088: branch 1 taken
                      103: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
      78             2279:   foreach(fnIt, m->begin(), m->end()) {
      79             1088:     const std::string *initialFile = &dummyString;
      80             1088:     unsigned initialLine = 0;
      81                 : 
      82                 :     // It may be better to look for the closest stoppoint to the entry
      83                 :     // following the CFG, but it is not clear that it ever matters in
      84                 :     // practice.    
                    85342: branch 3 taken
                      983: branch 4 taken
                        0: branch 8 not taken
                        0: branch 9 not taken
      85            87413:     foreach(it, inst_begin(fnIt), inst_end(fnIt)) {
                      105: branch 1 taken
                    85237: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
      86            85342:       if (DbgStopPointInst *dspi = dyn_cast<DbgStopPointInst>(&*it)) {
      87              105:         initialFile = internString(getDSPIPath(dspi));
      88              105:         initialLine = dspi->getLine();
      89              105:         break;
      90                 :       }
      91                 :     }
      92                 :     
      93                 :     std::map<BasicBlock*, 
      94                 :       std::pair<const std::string*,unsigned> > sourceInfo;
                     8981: branch 1 taken
                     1088: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
      95            20138:     foreach(bbIt, fnIt->begin(), fnIt->end()) {
      96            26943:       let(res, sourceInfo.insert(std::make_pair(bbIt,
      97                 :                                                 std::make_pair(initialFile,
      98                 :                                                                initialLine))));
                     8461: branch 0 taken
                      520: branch 1 taken
                      520: branch 2 taken
                      520: branch 3 taken
      99             8981:       if (!res.second)
     100             8461:         continue;
     101                 : 
     102                 :       std::vector<BasicBlock*> worklist;
     103              520:       worklist.push_back(bbIt);
     104                 : 
                     8461: branch 0 taken
                      520: branch 1 taken
                      520: branch 2 taken
                      520: branch 3 taken
     105             8981:       do {
     106             8981:         BasicBlock *bb = worklist.back();
     107                 :         worklist.pop_back();
     108                 :         
     109                 :         let(si, sourceInfo.find(bb));
                        0: branch 0 not taken
                     8981: branch 1 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
     110             8981:         assert(si != sourceInfo.end());
     111             8981:         const std::string *file = si->second.first;
     112             8981:         unsigned line = si->second.second;
     113                 :         
                    92853: branch 1 taken
                     8981: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
     114           221630:         foreach(it, bb->begin(), bb->end()) {
     115            92853:           Instruction *instr = it;
     116            92853:           unsigned assemblyLine = 0;
     117            92853:           let(ltit, lineTable.find(instr));
                    92853: branch 0 taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
     118            92853:           if (ltit!=lineTable.end())
     119            92853:             assemblyLine = ltit->second;
                     1277: branch 1 taken
                    91576: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
     120            92853:           if (DbgStopPointInst *dspi = dyn_cast<DbgStopPointInst>(instr)) {
     121             1277:             file = internString(getDSPIPath(dspi));
     122             1277:             line = dspi->getLine();
     123                 :           }
     124                 :           infos.insert(std::make_pair(instr,
     125                 :                                       InstructionInfo(id++,
     126                 :                                                       *file,
     127                 :                                                       line,
     128           278559:                                                       assemblyLine)));        
     129                 :         }
     130                 :         
                    13337: branch 2 taken
                     8981: branch 3 taken
                        0: branch 6 not taken
                        0: branch 7 not taken
     131            31299:         foreach(it, succ_begin(bb), succ_end(bb)) {
                     8461: branch 1 taken
                     4876: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
     132            40011:           if (sourceInfo.insert(std::make_pair(*it,
     133                 :                                                std::make_pair(file, line))).second)
     134             8461:             worklist.push_back(*it);
     135                 :         }
     136                 :       } while (!worklist.empty());
     137                 :     }
     138                 :   }
     139              103: }
     140                 : 
     141              103: InstructionInfoTable::~InstructionInfoTable() {
                       76: branch 0 taken
                      103: branch 1 taken
                      103: branch 2 taken
                      103: branch 3 taken
     142              385:   foreach(it, internedStrings.begin(), internedStrings.end())
                       76: branch 0 taken
                        0: branch 1 not taken
                       76: branch 4 taken
                       76: branch 5 taken
     143               76:     delete *it;
     144              309: }
     145                 : 
     146             1382: const std::string *InstructionInfoTable::internString(std::string s) {
     147             1382:   let(it, internedStrings.find(&s));
                       76: branch 0 taken
                     1306: branch 1 taken
     148             2764:   if (it==internedStrings.end()) {
     149               76:     std::string *interned = new std::string(s);
     150               76:     internedStrings.insert(interned);
     151               76:     return interned;
     152                 :   } else {
     153             1306:     return *it;
     154                 :   }
     155                 : }
     156                 : 
     157              103: unsigned InstructionInfoTable::getMaxID() const {
     158              206:   return infos.size();
     159                 : }
     160                 : 
     161                 : const InstructionInfo &
     162           205973: InstructionInfoTable::getInfo(const Instruction *inst) const {
     163           205973:   let(it, infos.find(inst));
                        0: branch 0 not taken
                   205973: branch 1 taken
     164           411946:   if (it==infos.end()) {
     165                0:     return dummyInfo;
     166                 :   } else {
     167           205973:     return it->second;
     168                 :   }
     169                 : }
     170                 : 
     171                 : const InstructionInfo &
     172              330: InstructionInfoTable::getFunctionInfo(const Function *f) const {
                        0: branch 1 not taken
                      330: branch 2 taken
     173              330:   if (f->isDeclaration()) {
     174                0:     return dummyInfo;
     175                 :   } else {
     176              330:     return getInfo(f->begin()->begin());
     177                 :   }
                      103: branch 0 taken
                        0: branch 1 not taken
                      103: branch 2 taken
                        0: branch 3 not taken
     178              206: }

Generated: 2009-05-17 22:47 by zcov