Procházet zdrojové kódy

[spirv] Cleanup the createStageVars function.

This change tries to make this function less messy and uses QualType
rather than integer type-id as much as possible. This will help with
switching to the new infrastructure.
Ehsan před 6 roky
rodič
revize
622ba0d116
1 změnil soubory, kde provedl 44 přidání a 37 odebrání
  1. 44 37
      tools/clang/lib/SPIRV/DeclResultIdMapper.cpp

+ 44 - 37
tools/clang/lib/SPIRV/DeclResultIdMapper.cpp

@@ -1366,7 +1366,8 @@ bool DeclResultIdMapper::createStageVars(const hlsl::SigPoint *sigPoint,
     return true;
   }
 
-  uint32_t typeId = typeTranslator.translateType(type);
+  // The type the variable is evaluated as for SPIR-V.
+  QualType evalType = type;
 
   // We have several cases regarding HLSL semantics to handle here:
   // * If the currrent decl inherits a semantic from some enclosing entity,
@@ -1448,38 +1449,36 @@ bool DeclResultIdMapper::createStageVars(const hlsl::SigPoint *sigPoint,
                                 noWriteBack))
       return true;
 
-    const uint32_t srcTypeId = typeId; // Variable type in source code
-    const QualType srcQualType = type; // Variable type in source code
-    uint32_t srcVecElemTypeId = 0;     // Variable element type if vector
-
     switch (semanticKind) {
     case hlsl::Semantic::Kind::DomainLocation:
-      typeId = theBuilder.getVecType(theBuilder.getFloat32Type(), 3);
+      evalType = astContext.getExtVectorType(astContext.FloatTy, 3);
       break;
     case hlsl::Semantic::Kind::TessFactor:
-      typeId = theBuilder.getArrayType(theBuilder.getFloat32Type(),
-                                       theBuilder.getConstantUint32(4));
+      evalType = astContext.getConstantArrayType(
+          astContext.FloatTy, llvm::APInt(32, 4), clang::ArrayType::Normal, 0);
       break;
     case hlsl::Semantic::Kind::InsideTessFactor:
-      typeId = theBuilder.getArrayType(theBuilder.getFloat32Type(),
-                                       theBuilder.getConstantUint32(2));
+      evalType = astContext.getConstantArrayType(
+          astContext.FloatTy, llvm::APInt(32, 2), clang::ArrayType::Normal, 0);
       break;
     case hlsl::Semantic::Kind::Coverage:
-      typeId = theBuilder.getArrayType(typeId, theBuilder.getConstantUint32(1));
+      evalType = astContext.getConstantArrayType(astContext.UnsignedIntTy,
+                                                 llvm::APInt(32, 1),
+                                                 clang::ArrayType::Normal, 0);
       break;
     case hlsl::Semantic::Kind::InnerCoverage:
-      typeId = theBuilder.getBoolType();
+      evalType = astContext.BoolTy;
       break;
     case hlsl::Semantic::Kind::Barycentrics:
-      typeId = theBuilder.getVecType(theBuilder.getFloat32Type(), 2);
+      evalType = astContext.getExtVectorType(astContext.FloatTy, 2);
       break;
     case hlsl::Semantic::Kind::DispatchThreadID:
     case hlsl::Semantic::Kind::GroupThreadID:
     case hlsl::Semantic::Kind::GroupID:
       // Keep the original integer signedness
-      srcVecElemTypeId = typeTranslator.translateType(
-          hlsl::IsHLSLVecType(type) ? hlsl::GetHLSLVecElementType(type) : type);
-      typeId = theBuilder.getVecType(srcVecElemTypeId, 3);
+      evalType = astContext.getExtVectorType(
+          hlsl::IsHLSLVecType(type) ? hlsl::GetHLSLVecElementType(type) : type,
+          3);
       break;
     default:
       // Only the semantic kinds mentioned above are handled.
@@ -1489,18 +1488,19 @@ bool DeclResultIdMapper::createStageVars(const hlsl::SigPoint *sigPoint,
     // Boolean stage I/O variables must be represented as unsigned integers.
     // Boolean built-in variables are represented as bool.
     if (isBooleanStageIOVar(decl, type, semanticKind, sigPoint->GetKind())) {
-      type = typeTranslator.getUintTypeWithSourceComponents(type);
-      typeId = typeTranslator.translateType(type);
+      evalType = typeTranslator.getUintTypeWithSourceComponents(type);
     }
 
     // Handle the extra arrayness
-    const uint32_t elementTypeId = typeId; // Array element's type
-    if (arraySize != 0)
-      typeId = theBuilder.getArrayType(typeId,
-                                       theBuilder.getConstantUint32(arraySize));
+    if (arraySize != 0) {
+      evalType = astContext.getConstantArrayType(
+          evalType, llvm::APInt(32, arraySize), clang::ArrayType::Normal, 0);
+    }
+
+    const uint32_t evalTypeId = typeTranslator.translateType(evalType);
 
     StageVar stageVar(
-        sigPoint, *semanticToUse, builtinAttr, typeId,
+        sigPoint, *semanticToUse, builtinAttr, evalTypeId,
         // For HS/DS/GS, we have already stripped the outmost arrayness on type.
         typeTranslator.getLocationCount(type));
     const auto name = namePrefix.str() + "." + stageVar.getSemanticStr();
@@ -1545,7 +1545,7 @@ bool DeclResultIdMapper::createStageVars(const hlsl::SigPoint *sigPoint,
       decoratePSInterpolationMode(decl, type, varId);
 
     if (asInput) {
-      *value = theBuilder.createLoad(typeId, varId);
+      *value = theBuilder.createLoad(evalTypeId, varId);
 
       // Fix ups for corner cases
 
@@ -1594,7 +1594,8 @@ bool DeclResultIdMapper::createStageVars(const hlsl::SigPoint *sigPoint,
       // Special handling of SV_Coverage, which is an uint value. We need to
       // read SampleMask and extract its first element.
       else if (semanticKind == hlsl::Semantic::Kind::Coverage) {
-        *value = theBuilder.createCompositeExtract(srcTypeId, *value, {0});
+        *value = theBuilder.createCompositeExtract(
+            typeTranslator.translateType(type), *value, {0});
       }
       // Special handling of SV_InnerCoverage, which is an uint value. We need
       // to read FullyCoveredEXT, which is a boolean value, and convert it to an
@@ -1636,7 +1637,9 @@ bool DeclResultIdMapper::createStageVars(const hlsl::SigPoint *sigPoint,
                 semanticKind == hlsl::Semantic::Kind::GroupID) &&
                (!hlsl::IsHLSLVecType(type) ||
                 hlsl::GetHLSLVecSize(type) != 3)) {
-        assert(srcVecElemTypeId);
+        const uint32_t srcVecElemTypeId = typeTranslator.translateType(
+            hlsl::IsHLSLVecType(type) ? hlsl::GetHLSLVecElementType(type)
+                                      : type);
         const auto vecSize =
             hlsl::IsHLSLVecType(type) ? hlsl::GetHLSLVecSize(type) : 1;
         if (vecSize == 1)
@@ -1654,10 +1657,9 @@ bool DeclResultIdMapper::createStageVars(const hlsl::SigPoint *sigPoint,
 
       // Since boolean stage input variables are represented as unsigned
       // integers, after loading them, we should cast them to boolean.
-      if (isBooleanStageIOVar(decl, srcQualType, semanticKind,
-                              sigPoint->GetKind())) {
-        *value = theEmitter.castToType(*value, type, srcQualType,
-                                       decl->getLocation());
+      if (isBooleanStageIOVar(decl, type, semanticKind, sigPoint->GetKind())) {
+        *value =
+            theEmitter.castToType(*value, evalType, type, decl->getLocation());
       }
     } else {
       if (noWriteBack)
@@ -1706,7 +1708,8 @@ bool DeclResultIdMapper::createStageVars(const hlsl::SigPoint *sigPoint,
       // write it to the first element in the SampleMask builtin.
       else if (semanticKind == hlsl::Semantic::Kind::Coverage) {
         ptr = theBuilder.createAccessChain(
-            theBuilder.getPointerType(srcTypeId, spv::StorageClass::Output),
+            theBuilder.getPointerType(typeTranslator.translateType(type),
+                                      spv::StorageClass::Output),
             varId, theBuilder.getConstantUint32(0));
         theBuilder.createStore(ptr, *value);
       }
@@ -1714,6 +1717,10 @@ bool DeclResultIdMapper::createStageVars(const hlsl::SigPoint *sigPoint,
       // element in the per-vertex data array: the one indexed by
       // SV_ControlPointID.
       else if (invocationId.hasValue()) {
+        // Remove the arrayness to get the element type.
+        assert(isa<ConstantArrayType>(evalType));
+        const uint32_t elementTypeId = typeTranslator.translateType(
+            astContext.getAsArrayType(evalType)->getElementType());
         const uint32_t ptrType =
             theBuilder.getPointerType(elementTypeId, spv::StorageClass::Output);
         const uint32_t index = invocationId.getValue();
@@ -1722,10 +1729,10 @@ bool DeclResultIdMapper::createStageVars(const hlsl::SigPoint *sigPoint,
       }
       // Since boolean output stage variables are represented as unsigned
       // integers, we must cast the value to uint before storing.
-      else if (isBooleanStageIOVar(decl, srcQualType, semanticKind,
+      else if (isBooleanStageIOVar(decl, type, semanticKind,
                                    sigPoint->GetKind())) {
-        *value = theEmitter.castToType(*value, srcQualType, type,
-                                       decl->getLocation());
+        *value =
+            theEmitter.castToType(*value, type, evalType, decl->getLocation());
         theBuilder.createStore(ptr, *value);
       }
       // For all normal cases
@@ -1777,7 +1784,8 @@ bool DeclResultIdMapper::createStageVars(const hlsl::SigPoint *sigPoint,
     }
 
     if (arraySize == 0) {
-      *value = theBuilder.createCompositeConstruct(typeId, subValues);
+      *value = theBuilder.createCompositeConstruct(
+          typeTranslator.translateType(evalType), subValues);
       return true;
     }
 
@@ -2195,8 +2203,7 @@ uint32_t DeclResultIdMapper::createSpirvStageVar(StageVar *stageVar,
   }
   // According to DXIL spec, the ClipDistance/CullDistance SV can be used by all
   // SigPoints other than PCIn, HSIn, GSIn, PSOut, CSIn.
-  // According to Vulkan spec, the ClipDistance/CullDistance BuiltIn can only
-  // be
+  // According to Vulkan spec, the ClipDistance/CullDistance BuiltIn can only be
   // used by VSOut, HS/DS/GS In/Out.
   case hlsl::Semantic::Kind::ClipDistance:
   case hlsl::Semantic::Kind::CullDistance: {