Browse Source

[spirv] SpirvBasicBlock, SpirvFunction, SpirvModule, SpirvContext

Lei Zhang 7 years ago
parent
commit
c0c8104467

+ 52 - 0
tools/clang/include/clang/SPIRV/SPIRVContext.h

@@ -15,6 +15,7 @@
 #include "clang/SPIRV/Constant.h"
 #include "clang/SPIRV/Decoration.h"
 #include "clang/SPIRV/Type.h"
+#include "llvm/Support/Allocator.h"
 
 namespace clang {
 namespace spirv {
@@ -111,7 +112,58 @@ SPIRVContext::SPIRVContext() : nextId(1) {}
 uint32_t SPIRVContext::getNextId() const { return nextId; }
 uint32_t SPIRVContext::takeNextId() { return nextId++; }
 
+/// The class owning various SPIR-V entities allocated in memory during CodeGen.
+///
+/// All entities should be allocated from an object of this class using
+/// placement new. This way other components of the CodeGen do not need to worry
+/// about lifetime of those SPIR-V entities. They will be deleted when such a
+/// context is deleted. Therefore, this context should outlive the usages of the
+/// the SPIR-V entities allocated in memory.
+class SpirvContext {
+public:
+  SpirvContext() = default;
+  ~SpirvContext() = default;
+
+  // Forbid copy construction and assignment
+  SpirvContext(const SpirvContext &) = delete;
+  SpirvContext &operator=(const SpirvContext &) = delete;
+
+  // Forbid move construction and assignment
+  SpirvContext(SpirvContext &&) = delete;
+  SpirvContext &operator=(SpirvContext &&) = delete;
+
+  /// Allocates memory of the given size and alignment.
+  void *allocate(size_t size, unsigned align = 8) const {
+    return allocator.Allocate(size, align);
+  }
+
+  /// Deallocates the memory pointed by the given pointer.
+  void deallocate(void *ptr) const {}
+
+private:
+  /// \brief The allocator used to create SPIR-V entity objects.
+  ///
+  /// SPIR-V entity objects are never destructed; rather, all memory associated
+  /// with the SPIR-V entity objects will be released when the SpirvContext
+  /// itself is destroyed.
+  mutable llvm::BumpPtrAllocator allocator;
+};
+
 } // end namespace spirv
 } // end namespace clang
 
+// operator new and delete aren't allowed inside namespaces.
+
+/// Placement new for using the SpirvContext's allocator.
+inline void *operator new(size_t bytes, const clang::spirv::SpirvContext &c,
+                          size_t align = 8) {
+  return c.allocate(bytes, align);
+}
+
+/// Placement delete companion to the new above.
+inline void operator delete(void *ptr, const clang::spirv::SpirvContext &c,
+                            size_t) {
+  c.deallocate(ptr);
+}
+
 #endif

+ 91 - 0
tools/clang/include/clang/SPIRV/SpirvBasicBlock.h

@@ -0,0 +1,91 @@
+//===-- SpirvBasicBlock.h - SPIR-V Basic Block ----------------*- C++ -*---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SPIRV_SPIRVBASICBLOCK_H
+#define LLVM_CLANG_SPIRV_SPIRVBASICBLOCK_H
+
+#include <string>
+#include <vector>
+
+#include "clang/SPIRV/SpirvInstruction.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+namespace spirv {
+
+/// The class representing a SPIR-V basic block in memory.
+class SpirvBasicBlock {
+public:
+  SpirvBasicBlock(uint32_t id, llvm::StringRef name);
+  ~SpirvBasicBlock() = default;
+
+  // Forbid copy construction and assignment
+  SpirvBasicBlock(const SpirvBasicBlock &) = delete;
+  SpirvBasicBlock &operator=(const SpirvBasicBlock &) = delete;
+
+  // Forbid move construction and assignment
+  SpirvBasicBlock(SpirvBasicBlock &&) = delete;
+  SpirvBasicBlock &operator=(SpirvBasicBlock &&) = delete;
+
+  /// Returns the label's <result-id> of this basic block.
+  uint32_t getLabelId() const { return labelId; }
+
+  /// Returns the debug name of this basic block.
+  llvm::StringRef getName() const { return labelName; }
+
+  /// Sets the merge target for this basic block.
+  ///
+  /// The caller must make sure this basic block contains an OpSelectionMerge
+  /// or OpLoopMerge instruction.
+  void setMergeTarget(SpirvBasicBlock *target) { mergeTarget = target; }
+  /// Returns the merge target if this basic block contains an OpSelectionMerge
+  /// or OpLoopMerge instruction. Returns nullptr otherwise.
+  SpirvBasicBlock *getMergeTarget() const { return mergeTarget; }
+
+  /// Sets the continue target to the given basic block.
+  ///
+  /// The caller must make sure this basic block contains an OpLoopMerge
+  /// instruction.
+  void setContinueTarget(SpirvBasicBlock *target) { continueTarget = target; }
+  /// Returns the continue target if this basic block contains an
+  /// OpLoopMerge instruction. Returns nullptr otherwise.
+  SpirvBasicBlock *getContinueTarget() const { return continueTarget; }
+
+  /// Returns true if the last instruction in this basic block is a termination
+  /// instruction.
+  bool hasTerminator() const;
+
+private:
+  uint32_t labelId;      ///< The label's <result-id>
+  std::string labelName; ///< The label's debug name
+
+  /// Variables defined in this basic block.
+  ///
+  /// Local variables inside a function should be defined at the beginning
+  /// of the entry basic block. So this field will only be used by entry
+  /// basic blocks.
+  std::vector<SpirvVariable *> variables;
+  /// Instructions belonging to this basic block.
+  std::vector<SpirvInstruction *> instructions;
+
+  /// Successors to this basic block.
+  llvm::SmallVector<SpirvBasicBlock *, 2> successors;
+
+  /// The corresponding merge targets if this basic block is a header
+  /// block of structured control flow.
+  SpirvBasicBlock *mergeTarget;
+  /// The continue merge targets if this basic block is a header block
+  /// of structured control flow.
+  SpirvBasicBlock *continueTarget;
+};
+
+} // end namespace spirv
+} // end namespace clang
+
+#endif // LLVM_CLANG_SPIRV_SPIRVBASICBLOCK_H

+ 67 - 0
tools/clang/include/clang/SPIRV/SpirvBuilder.h

@@ -0,0 +1,67 @@
+//===-- SpirvBuilder.h - SPIR-V Builder -----------------------*- C++ -*---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SPIRV_SPIRVBUILDER_H
+#define LLVM_CLANG_SPIRV_SPIRVBUILDER_H
+
+#include "clang/SPIRV/SPIRVContext.h"
+#include "clang/SPIRV/SpirvBasicBlock.h"
+#include "clang/SPIRV/SpirvFunction.h"
+#include "clang/SPIRV/SpirvInstruction.h"
+#include "clang/SPIRV/SpirvModule.h"
+#include "llvm/ADT/MapVector.h"
+
+namespace clang {
+namespace spirv {
+
+/// The SPIR-V in-memory representation builder class.
+///
+/// This class exports API for constructing SPIR-V in-memory representation
+/// interactively. Under the hood, it allocates SPIR-V entity objects from
+/// SpirvContext and wires them up into a connected structured representation.
+///
+/// At any time, there can only exist at most one function under building;
+/// but there can exist multiple basic blocks under construction.
+///
+/// Call `getModule()` to get the SPIR-V words after finishing building the
+/// module.
+class SpirvBuilder {
+public:
+  explicit SpirvBuilder(SpirvContext &c);
+  ~SpirvBuilder() = default;
+
+  // Forbid copy construction and assignment
+  SpirvBuilder(const SpirvBuilder &) = delete;
+  SpirvBuilder &operator=(const SpirvBuilder &) = delete;
+
+  // Forbid move construction and assignment
+  SpirvBuilder(SpirvBuilder &&) = delete;
+  SpirvBuilder &operator=(SpirvBuilder &&) = delete;
+
+  /// Returns the SPIR-V module being built.
+  SpirvModule *getModule() { return module; }
+
+private:
+  /// \brief Map from basic blocks' <label-id> to their objects.
+  ///
+  /// We need MapVector here to remember the order of insertion. Order matters
+  /// here since, for example, we'll know for sure the first basic block is
+  /// the entry block.
+  using OrderedBasicBlockMap = llvm::MapVector<uint32_t, SpirvBasicBlock *>;
+
+  SpirvContext &context;
+
+  SpirvModule *module;              ///< The current module being built
+  SpirvFunction *function;          ///< The current function being built
+  OrderedBasicBlockMap basicBlocks; ///< The current basic block being built
+};
+
+} // end namespace spirv
+} // end namespace clang
+
+#endif // LLVM_CLANG_SPIRV_SPIRVBUILDER_H

+ 57 - 0
tools/clang/include/clang/SPIRV/SpirvFunction.h

@@ -0,0 +1,57 @@
+//===-- SpirvFunction.h - SPIR-V Function ---------------------*- C++ -*---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SPIRV_SPIRVFUNCTION_H
+#define LLVM_CLANG_SPIRV_SPIRVFUNCTION_H
+
+#include <vector>
+
+#include "clang/SPIRV/SpirvBasicBlock.h"
+#include "clang/SPIRV/SpirvInstruction.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+namespace spirv {
+
+/// The class representing a SPIR-V function in memory.
+class SpirvFunction {
+public:
+  SpirvFunction(QualType type, uint32_t id, spv::FunctionControlMask);
+  ~SpirvFunction() = default;
+
+  // Forbid copy construction and assignment
+  SpirvFunction(const SpirvFunction &) = delete;
+  SpirvFunction &operator=(const SpirvFunction &) = delete;
+
+  // Forbid move construction and assignment
+  SpirvFunction(SpirvFunction &&) = delete;
+  SpirvFunction &operator=(SpirvFunction &&) = delete;
+
+private:
+  QualType functionType;                    ///< This function's type
+  uint32_t functionId;                      ///< This function's <result-id>
+  spv::FunctionControlMask functionControl; ///< SPIR-V function control
+
+  /// Parameters to this function.
+  llvm::SmallVector<SpirvFunctionParameter *, 8> parameters;
+
+  /// Variables defined in this function.
+  ///
+  /// Local variables inside a function should be defined at the beginning
+  /// of the entry basic block. This serves as a temporary place for holding
+  /// these variables.
+  std::vector<SpirvVariable *> variables;
+
+  /// Basic blocks inside this function.
+  std::vector<SpirvBasicBlock *> basicBlocks;
+};
+
+} // end namespace spirv
+} // end namespace clang
+
+#endif // LLVM_CLANG_SPIRV_SPIRVFUNCTION_H

+ 79 - 33
tools/clang/include/clang/SPIRV/SpirvInstruction.h

@@ -5,6 +5,8 @@
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SPIRV_SPIRVINSTRUCTION_H
+#define LLVM_CLANG_SPIRV_SPIRVINSTRUCTION_H
 
 #include "spirv/unified1/GLSL.std.450.h"
 #include "spirv/unified1/spirv.hpp11"
@@ -19,14 +21,18 @@ namespace spirv {
 /// \brief The base class for representing SPIR-V instructions.
 class SpirvInstruction {
 public:
+  virtual ~SpirvInstruction() = default;
+
   spv::Op getOpcode() const { return opcode; }
   QualType getResultType() const { return resultType; }
   uint32_t getResultId() const { return resultId; }
   clang::SourceLocation getSourceLocation() const { return srcLoc; }
 
-  virtual ~SpirvInstruction() = default;
+  /// Returns true if this instruction is a termination instruction.
+  bool isTerminator() const;
 
 protected:
+  // Forbid creating SpirvInstruction directly
   SpirvInstruction(spv::Op op, QualType type, uint32_t id, SourceLocation loc)
       : opcode(op), resultType(type), resultId(id), srcLoc(loc) {}
 
@@ -37,9 +43,11 @@ private:
   SourceLocation srcLoc;
 };
 
-/// \brief Represents SPIR-V unary operation instructions. Includes:
+/// \brief Represents SPIR-V unary operation instructions.
+///
+/// This class includes:
 /// ----------------------------------------------------------------------------
-/// opTranspose     // Matrix capability
+/// opTranspose    // Matrix capability
 /// opDPdx
 /// opDPdy
 /// opFwidth
@@ -99,7 +107,9 @@ private:
   spv::Op specOp;
 };
 
-/// \brief Represents SPIR-V binary operation instructions. Includes:
+/// \brief Represents SPIR-V binary operation instructions.
+///
+/// This class includes:
 /// -------------------------- Arithmetic operations ---------------------------
 /// OpIAdd
 /// OpFAdd
@@ -234,8 +244,9 @@ private:
 };
 
 /// \brief Access Chain instruction representation (OpAccessChain)
-/// Note: If needed, this class can be extended to cover Ptr access chains, and
-/// InBounds access chains. These are currently not used by CodeGen.
+///
+/// Note: If needed, this class can be extended to cover Ptr access chains,
+/// and InBounds access chains. These are currently not used by CodeGen.
 class SpirvAccessChain : public SpirvInstruction {
 public:
   SpirvAccessChain(QualType type, uint32_t resultId, SourceLocation loc,
@@ -314,6 +325,7 @@ private:
 };
 
 /// \brief Image query instructions:
+///
 /// Covers the following instructions:
 /// OpImageQueryFormat  (image)
 /// OpImageQueryOrder   (image)
@@ -353,24 +365,27 @@ private:
   uint32_t residentCode;
 };
 
-/// \brief Atomic instructions. includes:
-/// OpAtomicLoad           (pointer,scope,memorysemantics)
-/// OpAtomicIncrement      (pointer,scope,memorysemantics)
-/// OpAtomicDecrement      (pointer,scope,memorysemantics)
-/// OpAtomicFlagClear      (pointer,scope,memorysemantics)
-/// OpAtomicFlagTestAndSet (pointer,scope,memorysemantics)
-/// OpAtomicStore          (pointer,scope,memorysemantics,value)
-/// OpAtomicAnd            (pointer,scope,memorysemantics,value)
-/// OpAtomicOr             (pointer,scope,memorysemantics,value)
-/// OpAtomicXor            (pointer,scope,memorysemantics,value)
-/// OpAtomicIAdd           (pointer,scope,memorysemantics,value)
-/// OpAtomicISub           (pointer,scope,memorysemantics,value)
-/// OpAtomicSMin           (pointer,scope,memorysemantics,value)
-/// OpAtomicUMin           (pointer,scope,memorysemantics,value)
-/// OpAtomicSMax           (pointer,scope,memorysemantics,value)
-/// OpAtomicUMax           (pointer,scope,memorysemantics,value)
-/// OpAtomicExchange       (pointer,scope,memorysemantics,value)
-/// OpAtomicCompareExchange(pointer,scope,semaequal,semaunequal,value,comparator)
+/// \brief Atomic instructions.
+///
+/// This class includes:
+/// OpAtomicLoad           (pointer, scope, memorysemantics)
+/// OpAtomicIncrement      (pointer, scope, memorysemantics)
+/// OpAtomicDecrement      (pointer, scope, memorysemantics)
+/// OpAtomicFlagClear      (pointer, scope, memorysemantics)
+/// OpAtomicFlagTestAndSet (pointer, scope, memorysemantics)
+/// OpAtomicStore          (pointer, scope, memorysemantics, value)
+/// OpAtomicAnd            (pointer, scope, memorysemantics, value)
+/// OpAtomicOr             (pointer, scope, memorysemantics, value)
+/// OpAtomicXor            (pointer, scope, memorysemantics, value)
+/// OpAtomicIAdd           (pointer, scope, memorysemantics, value)
+/// OpAtomicISub           (pointer, scope, memorysemantics, value)
+/// OpAtomicSMin           (pointer, scope, memorysemantics, value)
+/// OpAtomicUMin           (pointer, scope, memorysemantics, value)
+/// OpAtomicSMax           (pointer, scope, memorysemantics, value)
+/// OpAtomicUMax           (pointer, scope, memorysemantics, value)
+/// OpAtomicExchange       (pointer, scope, memorysemantics, value)
+/// OpAtomicCompareExchange(pointer, scope, semaequal, semaunequal,
+///                         value, comparator)
 class SpirvAtomic : public SpirvInstruction {
 public:
   SpirvAtomic(spv::Op opCode, QualType type, uint32_t resultId,
@@ -589,6 +604,19 @@ private:
   spv::Capability capability;
 };
 
+/// \brief OpDecorate instruction
+class SpirvDecoration : public SpirvInstruction {
+public:
+  SpirvDecoration(SourceLocation loc, spv::Decoration decor,
+                  llvm::ArrayRef<uint32_t> params,
+                  llvm::Optional<uint32_t> index);
+
+private:
+  spv::Decoration decoration;
+  llvm::Optional<uint32_t> index;
+  llvm::SmallVector<uint32_t, 4> params;
+};
+
 /// \brief OpMemoryBarrier and OpControlBarrier instructions
 class SpirvBarrier : public SpirvInstruction {
 public:
@@ -653,9 +681,12 @@ private:
 };
 
 /// \brief Termination instructions are instructions that end a basic block.
+///
 /// These instructions include:
+///
 /// * OpBranch, OpBranchConditional, OpSwitch
 /// * OpReturn, OpReturnValue, OpKill, OpUnreachable
+///
 /// The first group (branching instructions) also include information on
 /// possible branches that will be taken next.
 class SpirvTerminator : public SpirvInstruction {
@@ -762,8 +793,10 @@ private:
   uint32_t returnValue;
 };
 
-/// \brief Composition instructions include: opConstantComposite,
-/// opSpecConstantComposite, and opCompositeConstruct
+/// \brief Composition instructions
+///
+/// This class includes OpConstantComposite, OpSpecConstantComposite,
+/// and OpCompositeConstruct.
 class SpirvComposite : public SpirvInstruction {
 public:
   SpirvComposite(QualType type, uint32_t resultId, SourceLocation loc,
@@ -797,8 +830,10 @@ private:
   llvm::SmallVector<uint32_t, 4> indices;
 };
 
-/// \brief BitField instructions include: OpBitFieldInsert, OpBitFieldSExtract,
-/// and OpBitFieldUExtract
+/// \brief BitField instructions
+///
+/// This class includes OpBitFieldInsert, OpBitFieldSExtract,
+//  and OpBitFieldUExtract.
 class SpirvBitField : public SpirvInstruction {
 public:
   virtual uint32_t getBase() const { return base; }
@@ -809,14 +844,15 @@ protected:
   SpirvBitField(spv::Op op, QualType type, uint32_t resultId,
                 SourceLocation loc, uint32_t baseId, uint32_t offsetId,
                 uint32_t countId)
-      : SpirvInstruction(op, type, resultId, loc), base(base), offset(offsetId),
-        count(countId) {}
+      : SpirvInstruction(op, type, resultId, loc), base(baseId),
+        offset(offsetId), count(countId) {}
 
 private:
   uint32_t base;
   uint32_t offset;
   uint32_t count;
 };
+
 class SpirvBitFieldInsert : public SpirvBitField {
 public:
   SpirvBitFieldInsert(QualType type, uint32_t resultId, SourceLocation loc,
@@ -830,6 +866,7 @@ public:
 private:
   uint32_t insert;
 };
+
 class SpirvBitFieldExtract : public SpirvBitField {
 public:
   SpirvBitFieldExtract(QualType type, uint32_t resultId, SourceLocation loc,
@@ -858,6 +895,12 @@ private:
   llvm::SmallVector<uint32_t, 4> args;
 };
 
+class SpirvFunctionParameter : public SpirvInstruction {
+public:
+  SpirvFunctionParameter(QualType type, uint32_t resultId, SourceLocation loc)
+      : SpirvInstruction(spv::Op::OpFunctionParameter, type, resultId, loc) {}
+};
+
 /// \brief OpVariable instruction
 class SpirvVariable : public SpirvInstruction {
 public:
@@ -944,7 +987,9 @@ public:
       : SpirvInstruction(spv::Op::OpLabel, /*QualType*/ {}, resultId, loc) {}
 };
 
-/// \brief Image instructions. These include:
+/// \brief Image instructions.
+///
+/// This class includes:
 ///
 /// OpImageSampleImplicitLod          (image, coordinate, mask, args)
 /// OpImageSampleExplicitLod          (image, coordinate, mask, args, lod)
@@ -1015,8 +1060,7 @@ private:
   spv::ImageOperandsMask operandsMask;
 };
 
-/// \brief OpSampledImage instruction (Create a sampled image, containing both a
-/// sampler and an image).
+/// \brief OpSampledImage instruction
 class SpirvSampledImage : public SpirvInstruction {
 public:
   SpirvSampledImage(QualType type, uint32_t resultId, SourceLocation loc,
@@ -1034,3 +1078,5 @@ private:
 
 } // namespace spirv
 } // namespace clang
+
+#endif // LLVM_CLANG_SPIRV_SPIRVINSTRUCTION_H

+ 74 - 0
tools/clang/include/clang/SPIRV/SpirvModule.h

@@ -0,0 +1,74 @@
+//===-- SpirvModule.h - SPIR-V Module -------------------------*- C++ -*---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SPIRV_SPIRVMODULE_H
+#define LLVM_CLANG_SPIRV_SPIRVMODULE_H
+
+#include <vector>
+
+#include "clang/SPIRV/SpirvFunction.h"
+#include "clang/SPIRV/SpirvInstruction.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+namespace spirv {
+
+// TODO: flesh this out
+class SpirvTypeConstant;
+
+/// The class representing a SPIR-V module in memory.
+///
+/// A SPIR-V module contains two main parts: instructions for "metadata" (e.g.,
+/// required capabilities and used types) and instructions for shader logic.
+/// The former consists of the instructions before the function section in
+/// SPIR-V logical layout; while the later is what are in the function section.
+///
+/// The SpirvBuilder class should be used to gradually build up the second part.
+/// After the SpirvBuilder completes its tasks, the first part should be filled
+/// out by traversing the second part built by the SpirvBuilder.
+///
+/// This representation is a just a minimal collection of SPIR-V entities;
+/// it does not provide much sanity check over the integrity among the enclosed
+/// entities, which modifying classes should be responsible for.
+class SpirvModule {
+public:
+  SpirvModule();
+  ~SpirvModule() = default;
+
+  // Forbid copy construction and assignment
+  SpirvModule(const SpirvModule &) = delete;
+  SpirvModule &operator=(const SpirvModule &) = delete;
+
+  // Forbid move construction and assignment
+  SpirvModule(SpirvModule &&) = delete;
+  SpirvModule &operator=(SpirvModule &&) = delete;
+
+private:
+  uint32_t bound; ///< The <result-id> bound: the next unused one
+
+  // "Metadata" instructions
+  llvm::SmallVector<SpirvCapability *, 8> capabilities;
+  llvm::SmallVector<SpirvExtension *, 4> extensions;
+  llvm::SmallVector<SpirvExtInstImport *, 1> extInstSets;
+  SpirvMemoryModel *memoryModel;
+  llvm::SmallVector<SpirvEntryPoint *, 1> entryPoints;
+  llvm::SmallVector<SpirvExecutionMode *, 4> executionModes;
+  SpirvSource *debugSource;
+  std::vector<SpirvName *> debugNames;
+  std::vector<SpirvDecoration *> decorations;
+  std::vector<SpirvTypeConstant *> typeConstants;
+  std::vector<SpirvVariable *> variables;
+
+  // Shader logic instructions
+  std::vector<SpirvFunction *> functions;
+};
+
+} // end namespace spirv
+} // end namespace clang
+
+#endif // LLVM_CLANG_SPIRV_SPIRVMODULE_H

+ 4 - 0
tools/clang/lib/SPIRV/CMakeLists.txt

@@ -17,7 +17,11 @@ add_clang_library(clangSPIRV
   ModuleBuilder.cpp
   SPIRVContext.cpp
   SPIRVEmitter.cpp
+  SpirvBasicBlock.cpp
+  SpirvBuilder.cpp
   SpirvInstruction.cpp
+  SpirvFunction.cpp
+  SpirvModule.cpp
   String.cpp
   Structure.cpp
   Type.cpp

+ 24 - 0
tools/clang/lib/SPIRV/SpirvBasicBlock.cpp

@@ -0,0 +1,24 @@
+//===--- SpirvBasicBlock.cpp - SPIR-V Basic Block Implementation -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/SPIRV/SpirvBasicBlock.h"
+
+namespace clang {
+namespace spirv {
+
+SpirvBasicBlock::SpirvBasicBlock(uint32_t id, llvm::StringRef name)
+    : labelId(id), labelName(name), mergeTarget(nullptr),
+      continueTarget(nullptr) {}
+
+bool SpirvBasicBlock::hasTerminator() const {
+  return !instructions.empty() && instructions.back()->isTerminator();
+}
+
+} // end namespace spirv
+} // end namespace clang

+ 21 - 0
tools/clang/lib/SPIRV/SpirvBuilder.cpp

@@ -0,0 +1,21 @@
+//===--- SpirvBuilder.cpp - SPIR-V Builder Implementation --------*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/SPIRV/SpirvBuilder.h"
+
+namespace clang {
+namespace spirv {
+
+SpirvBuilder::SpirvBuilder(SpirvContext &ctx)
+    : context(ctx), module(nullptr), function(nullptr) {
+  module = new (context) SpirvModule;
+}
+
+} // end namespace spirv
+} // end namespace clang

+ 20 - 0
tools/clang/lib/SPIRV/SpirvFunction.cpp

@@ -0,0 +1,20 @@
+//===--- SpirvFunction.cpp - SPIR-V Function Implementation ------*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/SPIRV/SpirvFunction.h"
+
+namespace clang {
+namespace spirv {
+
+SpirvFunction::SpirvFunction(QualType type, uint32_t id,
+                             spv::FunctionControlMask control)
+    : functionType(type), functionId(id), functionControl(control) {}
+
+} // end namespace spirv
+} // end namespace clang

+ 30 - 4
tools/clang/lib/SPIRV/SpirvInstruction.cpp

@@ -15,16 +15,42 @@
 namespace clang {
 namespace spirv {
 
+bool SpirvInstruction::isTerminator() const {
+  switch (opcode) {
+  case spv::Op::OpBranch:
+  case spv::Op::OpBranchConditional:
+  case spv::Op::OpSwitch:
+  case spv::Op::OpReturn:
+  case spv::Op::OpReturnValue:
+  case spv::Op::OpKill:
+  case spv::Op::OpUnreachable:
+    return true;
+  deault:
+    break;
+  }
+
+  return false;
+}
+
+SpirvDecoration::SpirvDecoration(SourceLocation loc, spv::Decoration decor,
+                                 llvm::ArrayRef<uint32_t> p,
+                                 llvm::Optional<uint32_t> idx)
+    : SpirvInstruction(index.hasValue() ? spv::Op::OpMemberDecorate
+                                        : spv::Op::OpDecorate,
+                       /*type*/ {}, /*id*/ 0, loc),
+      decoration(decor), params(p.begin(), p.end()), index(idx) {}
+
 // Image query instructions constructor.
 SpirvImageQuery::SpirvImageQuery(spv::Op op, QualType type, uint32_t resultId,
                                  SourceLocation loc, uint32_t img,
                                  uint32_t lodId, uint32_t coordId)
     : SpirvInstruction(op, type, resultId, loc), image(img), lod(lodId),
       coordinate(coordId) {
-  assert(op == spv::Op::OpImageQueryFormat || spv::Op::OpImageQueryOrder ||
-         spv::Op::OpImageQuerySize || spv::Op::OpImageQueryLevels ||
-         spv::Op::OpImageQuerySamples || spv::Op::OpImageQueryLod ||
-         spv::Op::OpImageQuerySizeLod);
+  assert(op == spv::Op::OpImageQueryFormat ||
+         op == spv::Op::OpImageQueryOrder || op == spv::Op::OpImageQuerySize ||
+         op == spv::Op::OpImageQueryLevels ||
+         op == spv::Op::OpImageQuerySamples || op == spv::Op::OpImageQueryLod ||
+         op == spv::Op::OpImageQuerySizeLod);
   if (lodId)
     assert(op == spv::Op::OpImageQuerySizeLod);
   if (coordId)

+ 20 - 0
tools/clang/lib/SPIRV/SpirvModule.cpp

@@ -0,0 +1,20 @@
+//===--- SpirvModule.cpp - SPIR-V Module Implementation ----------*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/SPIRV/SpirvModule.h"
+
+namespace clang {
+namespace spirv {
+
+SpirvModule::SpirvModule()
+    : bound(1), memoryModel(nullptr), debugSource(nullptr) {}
+
+} // end namespace spirv
+} // end namespace clang
+