xref: /llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h (revision 5c9d82de6b72cc0c037daecce452c450870f0034)
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:
MCJITTestAPICommon()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(HostTriple);
55   }
56 
HostCanBeTargeted()57   bool HostCanBeTargeted() {
58     std::string Error;
59     return TargetRegistry::lookupTarget(HostTriple, Error) != nullptr;
60   }
61 
62   /// Returns true if the host architecture is known to support MCJIT
ArchSupportsMCJIT()63   bool ArchSupportsMCJIT() {
64     Triple Host(HostTriple);
65     // If ARCH is not supported, bail
66     if (!is_contained(SupportedArchs, Host.getArch()))
67       return false;
68 
69     // If ARCH is supported and has no specific sub-arch support
70     if (!is_contained(HasSubArchs, 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(*I))
77         return true;
78 
79     return false;
80   }
81 
82   /// Returns true if the host OS is known to support MCJIT
OSSupportsMCJIT()83   bool OSSupportsMCJIT() {
84     Triple Host(HostTriple);
85 
86     if (find(UnsupportedEnvironments, Host.getEnvironment()) !=
87         UnsupportedEnvironments.end())
88       return false;
89 
90     if (!is_contained(UnsupportedOSs, 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