LLVM  10.0.0svn
CodeGenCoverage.cpp
Go to the documentation of this file.
1 //===- lib/Support/CodeGenCoverage.cpp -------------------------------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements the CodeGenCoverage class.
10 //===----------------------------------------------------------------------===//
11 
13 
14 #include "llvm/Config/llvm-config.h"
15 #include "llvm/Support/Endian.h"
18 #include "llvm/Support/Mutex.h"
21 
22 #if LLVM_ON_UNIX
23 #include <unistd.h>
24 #elif defined(_WIN32)
25 #include <windows.h>
26 #endif
27 
28 using namespace llvm;
29 
31 
33 
34 void CodeGenCoverage::setCovered(uint64_t RuleID) {
35  if (RuleCoverage.size() <= RuleID)
36  RuleCoverage.resize(RuleID + 1, 0);
37  RuleCoverage[RuleID] = true;
38 }
39 
40 bool CodeGenCoverage::isCovered(uint64_t RuleID) const {
41  if (RuleCoverage.size() <= RuleID)
42  return false;
43  return RuleCoverage[RuleID];
44 }
45 
48  return RuleCoverage.set_bits();
49 }
50 
51 bool CodeGenCoverage::parse(MemoryBuffer &Buffer, StringRef BackendName) {
52  const char *CurPtr = Buffer.getBufferStart();
53 
54  while (CurPtr != Buffer.getBufferEnd()) {
55  // Read the backend name from the input.
56  const char *LexedBackendName = CurPtr;
57  while (*CurPtr++ != 0)
58  ;
59  if (CurPtr == Buffer.getBufferEnd())
60  return false; // Data is invalid, expected rule id's to follow.
61 
62  bool IsForThisBackend = BackendName.equals(LexedBackendName);
63  while (CurPtr != Buffer.getBufferEnd()) {
64  if (std::distance(CurPtr, Buffer.getBufferEnd()) < 8)
65  return false; // Data is invalid. Not enough bytes for another rule id.
66 
67  uint64_t RuleID = support::endian::read64(CurPtr, support::native);
68  CurPtr += 8;
69 
70  // ~0ull terminates the rule id list.
71  if (RuleID == ~0ull)
72  break;
73 
74  // Anything else, is recorded or ignored depending on whether it's
75  // intended for the backend we're interested in.
76  if (IsForThisBackend)
77  setCovered(RuleID);
78  }
79  }
80 
81  return true;
82 }
83 
85  StringRef BackendName) const {
86  if (!CoveragePrefix.empty() && !RuleCoverage.empty()) {
87  sys::SmartScopedLock<true> Lock(OutputMutex);
88 
89  // We can handle locking within a process easily enough but we don't want to
90  // manage it between multiple processes. Use the process ID to ensure no
91  // more than one process is ever writing to the same file at the same time.
92  std::string Pid =
93 #if LLVM_ON_UNIX
94  llvm::to_string(::getpid());
95 #elif defined(_WIN32)
96  llvm::to_string(::GetCurrentProcessId());
97 #else
98  "";
99 #endif
100 
101  std::string CoverageFilename = (CoveragePrefix + Pid).str();
102 
103  std::error_code EC;
105  std::unique_ptr<ToolOutputFile> CoverageFile =
106  std::make_unique<ToolOutputFile>(CoverageFilename, EC, OpenFlags);
107  if (EC)
108  return false;
109 
110  uint64_t Zero = 0;
111  uint64_t InvZero = ~0ull;
112  CoverageFile->os() << BackendName;
113  CoverageFile->os().write((const char *)&Zero, sizeof(unsigned char));
114  for (uint64_t I : RuleCoverage.set_bits())
115  CoverageFile->os().write((const char *)&I, sizeof(uint64_t));
116  CoverageFile->os().write((const char *)&InvZero, sizeof(uint64_t));
117 
118  CoverageFile->keep();
119  }
120 
121  return true;
122 }
123 
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
Definition: BitVector.h:371
This class represents lattice values for constants.
Definition: AllocatorList.h:23
bool empty() const
empty - Tests whether there are no bits in this bitvector.
Definition: BitVector.h:166
SmartMutex - A mutex with a compile time constant parameter that indicates whether this mutex should ...
Definition: Mutex.h:28
static sys::Mutex Lock
bool parse(MemoryBuffer &Buffer, StringRef BackendName)
bool emit(StringRef FilePrefix, StringRef BackendName) const
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:126
void setCovered(uint64_t RuleID)
static const std::string CoveragePrefix
The file should be opened in append mode.
Definition: FileSystem.h:771
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:41
A range adaptor for a pair of iterators.
std::lock_guard< SmartMutex< mt_only > > SmartScopedLock
Definition: Mutex.h:71
LLVM_NODISCARD bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition: StringRef.h:160
const char * getBufferEnd() const
Definition: MemoryBuffer.h:60
static sys::SmartMutex< true > OutputMutex
iterator_range< const_covered_iterator > covered() const
#define I(x, y, z)
Definition: MD5.cpp:58
bool isCovered(uint64_t RuleID) const
size_type size() const
size - Returns the number of bits in this bitvector.
Definition: BitVector.h:169
const char * getBufferStart() const
Definition: MemoryBuffer.h:59
const std::string to_string(const T &Value)
Definition: ScopedPrinter.h:61
iterator_range< const_set_bits_iterator > set_bits() const
Definition: BitVector.h:129
uint64_t read64(const void *P, endianness E)
Definition: Endian.h:368
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48