File: SILCoverageMap.cpp

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (107 lines) | stat: -rw-r--r-- 3,888 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//===--- SILCoverageMap.cpp - Defines the SILCoverageMap class ------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the SILCoverageMap class, which is used to relay coverage
// mapping information from the AST to lower layers of the compiler.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/STLExtras.h"
#include "swift/SIL/SILCoverageMap.h"
#include "swift/SIL/SILModule.h"

using namespace swift;

using llvm::coverage::CounterExpression;
using llvm::coverage::CounterMappingRegion;

SILCoverageMap *
SILCoverageMap::create(SILModule &M, SourceFile *ParentSourceFile,
                       StringRef Filename, StringRef Name,
                       StringRef PGOFuncName, uint64_t Hash,
                       ArrayRef<MappedRegion> MappedRegions,
                       ArrayRef<CounterExpression> Expressions) {
  auto *Buf = M.allocate<SILCoverageMap>(1);
  SILCoverageMap *CM = ::new (Buf) SILCoverageMap(ParentSourceFile, Hash);

  // Store a copy of the names so that we own the lifetime.
  CM->Filename = M.allocateCopy(Filename);
  CM->Name = M.allocateCopy(Name);
  CM->PGOFuncName = M.allocateCopy(PGOFuncName).str();

  // Since we have two arrays, we need to manually tail allocate each of them,
  // rather than relying on the flexible array trick.
  CM->MappedRegions = M.allocateCopy(MappedRegions);
  CM->Expressions = M.allocateCopy(Expressions);

  auto result = M.coverageMaps.insert({CM->PGOFuncName, CM});

  // Assert that this coverage map is unique.
  assert(result.second && "Duplicate coverage mapping for function");
  (void)result;

  return CM;
}

SILCoverageMap::SILCoverageMap(SourceFile *ParentSourceFile, uint64_t Hash)
  : ParentSourceFile(ParentSourceFile), Hash(Hash) {}

SILCoverageMap::~SILCoverageMap() {}

CounterMappingRegion
SILCoverageMap::MappedRegion::getLLVMRegion(unsigned int FileID) const {
  switch (RegionKind) {
  case MappedRegion::Kind::Code:
    return CounterMappingRegion::makeRegion(Counter, FileID, StartLine,
                                            StartCol, EndLine, EndCol);
  case MappedRegion::Kind::Skipped:
    return CounterMappingRegion::makeSkipped(FileID, StartLine, StartCol,
                                             EndLine, EndCol);
  }
  llvm_unreachable("Unhandled case in switch!");
}

namespace {
struct Printer {
  const llvm::coverage::Counter &C;
  ArrayRef<llvm::coverage::CounterExpression> Exprs;
  Printer(const llvm::coverage::Counter &C,
          ArrayRef<llvm::coverage::CounterExpression> Exprs)
      : C(C), Exprs(Exprs) {}

  void print(raw_ostream &OS) const {
    // TODO: This format's nice and human readable, but does it fit well with
    // SIL's relatively simple structure?
    if (C.isZero())
      OS << "zero";
    else if (C.isExpression()) {
      assert(C.getExpressionID() < Exprs.size() && "expression out of range");
      const auto &E = Exprs[C.getExpressionID()];
      OS << '(' << Printer(E.LHS, Exprs)
         << (E.Kind == CounterExpression::Add ? " + " : " - ")
         << Printer(E.RHS, Exprs) << ')';
    } else
      OS << C.getCounterID();
  }

  friend raw_ostream &operator<<(raw_ostream &OS, const Printer &P) {
    P.print(OS);
    return OS;
  }
};
} // end anonymous namespace

void SILCoverageMap::printCounter(
    llvm::raw_ostream &OS, llvm::coverage::Counter C,
    ArrayRef<llvm::coverage::CounterExpression> Expressions) {
  OS << Printer(C, Expressions);
}