LCOV - code coverage report
Current view: top level - lib/Support - CodeGenCoverage.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 5 36 13.9 %
Date: 2018-06-17 00:07:59 Functions: 4 9 44.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- lib/Support/CodeGenCoverage.cpp -------------------------------------==//
       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             : /// \file
      10             : /// This file implements the CodeGenCoverage class.
      11             : //===----------------------------------------------------------------------===//
      12             : 
      13             : #include "llvm/Support/CodeGenCoverage.h"
      14             : 
      15             : #include "llvm/Config/llvm-config.h"
      16             : #include "llvm/Support/Endian.h"
      17             : #include "llvm/Support/FileSystem.h"
      18             : #include "llvm/Support/MemoryBuffer.h"
      19             : #include "llvm/Support/Mutex.h"
      20             : #include "llvm/Support/ScopedPrinter.h"
      21             : #include "llvm/Support/ToolOutputFile.h"
      22             : 
      23             : #if LLVM_ON_UNIX
      24             : #include <unistd.h>
      25             : #elif _WIN32
      26             : #include <windows.h>
      27             : #endif
      28             : 
      29             : using namespace llvm;
      30             : 
      31      101456 : static sys::SmartMutex<true> OutputMutex;
      32             : 
      33        3380 : CodeGenCoverage::CodeGenCoverage() {}
      34             : 
      35           0 : void CodeGenCoverage::setCovered(uint64_t RuleID) {
      36           0 :   if (RuleCoverage.size() <= RuleID)
      37           0 :     RuleCoverage.resize(RuleID + 1, 0);
      38           0 :   RuleCoverage[RuleID] = true;
      39           0 : }
      40             : 
      41           0 : bool CodeGenCoverage::isCovered(uint64_t RuleID) const {
      42           0 :   if (RuleCoverage.size() <= RuleID)
      43             :     return false;
      44           0 :   return RuleCoverage[RuleID];
      45             : }
      46             : 
      47             : iterator_range<CodeGenCoverage::const_covered_iterator>
      48           0 : CodeGenCoverage::covered() const {
      49           0 :   return RuleCoverage.set_bits();
      50             : }
      51             : 
      52           0 : bool CodeGenCoverage::parse(MemoryBuffer &Buffer, StringRef BackendName) {
      53           0 :   const char *CurPtr = Buffer.getBufferStart();
      54             : 
      55           0 :   while (CurPtr != Buffer.getBufferEnd()) {
      56             :     // Read the backend name from the input.
      57             :     const char *LexedBackendName = CurPtr;
      58           0 :     while (*CurPtr++ != 0)
      59             :       ;
      60           0 :     if (CurPtr == Buffer.getBufferEnd())
      61             :       return false; // Data is invalid, expected rule id's to follow.
      62             : 
      63             :     bool IsForThisBackend = BackendName.equals(LexedBackendName);
      64           0 :     while (CurPtr != Buffer.getBufferEnd()) {
      65           0 :       if (std::distance(CurPtr, Buffer.getBufferEnd()) < 8)
      66             :         return false; // Data is invalid. Not enough bytes for another rule id.
      67             : 
      68             :       uint64_t RuleID = support::endian::read64(CurPtr, support::native);
      69             :       CurPtr += 8;
      70             : 
      71             :       // ~0ull terminates the rule id list.
      72           0 :       if (RuleID == ~0ull)
      73             :         break;
      74             : 
      75             :       // Anything else, is recorded or ignored depending on whether it's
      76             :       // intended for the backend we're interested in.
      77           0 :       if (IsForThisBackend)
      78           0 :         setCovered(RuleID);
      79             :     }
      80             :   }
      81             : 
      82             :   return true;
      83             : }
      84             : 
      85        1678 : bool CodeGenCoverage::emit(StringRef CoveragePrefix,
      86             :                            StringRef BackendName) const {
      87        1678 :   if (!CoveragePrefix.empty() && !RuleCoverage.empty()) {
      88             :     sys::SmartScopedLock<true> Lock(OutputMutex);
      89             : 
      90             :     // We can handle locking within a process easily enough but we don't want to
      91             :     // manage it between multiple processes. Use the process ID to ensure no
      92             :     // more than one process is ever writing to the same file at the same time.
      93             :     std::string Pid =
      94             : #if LLVM_ON_UNIX
      95           0 :         llvm::to_string(::getpid());
      96             : #elif _WIN32
      97             :         llvm::to_string(::GetCurrentProcessId());
      98             : #else
      99             :         "";
     100             : #endif
     101             : 
     102           0 :     std::string CoverageFilename = (CoveragePrefix + Pid).str();
     103             : 
     104             :     std::error_code EC;
     105             :     sys::fs::OpenFlags OpenFlags = sys::fs::F_Append;
     106             :     std::unique_ptr<ToolOutputFile> CoverageFile =
     107           0 :         llvm::make_unique<ToolOutputFile>(CoverageFilename, EC, OpenFlags);
     108           0 :     if (EC)
     109             :       return false;
     110             : 
     111           0 :     uint64_t Zero = 0;
     112           0 :     uint64_t InvZero = ~0ull;
     113           0 :     CoverageFile->os() << BackendName;
     114           0 :     CoverageFile->os().write((const char *)&Zero, sizeof(unsigned char));
     115           0 :     for (uint64_t I : RuleCoverage.set_bits())
     116           0 :       CoverageFile->os().write((const char *)&I, sizeof(uint64_t));
     117           0 :     CoverageFile->os().write((const char *)&InvZero, sizeof(uint64_t));
     118             : 
     119             :     CoverageFile->keep();
     120             :   }
     121             : 
     122             :   return true;
     123             : }
     124             : 
     125      304368 : void CodeGenCoverage::reset() { RuleCoverage.resize(0); }

Generated by: LCOV version 1.13