Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Support/TargetRegistry.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- TargetRegistry.cpp - Target registration -------------------------===//
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
#include "llvm/Support/TargetRegistry.h"
11
#include "llvm/ADT/STLExtras.h"
12
#include "llvm/ADT/StringRef.h"
13
#include "llvm/Support/raw_ostream.h"
14
#include <cassert>
15
#include <vector>
16
using namespace llvm;
17
18
// Clients are responsible for avoid race conditions in registration.
19
static Target *FirstTarget = nullptr;
20
21
278k
iterator_range<TargetRegistry::iterator> TargetRegistry::targets() {
22
278k
  return make_range(iterator(FirstTarget), iterator());
23
278k
}
24
25
const Target *TargetRegistry::lookupTarget(const std::string &ArchName,
26
                                           Triple &TheTriple,
27
25.1k
                                           std::string &Error) {
28
25.1k
  // Allocate target machine.  First, check whether the user has explicitly
29
25.1k
  // specified an architecture to compile for. If so we have to look it up by
30
25.1k
  // name, because it might be a backend that has no mapping to a target triple.
31
25.1k
  const Target *TheTarget = nullptr;
32
25.1k
  if (
!ArchName.empty()25.1k
) {
33
4.79k
    auto I = find_if(targets(),
34
92.3k
                     [&](const Target &T) { return ArchName == T.getName(); });
35
4.79k
36
4.79k
    if (
I == targets().end()4.79k
) {
37
3
      Error = "error: invalid target '" + ArchName + "'.\n";
38
3
      return nullptr;
39
3
    }
40
4.79k
41
4.79k
    TheTarget = &*I;
42
4.79k
43
4.79k
    // Adjust the triple to match (if known), otherwise stick with the
44
4.79k
    // given triple.
45
4.79k
    Triple::ArchType Type = Triple::getArchTypeForLLVMName(ArchName);
46
4.79k
    if (Type != Triple::UnknownArch)
47
4.79k
      TheTriple.setArch(Type);
48
25.1k
  } else {
49
20.3k
    // Get the target specific parser.
50
20.3k
    std::string TempError;
51
20.3k
    TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), TempError);
52
20.3k
    if (
!TheTarget20.3k
) {
53
14
      Error = ": error: unable to get target for '"
54
14
            + TheTriple.getTriple()
55
14
            + "', see --version and --triple.\n";
56
14
      return nullptr;
57
14
    }
58
25.1k
  }
59
25.1k
60
25.1k
  return TheTarget;
61
25.1k
}
62
63
const Target *TargetRegistry::lookupTarget(const std::string &TT,
64
44.8k
                                           std::string &Error) {
65
44.8k
  // Provide special warning when no targets are initialized.
66
44.8k
  if (
targets().begin() == targets().end()44.8k
) {
67
30
    Error = "Unable to find target for this triple (no targets are registered)";
68
30
    return nullptr;
69
30
  }
70
44.8k
  Triple::ArchType Arch = Triple(TT).getArch();
71
1.38M
  auto ArchMatch = [&](const Target &T) { return T.ArchMatchFn(Arch); };
72
44.8k
  auto I = find_if(targets(), ArchMatch);
73
44.8k
74
44.8k
  if (
I == targets().end()44.8k
) {
75
117
    Error = "No available targets are compatible with this triple.";
76
117
    return nullptr;
77
117
  }
78
44.6k
79
44.6k
  auto J = std::find_if(std::next(I), targets().end(), ArchMatch);
80
44.6k
  if (
J != targets().end()44.6k
) {
81
0
    Error = std::string("Cannot choose between targets \"") + I->Name +
82
0
            "\" and \"" + J->Name + "\"";
83
0
    return nullptr;
84
0
  }
85
44.6k
86
44.6k
  return &*I;
87
44.6k
}
88
89
void TargetRegistry::RegisterTarget(Target &T,
90
                                    const char *Name,
91
                                    const char *ShortDesc,
92
                                    Target::ArchMatchFnTy ArchMatchFn,
93
4.10M
                                    bool HasJIT) {
94
4.10M
  assert(Name && ShortDesc && ArchMatchFn &&
95
4.10M
         "Missing required target information!");
96
4.10M
97
4.10M
  // Check if this target has already been initialized, we allow this as a
98
4.10M
  // convenience to some clients.
99
4.10M
  if (T.Name)
100
1.08M
    return;
101
3.02M
         
102
3.02M
  // Add to the list of targets.
103
3.02M
  T.Next = FirstTarget;
104
3.02M
  FirstTarget = &T;
105
3.02M
106
3.02M
  T.Name = Name;
107
3.02M
  T.ShortDesc = ShortDesc;
108
3.02M
  T.ArchMatchFn = ArchMatchFn;
109
3.02M
  T.HasJIT = HasJIT;
110
3.02M
}
111
112
static int TargetArraySortFn(const std::pair<StringRef, const Target *> *LHS,
113
0
                             const std::pair<StringRef, const Target *> *RHS) {
114
0
  return LHS->first.compare(RHS->first);
115
0
}
116
117
0
void TargetRegistry::printRegisteredTargetsForVersion(raw_ostream &OS) {
118
0
  std::vector<std::pair<StringRef, const Target*> > Targets;
119
0
  size_t Width = 0;
120
0
  for (const auto &T : TargetRegistry::targets()) {
121
0
    Targets.push_back(std::make_pair(T.getName(), &T));
122
0
    Width = std::max(Width, Targets.back().first.size());
123
0
  }
124
0
  array_pod_sort(Targets.begin(), Targets.end(), TargetArraySortFn);
125
0
126
0
  OS << "  Registered Targets:\n";
127
0
  for (unsigned i = 0, e = Targets.size(); 
i != e0
;
++i0
) {
128
0
    OS << "    " << Targets[i].first;
129
0
    OS.indent(Width - Targets[i].first.size()) << " - "
130
0
      << Targets[i].second->getShortDescription() << '\n';
131
0
  }
132
0
  if (Targets.empty())
133
0
    OS << "    (none)\n";
134
0
}