blob: 19b9040282e3684eecf5a8a8efd2c6f7cacd9c8f [file] [log] [blame]
Ben Claytonac07ed82019-03-26 14:17:41 +00001// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef rr_LLVMReactor_hpp
16#define rr_LLVMReactor_hpp
17
Nicolas Capens41a73022020-01-30 00:30:14 -050018#include "Nucleus.hpp"
Nicolas Capens157ba262019-12-10 17:49:14 -050019
Nicolas Capens41a73022020-01-30 00:30:14 -050020#include "Debug.hpp"
21#include "LLVMReactorDebugInfo.hpp"
22#include "Print.hpp"
23
24#ifdef _MSC_VER
25__pragma(warning(push))
26 __pragma(warning(disable : 4146)) // unary minus operator applied to unsigned type, result still unsigned
27#endif
28
29#include "llvm/IR/IRBuilder.h"
30#include "llvm/IR/LLVMContext.h"
31
32#ifdef _MSC_VER
33 __pragma(warning(pop))
34#endif
35
36#include <memory>
37
38 namespace llvm
39{
40
41 class Type;
42 class Value;
Nicolas Capens157ba262019-12-10 17:49:14 -050043
44} // namespace llvm
45
46namespace rr {
47
48class Type;
49class Value;
50
51llvm::Type *T(Type *t);
52
53inline Type *T(llvm::Type *t)
Ben Claytonac07ed82019-03-26 14:17:41 +000054{
Ben Clayton713b8d32019-12-17 20:37:56 +000055 return reinterpret_cast<Type *>(t);
Ben Claytonac07ed82019-03-26 14:17:41 +000056}
57
Nicolas Capens157ba262019-12-10 17:49:14 -050058inline llvm::Value *V(Value *t)
Ben Claytonac07ed82019-03-26 14:17:41 +000059{
Ben Clayton713b8d32019-12-17 20:37:56 +000060 return reinterpret_cast<llvm::Value *>(t);
Ben Claytonac07ed82019-03-26 14:17:41 +000061}
62
Nicolas Capens157ba262019-12-10 17:49:14 -050063inline Value *V(llvm::Value *t)
64{
Ben Clayton713b8d32019-12-17 20:37:56 +000065 return reinterpret_cast<Value *>(t);
Nicolas Capens157ba262019-12-10 17:49:14 -050066}
67
Antonio Maiorano62427e02020-02-13 09:18:05 -050068inline std::vector<llvm::Value *> V(const std::vector<Value *> &values)
69{
70 std::vector<llvm::Value *> result;
71 result.reserve(values.size());
72 for(auto &v : values)
73 {
74 result.push_back(V(v));
75 }
76 return result;
77}
78
Nicolas Capens157ba262019-12-10 17:49:14 -050079// Emits a no-op instruction that will not be optimized away.
80// Useful for emitting something that can have a source location without
81// effect.
82void Nop();
83
Nicolas Capens41a73022020-01-30 00:30:14 -050084class Routine;
Nicolas Capens41a73022020-01-30 00:30:14 -050085
86// JITBuilder holds all the LLVM state for building routines.
87class JITBuilder
88{
89public:
Nicolas Capens79d4c6c2022-04-22 17:20:26 -040090 JITBuilder();
Nicolas Capens41a73022020-01-30 00:30:14 -050091
Nicolas Capens79d4c6c2022-04-22 17:20:26 -040092 void runPasses();
Nicolas Capens41a73022020-01-30 00:30:14 -050093
Nicolas Capens79d4c6c2022-04-22 17:20:26 -040094 std::shared_ptr<rr::Routine> acquireRoutine(const char *name, llvm::Function **funcs, size_t count);
Nicolas Capens41a73022020-01-30 00:30:14 -050095
Nicolas Capens567e5602021-01-07 23:18:56 -050096 std::unique_ptr<llvm::LLVMContext> context;
Nicolas Capens41a73022020-01-30 00:30:14 -050097 std::unique_ptr<llvm::Module> module;
98 std::unique_ptr<llvm::IRBuilder<>> builder;
99 llvm::Function *function = nullptr;
100
101 struct CoroutineState
102 {
103 llvm::Function *await = nullptr;
104 llvm::Function *destroy = nullptr;
105 llvm::Value *handle = nullptr;
106 llvm::Value *id = nullptr;
107 llvm::Value *promise = nullptr;
108 llvm::Type *yieldType = nullptr;
109 llvm::BasicBlock *entryBlock = nullptr;
110 llvm::BasicBlock *suspendBlock = nullptr;
111 llvm::BasicBlock *endBlock = nullptr;
112 llvm::BasicBlock *destroyBlock = nullptr;
113 };
114 CoroutineState coroutine;
115
116#ifdef ENABLE_RR_DEBUG_INFO
117 std::unique_ptr<rr::DebugInfo> debugInfo;
118#endif
Nicolas Capensdc8cbfa2021-06-10 17:09:50 -0400119
120 bool msanInstrumentation = false;
Nicolas Capens41a73022020-01-30 00:30:14 -0500121};
122
123inline std::memory_order atomicOrdering(llvm::AtomicOrdering memoryOrder)
124{
125 switch(memoryOrder)
126 {
Nicolas Capens112faf42019-12-13 17:32:26 -0500127 case llvm::AtomicOrdering::Monotonic: return std::memory_order_relaxed; // https://llvm.org/docs/Atomics.html#monotonic
128 case llvm::AtomicOrdering::Acquire: return std::memory_order_acquire;
129 case llvm::AtomicOrdering::Release: return std::memory_order_release;
130 case llvm::AtomicOrdering::AcquireRelease: return std::memory_order_acq_rel;
131 case llvm::AtomicOrdering::SequentiallyConsistent: return std::memory_order_seq_cst;
132 default:
133 UNREACHABLE("memoryOrder: %d", int(memoryOrder));
134 return std::memory_order_acq_rel;
Nicolas Capens41a73022020-01-30 00:30:14 -0500135 }
136}
137
138inline llvm::AtomicOrdering atomicOrdering(bool atomic, std::memory_order memoryOrder)
139{
140 if(!atomic)
141 {
142 return llvm::AtomicOrdering::NotAtomic;
143 }
144
145 switch(memoryOrder)
146 {
Nicolas Capens112faf42019-12-13 17:32:26 -0500147 case std::memory_order_relaxed: return llvm::AtomicOrdering::Monotonic; // https://llvm.org/docs/Atomics.html#monotonic
148 case std::memory_order_consume: return llvm::AtomicOrdering::Acquire; // https://llvm.org/docs/Atomics.html#acquire: "It should also be used for C++11/C11 memory_order_consume."
149 case std::memory_order_acquire: return llvm::AtomicOrdering::Acquire;
150 case std::memory_order_release: return llvm::AtomicOrdering::Release;
151 case std::memory_order_acq_rel: return llvm::AtomicOrdering::AcquireRelease;
152 case std::memory_order_seq_cst: return llvm::AtomicOrdering::SequentiallyConsistent;
153 default:
154 UNREACHABLE("memoryOrder: %d", int(memoryOrder));
155 return llvm::AtomicOrdering::AcquireRelease;
Nicolas Capens41a73022020-01-30 00:30:14 -0500156 }
157}
158
Nicolas Capens157ba262019-12-10 17:49:14 -0500159} // namespace rr
160
Ben Clayton713b8d32019-12-17 20:37:56 +0000161#endif // rr_LLVMReactor_hpp