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