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