2
0
Эх сурвалжийг харах

[spirv] Add custom type lowering for Variables.

Variables store the QualType of the value. In SPIR-V the result-type of
the variable should be a pointer with pointee that is value type.

Also fixed the wrapper function handling.
Ehsan Nasiri 6 жил өмнө
parent
commit
1e881bfc1e

+ 3 - 0
tools/clang/include/clang/SPIRV/LowerTypeVisitor.h

@@ -30,6 +30,9 @@ public:
   bool visit(SpirvFunction *, Phase);
   bool visit(SpirvBasicBlock *, Phase) { return true; }
 
+  // Custom visitor for variables. Variables must have a pointer result-type.
+  bool visit(SpirvVariable *);
+
   /// The "sink" visit function for all instructions.
   ///
   /// By default, all other visit instructions redirect to this visit function.

+ 1 - 1
tools/clang/include/clang/SPIRV/SPIRVContext.h

@@ -123,7 +123,7 @@ uint32_t SPIRVContext::takeNextId() { return nextId++; }
 // Mostly from DenseMapInfo<unsigned> in DenseMapInfo.h.
 struct StorageClassDenseMapInfo {
   static inline spv::StorageClass getEmptyKey() {
-    return spv::StorageClass::Function;
+    return spv::StorageClass::Max;
   }
   static inline spv::StorageClass getTombstoneKey() {
     return spv::StorageClass::Max;

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

@@ -69,6 +69,7 @@ public:
   // Returns the result-id of the OpTypeFunction
   uint32_t getFunctionTypeId() const { return fnTypeId; }
 
+  void setSourceLocation(SourceLocation loc) { functionLoc = loc; }
   SourceLocation getSourceLocation() const { return functionLoc; }
 
   void setConstainsAliasComponent(bool isAlias) { containsAlias = isAlias; }

+ 11 - 0
tools/clang/lib/SPIRV/LowerTypeVisitor.cpp

@@ -59,6 +59,17 @@ bool LowerTypeVisitor::visitInstruction(SpirvInstruction *instr) {
   return true;
 }
 
+bool LowerTypeVisitor::visit(SpirvVariable *var) {
+  if (!visitInstruction(var))
+    return false;
+
+  const SpirvType *valueType = var->getResultType();
+  const SpirvType *pointerType =
+      spvContext.getPointerType(valueType, var->getStorageClass());
+  var->setResultType(pointerType);
+  return true;
+}
+
 const SpirvType *LowerTypeVisitor::lowerType(const HybridType *hybrid,
                                              SpirvLayoutRule rule,
                                              SourceLocation loc) {

+ 5 - 4
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -1143,7 +1143,8 @@ void SPIRVEmitter::doFunctionDecl(const FunctionDecl *decl) {
   }
 
   auto *funcType = spvContext.getFunctionType(retType, paramTypes);
-  spvBuilder.beginFunction(retType, funcType, decl->getLocation(), funcName);
+  spvBuilder.beginFunction(retType, funcType, decl->getLocation(), funcName,
+                           func);
 
   if (isNonStaticMemberFn) {
     // Remember the parameter for the this object so later we can handle
@@ -9410,9 +9411,9 @@ bool SPIRVEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
   // The wrapper entry function surely does not have pre-assigned <result-id>
   // for it like other functions that got added to the work queue following
   // function calls. And the wrapper is the entry function.
-  entryFunction = spvBuilder.beginFunction(astContext.VoidTy, funcType,
-                                           /*SourceLocation*/ {},
-                                           decl->getName(), entryFuncInstr);
+  entryFunction =
+      spvBuilder.beginFunction(astContext.VoidTy, funcType,
+                               /*SourceLocation*/ {}, decl->getName());
   // Note this should happen before using declIdMapper for other tasks.
   declIdMapper.setEntryFunction(entryFunction);
 

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

@@ -35,6 +35,8 @@ SpirvFunction *SpirvBuilder::beginFunction(QualType returnType,
     function = func;
     function->setAstReturnType(returnType);
     function->setFunctionType(functionType);
+    function->setSourceLocation(loc);
+    function->setFunctionName(funcName);
   } else {
     function = new (context)
         SpirvFunction(returnType, functionType, /*id*/ 0,