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