blob: a69d255f119e58ac9d03c4a0eb1fe45317b45aa5 [file] [log] [blame]
Yang Ni4df77d12017-01-31 10:24:36 -08001/*
2 * Copyright 2017, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef MODULE_H
18#define MODULE_H
19
20#include <iostream>
21#include <map>
22#include <vector>
23
24#include "core_defs.h"
25#include "entity.h"
Yang Ni3f30b622017-02-25 20:23:58 -080026#include "instructions.h"
Yang Ni4df77d12017-01-31 10:24:36 -080027#include "stl_util.h"
28#include "types_generated.h"
29#include "visitor.h"
30
31namespace android {
32namespace spirit {
33
34class Builder;
35class AnnotationSection;
36class CapabilityInst;
37class DebugInfoSection;
38class ExtensionInst;
39class ExtInstImportInst;
40class EntryPointInst;
41class ExecutionModeInst;
42class EntryPointDefinition;
43class FunctionDeclaration;
44class FunctionDefinition;
45class GlobalSection;
46class InputWordStream;
47class Instruction;
48class MemoryModelInst;
49
50union VersionNumber {
51 struct {
52 uint8_t mLowZero;
53 uint8_t mMinorNumber;
54 uint8_t mMajorNumber;
55 uint8_t mHighZero;
56 } mMajorMinor;
57 uint8_t mBytes[4];
58 uint32_t mWord;
59};
60
61class Module : public Entity {
62public:
63 static Module *getCurrentModule();
64 uint32_t nextId() { return mNextId++; }
65
66 Module();
67
68 Module(Builder *b);
69
70 virtual ~Module() {}
71
72 bool DeserializeInternal(InputWordStream &IS) override;
73
74 void Serialize(OutputWordStream &OS) const override;
75
76 void SerializeHeader(OutputWordStream &OS) const;
77
78 void registerId(uint32_t id, Instruction *inst) {
79 mIdTable.insert(std::make_pair(id, inst));
80 }
81
82 void initialize();
83
84 bool resolveIds();
85
86 void accept(IVisitor *v) override {
87 for (auto cap : mCapabilities) {
88 v->visit(cap);
89 }
90 for (auto ext : mExtensions) {
91 v->visit(ext);
92 }
93 for (auto imp : mExtInstImports) {
94 v->visit(imp);
95 }
96
97 v->visit(mMemoryModel.get());
98
99 for (auto entry : mEntryPoints) {
100 v->visit(entry);
101 }
102
103 for (auto mode : mExecutionModes) {
104 v->visit(mode);
105 }
106
107 v->visit(mDebugInfo.get());
108 if (mAnnotations) {
109 v->visit(mAnnotations.get());
110 }
111 if (mGlobals) {
112 v->visit(mGlobals.get());
113 }
114
115 for (auto def : mFunctionDefinitions) {
116 v->visit(def);
117 }
118 }
119
120 static std::ostream &errs() { return std::cerr; }
121
122 Module *addCapability(Capability cap);
123 Module *setMemoryModel(AddressingModel am, MemoryModel mm);
124 Module *addExtInstImport(const char *extName);
125 Module *addSource(SourceLanguage lang, int version);
126 Module *addSourceExtension(const char *ext);
127 Module *addEntryPoint(EntryPointDefinition *entry);
128
129 ExtInstImportInst *getGLExt() const { return mGLExt; }
130
131 GlobalSection *getGlobalSection();
132
133 Instruction *lookupByName(const char *) const;
134 FunctionDefinition *
135 getFunctionDefinitionFromInstruction(FunctionInst *) const;
136 FunctionDefinition *lookupFunctionDefinitionByName(const char *name) const;
137
Yang Ni3f30b622017-02-25 20:23:58 -0800138 // Find the name of the instruction, e.g., the name of a function (OpFunction
139 // instruction).
140 // The returned string is owned by the OpName instruction, whose first operand
141 // is the instruction being queried on.
Yang Ni4df77d12017-01-31 10:24:36 -0800142 const char *lookupNameByInstruction(const Instruction *) const;
143
144 VariableInst *getInvocationId();
145 VariableInst *getNumWorkgroups();
146
147 // Adds a struct type built somewhere else.
148 Module *addStructType(TypeStructInst *structType);
149 Module *addVariable(VariableInst *var);
150
151 // Methods to look up types. Create them if not found.
152 TypeVoidInst *getVoidType();
153 TypeIntInst *getIntType(int bits, bool isSigned = true);
154 TypeIntInst *getUnsignedIntType(int bits);
155 TypeFloatInst *getFloatType(int bits);
156 TypeVectorInst *getVectorType(Instruction *componentType, int width);
157 TypePointerInst *getPointerType(StorageClass storage,
158 Instruction *pointeeType);
159 TypeRuntimeArrayInst *getRuntimeArrayType(Instruction *elementType);
160
161 // This implies that struct types are strictly structural equivalent, i.e.,
162 // two structs are equivalent i.f.f. their fields are equivalent, recursively.
163 TypeStructInst *getStructType(Instruction *fieldType[], int numField);
164 TypeStructInst *getStructType(const std::vector<Instruction *> &fieldType);
165 TypeStructInst *getStructType(Instruction *field0Type);
166 TypeStructInst *getStructType(Instruction *field0Type,
167 Instruction *field1Type);
168 TypeStructInst *getStructType(Instruction *field0Type,
169 Instruction *field1Type,
170 Instruction *field2Type);
171
172 // TODO: Can function types of different decorations be considered the same?
173 TypeFunctionInst *getFunctionType(Instruction *retType,
174 Instruction *const argType[],
175 size_t numArg);
176 TypeFunctionInst *getFunctionType(Instruction *retType,
177 const std::vector<Instruction *> &argTypes);
178
179 size_t getSize(TypeVoidInst *voidTy);
180 size_t getSize(TypeIntInst *intTy);
181 size_t getSize(TypeFloatInst *fpTy);
182 size_t getSize(TypeVectorInst *vTy);
183 size_t getSize(TypePointerInst *ptrTy);
184 size_t getSize(TypeStructInst *structTy);
185 size_t getSize(TypeFunctionInst *funcTy);
186 size_t getSize(Instruction *inst);
187
188 ConstantInst *getConstant(TypeIntInst *type, int32_t value);
189 ConstantInst *getConstant(TypeIntInst *type, uint32_t value);
190 ConstantInst *getConstant(TypeFloatInst *type, float value);
191
192 ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
193 ConstantInst *components[],
194 size_t width);
195 ConstantCompositeInst *
196 getConstantComposite(Instruction *type,
197 const std::vector<ConstantInst *> &components);
198 ConstantCompositeInst *getConstantComposite(Instruction *type,
199 ConstantInst *comp0,
200 ConstantInst *comp1);
201 ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
202 ConstantInst *comp0,
203 ConstantInst *comp1,
204 ConstantInst *comp2);
205 ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
206 ConstantInst *comp0,
207 ConstantInst *comp1,
208 ConstantInst *comp2,
209 ConstantInst *comp3);
210
211 Module *addFunctionDefinition(FunctionDefinition *func);
212
213 void consolidateAnnotations();
214
215private:
216 static Module *mInstance;
217 uint32_t mNextId;
218 std::map<uint32_t, Instruction *> mIdTable;
219
220 uint32_t mMagicNumber;
221 VersionNumber mVersion;
222 uint32_t mGeneratorMagicNumber;
223 uint32_t mBound;
224 uint32_t mReserved;
225
226 std::vector<CapabilityInst *> mCapabilities;
227 std::vector<ExtensionInst *> mExtensions;
228 std::vector<ExtInstImportInst *> mExtInstImports;
229 std::unique_ptr<MemoryModelInst> mMemoryModel;
230 std::vector<EntryPointInst *> mEntryPointInsts;
231 std::vector<ExecutionModeInst *> mExecutionModes;
232 std::vector<EntryPointDefinition *> mEntryPoints;
233 std::unique_ptr<DebugInfoSection> mDebugInfo;
234 std::unique_ptr<AnnotationSection> mAnnotations;
235 std::unique_ptr<GlobalSection> mGlobals;
236 std::vector<FunctionDefinition *> mFunctionDefinitions;
237
238 ExtInstImportInst *mGLExt;
239
240 ContainerDeleter<std::vector<CapabilityInst *>> mCapabilitiesDeleter;
241 ContainerDeleter<std::vector<ExtensionInst *>> mExtensionsDeleter;
242 ContainerDeleter<std::vector<ExtInstImportInst *>> mExtInstImportsDeleter;
243 ContainerDeleter<std::vector<EntryPointInst *>> mEntryPointInstsDeleter;
244 ContainerDeleter<std::vector<ExecutionModeInst *>> mExecutionModesDeleter;
245 ContainerDeleter<std::vector<EntryPointDefinition *>> mEntryPointsDeleter;
246 ContainerDeleter<std::vector<FunctionDefinition *>>
247 mFunctionDefinitionsDeleter;
248};
249
250struct Extent3D {
251 uint32_t mWidth;
252 uint32_t mHeight;
253 uint32_t mDepth;
254};
255
256class EntryPointDefinition : public Entity {
257public:
258 EntryPointDefinition() {}
259 EntryPointDefinition(Builder *builder, ExecutionModel execModel,
260 FunctionDefinition *func, const char *name);
261
262 virtual ~EntryPointDefinition() {
263 // Nothing to do here since ~Module() will delete entities referenced here
264 }
265
266 void accept(IVisitor *visitor) override {
267 visitor->visit(mEntryPointInst);
268 // Do not visit the ExecutionMode instructions here. They are linked here
269 // for convinience, and for convinience only. They are all grouped, stored,
270 // and serialized directly in the module in a section right after all
271 // EntryPoint instructions. Visit them from there.
272 }
273
274 bool DeserializeInternal(InputWordStream &IS) override;
275
276 EntryPointDefinition *addToInterface(VariableInst *var);
277 EntryPointDefinition *addExecutionMode(ExecutionModeInst *mode) {
278 mExecutionModeInsts.push_back(mode);
279 return this;
280 }
281 const std::vector<ExecutionModeInst *> &getExecutionModes() const {
282 return mExecutionModeInsts;
283 }
284
285 EntryPointDefinition *setLocalSize(uint32_t width, uint32_t height,
286 uint32_t depth);
287
288 EntryPointDefinition *applyExecutionMode(ExecutionModeInst *mode);
289
290 EntryPointInst *getInstruction() const { return mEntryPointInst; }
291
292private:
293 const char *mName;
294 FunctionInst *mFunction;
295 ExecutionModel mExecutionModel;
296 std::vector<VariableInst *> mInterface;
297 Extent3D mLocalSize;
298
299 EntryPointInst *mEntryPointInst;
300 std::vector<ExecutionModeInst *> mExecutionModeInsts;
301};
302
303class DebugInfoSection : public Entity {
304public:
305 DebugInfoSection() : mSourcesDeleter(mSources), mNamesDeleter(mNames) {}
306 DebugInfoSection(Builder *b)
307 : Entity(b), mSourcesDeleter(mSources), mNamesDeleter(mNames) {}
308
309 virtual ~DebugInfoSection() {}
310
311 bool DeserializeInternal(InputWordStream &IS) override;
312
313 DebugInfoSection *addSource(SourceLanguage lang, int version);
314 DebugInfoSection *addSourceExtension(const char *ext);
315
316 Instruction *lookupByName(const char *name) const;
317 const char *lookupNameByInstruction(const Instruction *) const;
318
319 void accept(IVisitor *v) override {
320 for (auto source : mSources) {
321 v->visit(source);
322 }
323 for (auto name : mNames) {
324 v->visit(name);
325 }
326 }
327
328private:
329 // (OpString|OpSource|OpSourceExtension|OpSourceContinued)*
330 std::vector<Instruction *> mSources;
331 // (OpName|OpMemberName)*
332 std::vector<Instruction *> mNames;
333
334 ContainerDeleter<std::vector<Instruction *>> mSourcesDeleter;
335 ContainerDeleter<std::vector<Instruction *>> mNamesDeleter;
336};
337
338class AnnotationSection : public Entity {
339public:
340 AnnotationSection();
341 AnnotationSection(Builder *b);
342
343 virtual ~AnnotationSection() {}
344
345 bool DeserializeInternal(InputWordStream &IS) override;
346
347 void accept(IVisitor *v) override {
348 for (auto inst : mAnnotations) {
349 v->visit(inst);
350 }
351 }
352
353 template <typename T> void addAnnotations(T begin, T end) {
354 mAnnotations.insert<T>(std::end(mAnnotations), begin, end);
355 }
356
357 std::vector<Instruction *>::const_iterator begin() const {
358 return mAnnotations.begin();
359 }
360
361 std::vector<Instruction *>::const_iterator end() const {
362 return mAnnotations.end();
363 }
364
365 void clear() { mAnnotations.clear(); }
366
367private:
368 std::vector<Instruction *> mAnnotations; // OpDecorate, etc.
369
370 ContainerDeleter<std::vector<Instruction *>> mAnnotationsDeleter;
371};
372
373// Types, constants, and globals
374class GlobalSection : public Entity {
375public:
376 GlobalSection();
377 GlobalSection(Builder *builder);
378
379 virtual ~GlobalSection() {}
380
381 bool DeserializeInternal(InputWordStream &IS) override;
382
383 void accept(IVisitor *v) override {
384 for (auto inst : mGlobalDefs) {
385 v->visit(inst);
386 }
387
388 if (mInvocationId) {
389 v->visit(mInvocationId.get());
390 }
391
392 if (mNumWorkgroups) {
393 v->visit(mNumWorkgroups.get());
394 }
395 }
396
397 ConstantInst *getConstant(TypeIntInst *type, int32_t value);
398 ConstantInst *getConstant(TypeIntInst *type, uint32_t value);
399 ConstantInst *getConstant(TypeFloatInst *type, float value);
400 ConstantCompositeInst *getConstantComposite(TypeVectorInst *type,
401 ConstantInst *components[],
402 size_t width);
403
404 // Methods to look up types. Create them if not found.
405 TypeVoidInst *getVoidType();
406 TypeIntInst *getIntType(int bits, bool isSigned = true);
407 TypeFloatInst *getFloatType(int bits);
408 TypeVectorInst *getVectorType(Instruction *componentType, int width);
409 TypePointerInst *getPointerType(StorageClass storage,
410 Instruction *pointeeType);
411 TypeRuntimeArrayInst *getRuntimeArrayType(Instruction *elementType);
412
413 // This implies that struct types are strictly structural equivalent, i.e.,
414 // two structs are equivalent i.f.f. their fields are equivalent, recursively.
415 TypeStructInst *getStructType(Instruction *fieldType[], int numField);
416 // TypeStructInst *getStructType(const std::vector<Instruction *>
417 // &fieldTypes);
418
419 // TODO: Can function types of different decorations be considered the same?
420 TypeFunctionInst *getFunctionType(Instruction *retType,
421 Instruction *const argType[],
422 size_t numArg);
423 // TypeStructInst *addStructType(Instruction *fieldType[], int numField);
424 GlobalSection *addStructType(TypeStructInst *structType);
425 GlobalSection *addVariable(VariableInst *var);
426
427 VariableInst *getInvocationId();
428 VariableInst *getNumWorkgroups();
429
430private:
431 // TODO: Add structure to this.
432 // Separate types, constants, variables, etc.
433 std::vector<Instruction *> mGlobalDefs;
434 std::unique_ptr<VariableInst> mInvocationId;
435 std::unique_ptr<VariableInst> mNumWorkgroups;
436
437 ContainerDeleter<std::vector<Instruction *>> mGlobalDefsDeleter;
438};
439
440class FunctionDeclaration : public Entity {
441public:
442 virtual ~FunctionDeclaration() {}
443
444 bool DeserializeInternal(InputWordStream &IS) override;
445
446 void accept(IVisitor *v) override {
447 v->visit(mFunc);
448 for (auto param : mParams) {
449 v->visit(param);
450 }
451 v->visit(mFuncEnd);
452 }
453
454private:
455 FunctionInst *mFunc;
456 std::vector<FunctionParameterInst *> mParams;
457 FunctionEndInst *mFuncEnd;
458};
459
460class Block : public Entity {
461public:
462 Block() {}
463 Block(Builder *b) : Entity(b) {}
464
465 virtual ~Block() {}
466
467 bool DeserializeInternal(InputWordStream &IS) override;
468
469 void accept(IVisitor *v) override {
470 for (auto inst : mInsts) {
471 v->visit(inst);
472 }
473 }
474
475 Block *addInstruction(Instruction *inst) {
476 mInsts.push_back(inst);
477 return this;
478 }
479
480private:
481 std::vector<Instruction *> mInsts;
482};
483
484class FunctionDefinition : public Entity {
485public:
486 FunctionDefinition();
487 FunctionDefinition(Builder *builder, FunctionInst *func,
488 FunctionEndInst *end);
489
490 virtual ~FunctionDefinition() {}
491
492 bool DeserializeInternal(InputWordStream &IS) override;
493
494 void accept(IVisitor *v) override {
495 v->visit(mFunc.get());
496 for (auto param : mParams) {
497 v->visit(param);
498 }
499 for (auto block : mBlocks) {
500 v->visit(block);
501 }
502 v->visit(mFuncEnd.get());
503 }
504
505 FunctionDefinition *addBlock(Block *b) {
506 mBlocks.push_back(b);
507 return this;
508 }
509
510 FunctionInst *getInstruction() const { return mFunc.get(); }
511 FunctionParameterInst *getParameter(uint32_t i) const { return mParams[i]; }
512
513 Instruction *getReturnType() const;
514
515private:
516 std::unique_ptr<FunctionInst> mFunc;
517 std::vector<FunctionParameterInst *> mParams;
518 std::vector<Block *> mBlocks;
519 std::unique_ptr<FunctionEndInst> mFuncEnd;
520
521 ContainerDeleter<std::vector<FunctionParameterInst *>> mParamsDeleter;
522 ContainerDeleter<std::vector<Block *>> mBlocksDeleter;
523};
524
525} // namespace spirit
526} // namespace android
527
528#endif // MODULE_H