1//===- MCJITTestBase.h - Common base class for MCJIT Unit tests  ----------===//
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// This class implements functionality shared by both MCJIT C API tests, and
11// the C++ API tests.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_UNITTESTS_EXECUTIONENGINE_MCJIT_MCJITTESTAPICOMMON_H
16#define LLVM_UNITTESTS_EXECUTIONENGINE_MCJIT_MCJITTESTAPICOMMON_H
17
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/ADT/Triple.h"
20#include "llvm/IR/LegacyPassManager.h"
21#include "llvm/InitializePasses.h"
22#include "llvm/Support/Host.h"
23#include "llvm/Support/TargetSelect.h"
24
25// Used to skip tests on unsupported architectures and operating systems.
26// To skip a test, add this macro at the top of a test-case in a suite that
27// inherits from MCJITTestBase. See MCJITTest.cpp for examples.
28#define SKIP_UNSUPPORTED_PLATFORM \
29  do \
30    if (!ArchSupportsMCJIT() || !OSSupportsMCJIT()) \
31      return; \
32  while(0)
33
34namespace llvm {
35
36class MCJITTestAPICommon {
37protected:
38  MCJITTestAPICommon()
39    : HostTriple(sys::getProcessTriple())
40  {
41    InitializeNativeTarget();
42    InitializeNativeTargetAsmPrinter();
43
44    // FIXME: It isn't at all clear why this is necesasry, but without it we
45    // fail to initialize the AssumptionCacheTracker.
46    initializeAssumptionCacheTrackerPass(*PassRegistry::getPassRegistry());
47
48#ifdef LLVM_ON_WIN32
49    // On Windows, generate ELF objects by specifying "-elf" in triple
50    HostTriple += "-elf";
51#endif // LLVM_ON_WIN32
52    HostTriple = Triple::normalize(HostTriple);
53  }
54
55  /// Returns true if the host architecture is known to support MCJIT
56  bool ArchSupportsMCJIT() {
57    Triple Host(HostTriple);
58    // If ARCH is not supported, bail
59    if (std::find(SupportedArchs.begin(), SupportedArchs.end(), Host.getArch())
60        == SupportedArchs.end())
61      return false;
62
63    // If ARCH is supported and has no specific sub-arch support
64    if (std::find(HasSubArchs.begin(), HasSubArchs.end(), Host.getArch())
65        == HasSubArchs.end())
66      return true;
67
68    // If ARCH has sub-arch support, find it
69    SmallVectorImpl<std::string>::const_iterator I = SupportedSubArchs.begin();
70    for(; I != SupportedSubArchs.end(); ++I)
71      if (Host.getArchName().startswith(I->c_str()))
72        return true;
73
74    return false;
75  }
76
77  /// Returns true if the host OS is known to support MCJIT
78  bool OSSupportsMCJIT() {
79    Triple Host(HostTriple);
80
81    if (std::find(UnsupportedEnvironments.begin(), UnsupportedEnvironments.end(),
82                  Host.getEnvironment()) != UnsupportedEnvironments.end())
83      return false;
84
85    if (std::find(UnsupportedOSs.begin(), UnsupportedOSs.end(), Host.getOS())
86        == UnsupportedOSs.end())
87      return true;
88
89    return false;
90  }
91
92  std::string HostTriple;
93  SmallVector<Triple::ArchType, 4> SupportedArchs;
94  SmallVector<Triple::ArchType, 1> HasSubArchs;
95  SmallVector<std::string, 2> SupportedSubArchs; // We need to own the memory
96  SmallVector<Triple::OSType, 4> UnsupportedOSs;
97  SmallVector<Triple::EnvironmentType, 1> UnsupportedEnvironments;
98};
99
100} // namespace llvm
101
102#endif
103
104