LCOV - code coverage report
Current view: top level - lib/Support - TargetRegistry.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 35 53 66.0 %
Date: 2018-10-20 13:21:21 Functions: 4 6 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       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      292565 : iterator_range<TargetRegistry::iterator> TargetRegistry::targets() {
      22      292565 :   return make_range(iterator(FirstTarget), iterator());
      23             : }
      24             : 
      25       35353 : const Target *TargetRegistry::lookupTarget(const std::string &ArchName,
      26             :                                            Triple &TheTriple,
      27             :                                            std::string &Error) {
      28             :   // Allocate target machine.  First, check whether the user has explicitly
      29             :   // specified an architecture to compile for. If so we have to look it up by
      30             :   // name, because it might be a backend that has no mapping to a target triple.
      31             :   const Target *TheTarget = nullptr;
      32       35353 :   if (!ArchName.empty()) {
      33       11678 :     auto I = find_if(targets(),
      34      137350 :                      [&](const Target &T) { return ArchName == T.getName(); });
      35             : 
      36        5839 :     if (I == targets().end()) {
      37           6 :       Error = "error: invalid target '" + ArchName + "'.\n";
      38             :       return nullptr;
      39             :     }
      40             : 
      41             :     TheTarget = &*I;
      42             : 
      43             :     // Adjust the triple to match (if known), otherwise stick with the
      44             :     // given triple.
      45        5836 :     Triple::ArchType Type = Triple::getArchTypeForLLVMName(ArchName);
      46        5836 :     if (Type != Triple::UnknownArch)
      47        5836 :       TheTriple.setArch(Type);
      48             :   } else {
      49             :     // Get the target specific parser.
      50             :     std::string TempError;
      51       29514 :     TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), TempError);
      52       29514 :     if (!TheTarget) {
      53             :       Error = ": error: unable to get target for '"
      54          22 :             + TheTriple.getTriple()
      55          22 :             + "', see --version and --triple.\n";
      56             :       return nullptr;
      57             :     }
      58             :   }
      59             : 
      60             :   return TheTarget;
      61             : }
      62             : 
      63       46876 : const Target *TargetRegistry::lookupTarget(const std::string &TT,
      64             :                                            std::string &Error) {
      65             :   // Provide special warning when no targets are initialized.
      66       46876 :   if (targets().begin() == targets().end()) {
      67             :     Error = "Unable to find target for this triple (no targets are registered)";
      68          39 :     return nullptr;
      69             :   }
      70       46837 :   Triple::ArchType Arch = Triple(TT).getArch();
      71     1582574 :   auto ArchMatch = [&](const Target &T) { return T.ArchMatchFn(Arch); };
      72       46837 :   auto I = find_if(targets(), ArchMatch);
      73             : 
      74       46837 :   if (I == targets().end()) {
      75         218 :     Error = "No available targets are compatible with triple \"" + TT + "\"";
      76         109 :     return nullptr;
      77             :   }
      78             : 
      79       46728 :   auto J = std::find_if(std::next(I), targets().end(), ArchMatch);
      80       46728 :   if (J != targets().end()) {
      81           0 :     Error = std::string("Cannot choose between targets \"") + I->Name +
      82           0 :             "\" and \"" + J->Name + "\"";
      83           0 :     return nullptr;
      84             :   }
      85             : 
      86             :   return &*I;
      87             : }
      88             : 
      89     4348372 : void TargetRegistry::RegisterTarget(Target &T, const char *Name,
      90             :                                     const char *ShortDesc,
      91             :                                     const char *BackendName,
      92             :                                     Target::ArchMatchFnTy ArchMatchFn,
      93             :                                     bool HasJIT) {
      94             :   assert(Name && ShortDesc && ArchMatchFn &&
      95             :          "Missing required target information!");
      96             : 
      97             :   // Check if this target has already been initialized, we allow this as a
      98             :   // convenience to some clients.
      99     4348372 :   if (T.Name)
     100             :     return;
     101             : 
     102             :   // Add to the list of targets.
     103     3341462 :   T.Next = FirstTarget;
     104     3341462 :   FirstTarget = &T;
     105             : 
     106     3341462 :   T.Name = Name;
     107     3341462 :   T.ShortDesc = ShortDesc;
     108     3341462 :   T.BackendName = BackendName;
     109     3341462 :   T.ArchMatchFn = ArchMatchFn;
     110     3341462 :   T.HasJIT = HasJIT;
     111             : }
     112             : 
     113           0 : static int TargetArraySortFn(const std::pair<StringRef, const Target *> *LHS,
     114             :                              const std::pair<StringRef, const Target *> *RHS) {
     115           0 :   return LHS->first.compare(RHS->first);
     116             : }
     117             : 
     118           0 : void TargetRegistry::printRegisteredTargetsForVersion(raw_ostream &OS) {
     119             :   std::vector<std::pair<StringRef, const Target*> > Targets;
     120           0 :   size_t Width = 0;
     121           0 :   for (const auto &T : TargetRegistry::targets()) {
     122           0 :     Targets.push_back(std::make_pair(T.getName(), &T));
     123           0 :     Width = std::max(Width, Targets.back().first.size());
     124             :   }
     125             :   array_pod_sort(Targets.begin(), Targets.end(), TargetArraySortFn);
     126             : 
     127           0 :   OS << "  Registered Targets:\n";
     128           0 :   for (unsigned i = 0, e = Targets.size(); i != e; ++i) {
     129           0 :     OS << "    " << Targets[i].first;
     130           0 :     OS.indent(Width - Targets[i].first.size()) << " - "
     131           0 :       << Targets[i].second->getShortDescription() << '\n';
     132             :   }
     133           0 :   if (Targets.empty())
     134           0 :     OS << "    (none)\n";
     135           0 : }

Generated by: LCOV version 1.13