1bf215546Sopenharmony_ci//
2bf215546Sopenharmony_ci// Copyright 2016 Francisco Jerez
3bf215546Sopenharmony_ci//
4bf215546Sopenharmony_ci// Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci// copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci// to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci// and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci// Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci//
11bf215546Sopenharmony_ci// The above copyright notice and this permission notice shall be included in
12bf215546Sopenharmony_ci// all copies or substantial portions of the Software.
13bf215546Sopenharmony_ci//
14bf215546Sopenharmony_ci// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15bf215546Sopenharmony_ci// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16bf215546Sopenharmony_ci// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17bf215546Sopenharmony_ci// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18bf215546Sopenharmony_ci// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19bf215546Sopenharmony_ci// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20bf215546Sopenharmony_ci// OTHER DEALINGS IN THE SOFTWARE.
21bf215546Sopenharmony_ci//
22bf215546Sopenharmony_ci
23bf215546Sopenharmony_ci///
24bf215546Sopenharmony_ci/// \file
25bf215546Sopenharmony_ci/// Some thin wrappers around the Clang/LLVM API used to preserve
26bf215546Sopenharmony_ci/// compatibility with older API versions while keeping the ifdef clutter low
27bf215546Sopenharmony_ci/// in the rest of the clover::llvm subtree.  In case of an API break please
28bf215546Sopenharmony_ci/// consider whether it's possible to preserve backwards compatibility by
29bf215546Sopenharmony_ci/// introducing a new one-liner inline function or typedef here under the
30bf215546Sopenharmony_ci/// compat namespace in order to keep the running code free from preprocessor
31bf215546Sopenharmony_ci/// conditionals.
32bf215546Sopenharmony_ci///
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_ci#ifndef CLOVER_LLVM_COMPAT_HPP
35bf215546Sopenharmony_ci#define CLOVER_LLVM_COMPAT_HPP
36bf215546Sopenharmony_ci
37bf215546Sopenharmony_ci#include "util/algorithm.hpp"
38bf215546Sopenharmony_ci
39bf215546Sopenharmony_ci#include <llvm/Config/llvm-config.h>
40bf215546Sopenharmony_ci
41bf215546Sopenharmony_ci#include <llvm/ADT/Triple.h>
42bf215546Sopenharmony_ci#include <llvm/Analysis/TargetLibraryInfo.h>
43bf215546Sopenharmony_ci#include <llvm/IR/LegacyPassManager.h>
44bf215546Sopenharmony_ci#include <llvm/IR/LLVMContext.h>
45bf215546Sopenharmony_ci#include <llvm/IR/Type.h>
46bf215546Sopenharmony_ci#include <llvm/Linker/Linker.h>
47bf215546Sopenharmony_ci#include <llvm/Target/TargetMachine.h>
48bf215546Sopenharmony_ci#include <llvm/Transforms/IPO.h>
49bf215546Sopenharmony_ci#include <llvm/Transforms/Utils/Cloning.h>
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_ci#include <clang/Basic/TargetInfo.h>
52bf215546Sopenharmony_ci#include <clang/Frontend/CompilerInstance.h>
53bf215546Sopenharmony_ci#include <clang/Lex/PreprocessorOptions.h>
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci#if LLVM_VERSION_MAJOR >= 10
56bf215546Sopenharmony_ci#include <llvm/Support/CodeGen.h>
57bf215546Sopenharmony_ci#endif
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_ci#if LLVM_VERSION_MAJOR >= 14
60bf215546Sopenharmony_ci#include <llvm/MC/TargetRegistry.h>
61bf215546Sopenharmony_ci#else
62bf215546Sopenharmony_ci#include <llvm/Support/TargetRegistry.h>
63bf215546Sopenharmony_ci#endif
64bf215546Sopenharmony_ci
65bf215546Sopenharmony_cinamespace clover {
66bf215546Sopenharmony_ci   namespace llvm {
67bf215546Sopenharmony_ci      namespace compat {
68bf215546Sopenharmony_ci
69bf215546Sopenharmony_ci#if LLVM_VERSION_MAJOR >= 10
70bf215546Sopenharmony_ci         const auto CGFT_ObjectFile = ::llvm::CGFT_ObjectFile;
71bf215546Sopenharmony_ci         const auto CGFT_AssemblyFile = ::llvm::CGFT_AssemblyFile;
72bf215546Sopenharmony_ci         typedef ::llvm::CodeGenFileType CodeGenFileType;
73bf215546Sopenharmony_ci#else
74bf215546Sopenharmony_ci         const auto CGFT_ObjectFile = ::llvm::TargetMachine::CGFT_ObjectFile;
75bf215546Sopenharmony_ci         const auto CGFT_AssemblyFile =
76bf215546Sopenharmony_ci            ::llvm::TargetMachine::CGFT_AssemblyFile;
77bf215546Sopenharmony_ci         typedef ::llvm::TargetMachine::CodeGenFileType CodeGenFileType;
78bf215546Sopenharmony_ci#endif
79bf215546Sopenharmony_ci
80bf215546Sopenharmony_ci#if LLVM_VERSION_MAJOR >= 10
81bf215546Sopenharmony_ci         const clang::InputKind ik_opencl = clang::Language::OpenCL;
82bf215546Sopenharmony_ci#else
83bf215546Sopenharmony_ci         const clang::InputKind ik_opencl = clang::InputKind::OpenCL;
84bf215546Sopenharmony_ci#endif
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_ci         template<typename T> inline bool
87bf215546Sopenharmony_ci         create_compiler_invocation_from_args(clang::CompilerInvocation &cinv,
88bf215546Sopenharmony_ci                                              T copts,
89bf215546Sopenharmony_ci                                              clang::DiagnosticsEngine &diag)
90bf215546Sopenharmony_ci         {
91bf215546Sopenharmony_ci#if LLVM_VERSION_MAJOR >= 10
92bf215546Sopenharmony_ci            return clang::CompilerInvocation::CreateFromArgs(
93bf215546Sopenharmony_ci               cinv, copts, diag);
94bf215546Sopenharmony_ci#else
95bf215546Sopenharmony_ci            return clang::CompilerInvocation::CreateFromArgs(
96bf215546Sopenharmony_ci               cinv, copts.data(), copts.data() + copts.size(), diag);
97bf215546Sopenharmony_ci#endif
98bf215546Sopenharmony_ci         }
99bf215546Sopenharmony_ci
100bf215546Sopenharmony_ci         static inline void
101bf215546Sopenharmony_ci         compiler_set_lang_defaults(std::unique_ptr<clang::CompilerInstance> &c,
102bf215546Sopenharmony_ci                                    clang::InputKind ik, const ::llvm::Triple& triple,
103bf215546Sopenharmony_ci                                    clang::LangStandard::Kind d)
104bf215546Sopenharmony_ci         {
105bf215546Sopenharmony_ci#if LLVM_VERSION_MAJOR >= 15
106bf215546Sopenharmony_ci            c->getLangOpts().setLangDefaults(c->getLangOpts(), ik.getLanguage(), triple,
107bf215546Sopenharmony_ci#else
108bf215546Sopenharmony_ci            c->getInvocation().setLangDefaults(c->getLangOpts(), ik, triple,
109bf215546Sopenharmony_ci#endif
110bf215546Sopenharmony_ci#if LLVM_VERSION_MAJOR >= 12
111bf215546Sopenharmony_ci                                               c->getPreprocessorOpts().Includes,
112bf215546Sopenharmony_ci#else
113bf215546Sopenharmony_ci                                               c->getPreprocessorOpts(),
114bf215546Sopenharmony_ci#endif
115bf215546Sopenharmony_ci                                               d);
116bf215546Sopenharmony_ci         }
117bf215546Sopenharmony_ci
118bf215546Sopenharmony_ci         static inline bool
119bf215546Sopenharmony_ci         is_scalable_vector(const ::llvm::Type *type)
120bf215546Sopenharmony_ci         {
121bf215546Sopenharmony_ci#if LLVM_VERSION_MAJOR >= 11
122bf215546Sopenharmony_ci            return ::llvm::isa<::llvm::ScalableVectorType>(type);
123bf215546Sopenharmony_ci#else
124bf215546Sopenharmony_ci            return false;
125bf215546Sopenharmony_ci#endif
126bf215546Sopenharmony_ci         }
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_ci         static inline bool
129bf215546Sopenharmony_ci         is_fixed_vector(const ::llvm::Type *type)
130bf215546Sopenharmony_ci         {
131bf215546Sopenharmony_ci#if LLVM_VERSION_MAJOR >= 11
132bf215546Sopenharmony_ci            return ::llvm::isa<::llvm::FixedVectorType>(type);
133bf215546Sopenharmony_ci#else
134bf215546Sopenharmony_ci            return type->isVectorTy();
135bf215546Sopenharmony_ci#endif
136bf215546Sopenharmony_ci         }
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ci         static inline unsigned
139bf215546Sopenharmony_ci         get_fixed_vector_elements(const ::llvm::Type *type)
140bf215546Sopenharmony_ci         {
141bf215546Sopenharmony_ci#if LLVM_VERSION_MAJOR >= 11
142bf215546Sopenharmony_ci            return ::llvm::cast<::llvm::FixedVectorType>(type)->getNumElements();
143bf215546Sopenharmony_ci#else
144bf215546Sopenharmony_ci            return ((::llvm::VectorType*)type)->getNumElements();
145bf215546Sopenharmony_ci#endif
146bf215546Sopenharmony_ci         }
147bf215546Sopenharmony_ci      }
148bf215546Sopenharmony_ci   }
149bf215546Sopenharmony_ci}
150bf215546Sopenharmony_ci
151bf215546Sopenharmony_ci#endif
152