1// Copyright 2016 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_Nucleus_hpp
16#define rr_Nucleus_hpp
17
18#include <atomic>
19#include <cassert>
20#include <cstdarg>
21#include <cstdint>
22#include <functional>
23#include <memory>
24#include <string>
25#include <vector>
26
27#ifdef None
28# undef None // TODO(b/127920555)
29#endif
30
31static_assert(sizeof(short) == 2, "Reactor's 'Short' type is 16-bit, and requires the C++ 'short' to match that.");
32static_assert(sizeof(int) == 4, "Reactor's 'Int' type is 32-bit, and requires the C++ 'int' to match that.");
33
34namespace rr {
35
36class Type;
37class Value;
38class SwitchCases;
39class BasicBlock;
40class Routine;
41
42class Nucleus
43{
44public:
45 Nucleus();
46
47 virtual ~Nucleus();
48
49 std::shared_ptr<Routine> acquireRoutine(const char *name);
50
51 static Value *allocateStackVariable(Type *type, int arraySize = 0);
52 static BasicBlock *createBasicBlock();
53 static BasicBlock *getInsertBlock();
54 static void setInsertBlock(BasicBlock *basicBlock);
55
56 static void createFunction(Type *returnType, const std::vector<Type *> &paramTypes);
57 static Value *getArgument(unsigned int index);
58
59 // Coroutines
60 using CoroutineHandle = void *;
61
62 template<typename... ARGS>
63 using CoroutineBegin = CoroutineHandle(ARGS...);
64 using CoroutineAwait = bool(CoroutineHandle, void *yieldValue);
65 using CoroutineDestroy = void(CoroutineHandle);
66
67 enum CoroutineEntries
68 {
69 CoroutineEntryBegin = 0,
70 CoroutineEntryAwait,
71 CoroutineEntryDestroy,
72 CoroutineEntryCount
73 };
74
75 // Begins the generation of the three coroutine functions: CoroutineBegin, CoroutineAwait, and CoroutineDestroy,
76 // which will be returned by Routine::getEntry() with arg CoroutineEntryBegin, CoroutineEntryAwait, and CoroutineEntryDestroy
77 // respectively. Called by Coroutine constructor.
78 // Params are used to generate the params to CoroutineBegin, while ReturnType is used as the YieldType for the coroutine,
79 // returned via CoroutineAwait..
80 static void createCoroutine(Type *returnType, const std::vector<Type *> &params);
81 // Generates code to store the passed in value, and to suspend execution of the coroutine, such that the next call to
82 // CoroutineAwait can set the output yieldValue and resume execution of the coroutine.
83 static void yield(Value *val);
84 // Called to finalize coroutine creation. After this call, Routine::getEntry can be called to retrieve the entry point to any
85 // of the three coroutine functions. Called by Coroutine::finalize.
86 std::shared_ptr<Routine> acquireCoroutine(const char *name);
87 // Called by Coroutine::operator() to execute CoroutineEntryBegin wrapped up in func. This is needed in case
88 // the call must be run on a separate thread of execution (e.g. on a fiber).
89 static CoroutineHandle invokeCoroutineBegin(Routine &routine, std::function<CoroutineHandle()> func);
90
91 // Terminators
92 static void createRetVoid();
93 static void createRet(Value *V);
94 static void createBr(BasicBlock *dest);
95 static void createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse);
96
97 // Binary operators
98 static Value *createAdd(Value *lhs, Value *rhs);
99 static Value *createSub(Value *lhs, Value *rhs);
100 static Value *createMul(Value *lhs, Value *rhs);
101 static Value *createUDiv(Value *lhs, Value *rhs);
102 static Value *createSDiv(Value *lhs, Value *rhs);
103 static Value *createFAdd(Value *lhs, Value *rhs);
104 static Value *createFSub(Value *lhs, Value *rhs);
105 static Value *createFMul(Value *lhs, Value *rhs);
106 static Value *createFDiv(Value *lhs, Value *rhs);
107 static Value *createURem(Value *lhs, Value *rhs);
108 static Value *createSRem(Value *lhs, Value *rhs);
109 static Value *createFRem(Value *lhs, Value *rhs);
110 static Value *createShl(Value *lhs, Value *rhs);
111 static Value *createLShr(Value *lhs, Value *rhs);
112 static Value *createAShr(Value *lhs, Value *rhs);
113 static Value *createAnd(Value *lhs, Value *rhs);
114 static Value *createOr(Value *lhs, Value *rhs);
115 static Value *createXor(Value *lhs, Value *rhs);
116
117 // Unary operators
118 static Value *createNeg(Value *V);
119 static Value *createFNeg(Value *V);
120 static Value *createNot(Value *V);
121
122 // Memory instructions
123 static Value *createLoad(Value *ptr, Type *type, bool isVolatile = false, unsigned int alignment = 0, bool atomic = false, std::memory_order memoryOrder = std::memory_order_relaxed);
124 static Value *createStore(Value *value, Value *ptr, Type *type, bool isVolatile = false, unsigned int aligment = 0, bool atomic = false, std::memory_order memoryOrder = std::memory_order_relaxed);
125 static Value *createGEP(Value *ptr, Type *type, Value *index, bool unsignedIndex);
126
127 // Masked Load / Store instructions
128 static Value *createMaskedLoad(Value *base, Type *elementType, Value *mask, unsigned int alignment, bool zeroMaskedLanes);
129 static void createMaskedStore(Value *base, Value *value, Value *mask, unsigned int alignment);
130
131 // Barrier instructions
132 static void createFence(std::memory_order memoryOrder);
133
134 // Atomic instructions
135 static Value *createAtomicAdd(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed);
136 static Value *createAtomicSub(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed);
137 static Value *createAtomicAnd(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed);
138 static Value *createAtomicOr(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed);
139 static Value *createAtomicXor(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed);
140 static Value *createAtomicMin(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed);
141 static Value *createAtomicMax(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed);
142 static Value *createAtomicUMin(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed);
143 static Value *createAtomicUMax(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed);
144 static Value *createAtomicExchange(Value *ptr, Value *value, std::memory_order memoryOrder = std::memory_order_relaxed);
145 static Value *createAtomicCompareExchange(Value *ptr, Value *value, Value *compare, std::memory_order memoryOrderEqual, std::memory_order memoryOrderUnequal);
146
147 // Cast/Conversion Operators
148 static Value *createTrunc(Value *V, Type *destType);
149 static Value *createZExt(Value *V, Type *destType);
150 static Value *createSExt(Value *V, Type *destType);
151 static Value *createFPToUI(Value *V, Type *destType);
152 static Value *createFPToSI(Value *V, Type *destType);
153 static Value *createSIToFP(Value *V, Type *destType);
154 static Value *createFPTrunc(Value *V, Type *destType);
155 static Value *createFPExt(Value *V, Type *destType);
156 static Value *createBitCast(Value *V, Type *destType);
157
158 // Compare instructions
159 static Value *createICmpEQ(Value *lhs, Value *rhs);
160 static Value *createICmpNE(Value *lhs, Value *rhs);
161 static Value *createICmpUGT(Value *lhs, Value *rhs);
162 static Value *createICmpUGE(Value *lhs, Value *rhs);
163 static Value *createICmpULT(Value *lhs, Value *rhs);
164 static Value *createICmpULE(Value *lhs, Value *rhs);
165 static Value *createICmpSGT(Value *lhs, Value *rhs);
166 static Value *createICmpSGE(Value *lhs, Value *rhs);
167 static Value *createICmpSLT(Value *lhs, Value *rhs);
168 static Value *createICmpSLE(Value *lhs, Value *rhs);
169 static Value *createFCmpOEQ(Value *lhs, Value *rhs);
170 static Value *createFCmpOGT(Value *lhs, Value *rhs);
171 static Value *createFCmpOGE(Value *lhs, Value *rhs);
172 static Value *createFCmpOLT(Value *lhs, Value *rhs);
173 static Value *createFCmpOLE(Value *lhs, Value *rhs);
174 static Value *createFCmpONE(Value *lhs, Value *rhs);
175 static Value *createFCmpORD(Value *lhs, Value *rhs);
176 static Value *createFCmpUNO(Value *lhs, Value *rhs);
177 static Value *createFCmpUEQ(Value *lhs, Value *rhs);
178 static Value *createFCmpUGT(Value *lhs, Value *rhs);
179 static Value *createFCmpUGE(Value *lhs, Value *rhs);
180 static Value *createFCmpULT(Value *lhs, Value *rhs);
181 static Value *createFCmpULE(Value *lhs, Value *rhs);
182 static Value *createFCmpUNE(Value *lhs, Value *rhs);
183
184 // Vector instructions
185 static Value *createExtractElement(Value *vector, Type *type, int index);
186 static Value *createInsertElement(Value *vector, Value *element, int index);
187 static Value *createShuffleVector(Value *V1, Value *V2, std::vector<int> select);
188
189 // Other instructions
190 static Value *createSelect(Value *C, Value *ifTrue, Value *ifFalse);
191 static SwitchCases *createSwitch(Value *control, BasicBlock *defaultBranch, unsigned numCases);
192 static void addSwitchCase(SwitchCases *switchCases, int label, BasicBlock *branch);
193 static void createUnreachable();
194
195 // Constant values
196 static Value *createNullValue(Type *type);
197 static Value *createConstantLong(int64_t i);
198 static Value *createConstantInt(int i);
199 static Value *createConstantInt(unsigned int i);
200 static Value *createConstantBool(bool b);
201 static Value *createConstantByte(signed char i);
202 static Value *createConstantByte(unsigned char i);
203 static Value *createConstantShort(short i);
204 static Value *createConstantShort(unsigned short i);
205 static Value *createConstantFloat(float x);
206 static Value *createNullPointer(Type *type);
207 static Value *createConstantVector(std::vector<int64_t> constants, Type *type);
208 static Value *createConstantVector(std::vector<double> constants, Type *type);
209 static Value *createConstantString(const char *v);
210 static Value *createConstantString(const std::string &v) { return createConstantString(v: v.c_str()); }
211
212 static Type *getType(Value *value);
213 static Type *getContainedType(Type *vectorType);
214 static Type *getPointerType(Type *elementType);
215 static Type *getPrintfStorageType(Type *valueType);
216
217 // Diagnostic utilities
218 struct OptimizerReport
219 {
220 int allocas = 0;
221 int loads = 0;
222 int stores = 0;
223 };
224
225 using OptimizerCallback = void(const OptimizerReport *report);
226
227 // Sets the callback to be used by the next optimizer invocation (during acquireRoutine),
228 // for reporting stats about the resulting IR code. For testing only.
229 static void setOptimizerCallback(OptimizerCallback *callback);
230};
231
232} // namespace rr
233
234#endif // rr_Nucleus_hpp
235

Provided by KDAB

Privacy Policy
Learn more about Flutter for embedded and desktop on industrialflutter.com

source code of flutter_engine/third_party/swiftshader/src/Reactor/Nucleus.hpp