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