Selaa lähdekoodia

Add target-dependent experimental function attribute (#759)

Tex Riddell 7 vuotta sitten
vanhempi
commit
694296b6b0

+ 8 - 0
tools/clang/include/clang/Basic/Attr.td

@@ -851,6 +851,14 @@ def HLSLShader : InheritableAttr {
   let Documentation = [Undocumented];
 }
 
+// Add experimental target-dependent attribute to function for backend ("exp-name"="value")
+def HLSLExperimental : InheritableAttr {
+  let Spellings = [CXX11<"", "experimental", 2017>];
+  let Args = [StringArgument<"name">, StringArgument<"value">];
+  let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedFunction">;
+  let Documentation = [Undocumented];
+}
+
 // HLSL Change Ends
 
 // SPIRV Change Starts

+ 5 - 0
tools/clang/lib/CodeGen/CGHLSLMS.cpp

@@ -1689,6 +1689,11 @@ void CGMSHLSLRuntime::AddHLSLFunctionInfo(Function *F, const FunctionDecl *FD) {
     Entry.SL = FD->getLocation();
     Entry.Func= F;
   }
+
+  // Add target-dependent experimental function attributes
+  for (const auto &Attr : FD->specific_attrs<HLSLExperimentalAttr>()) {
+    F->addFnAttr(Twine("exp-", Attr->getName()).str(), Attr->getValue());
+  }
 }
 
 void CGMSHLSLRuntime::EmitHLSLFunctionProlog(Function *F, const FunctionDecl *FD) {

+ 1 - 0
tools/clang/lib/Parse/ParseDecl.cpp

@@ -707,6 +707,7 @@ void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,
     case AttributeList::AT_HLSLMaxTessFactor:
     case AttributeList::AT_HLSLNumThreads:
     case AttributeList::AT_HLSLShader:
+    case AttributeList::AT_HLSLExperimental:
     case AttributeList::AT_HLSLRootSignature:
     case AttributeList::AT_HLSLOutputControlPoints:
     case AttributeList::AT_HLSLOutputTopology:

+ 23 - 6
tools/clang/lib/Sema/SemaHLSL.cpp

@@ -9888,10 +9888,13 @@ static void ValidateAttributeOnSwitchOrIf(Sema& S, Stmt* St, const AttributeList
   }
 }
 
-static StringRef ValidateAttributeStringArg(Sema& S, const AttributeList &A, _In_opt_z_ const char* values)
+static StringRef ValidateAttributeStringArg(Sema& S, const AttributeList &A, _In_opt_z_ const char* values, unsigned index = 0)
 {
   // values is an optional comma-separated list of potential values.
-  Expr* E = A.getArgAsExpr(0);
+  if (A.getNumArgs() <= index)
+    return StringRef();
+
+  Expr* E = A.getArgAsExpr(index);
   if (E->isTypeDependent() || E->isValueDependent() || E->getStmtClass() != Stmt::StringLiteralClass)
   {
     S.Diag(E->getLocStart(), diag::err_hlsl_attribute_expects_string_literal)
@@ -10150,9 +10153,14 @@ void hlsl::HandleDeclAttributeForHLSL(Sema &S, Decl *D, const AttributeList &A,
         A.getAttributeSpellingListIndex());
     break;
   case AttributeList::AT_HLSLMaxVertexCount:
-	  declAttr = ::new (S.Context) HLSLMaxVertexCountAttr(A.getRange(), S.Context,
-		  ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
-	  break;
+    declAttr = ::new (S.Context) HLSLMaxVertexCountAttr(A.getRange(), S.Context,
+      ValidateAttributeIntArg(S, A), A.getAttributeSpellingListIndex());
+    break;
+  case AttributeList::AT_HLSLExperimental:
+    declAttr = ::new (S.Context) HLSLExperimentalAttr(A.getRange(), S.Context,
+      ValidateAttributeStringArg(S, A, nullptr, 0), ValidateAttributeStringArg(S, A, nullptr, 1),
+      A.getAttributeSpellingListIndex());
+    break;
   default:
     Handled = false;
     break;  // SPIRV Change: was return;
@@ -11210,7 +11218,16 @@ void hlsl::CustomPrintHLSLAttr(const clang::Attr *A, llvm::raw_ostream &Out, con
     Out << "[shader(\"" << ACast->getStage() << "\")]\n";
     break;
   }
-  
+
+  case clang::attr::HLSLExperimental:
+  {
+    Attr * noconst = const_cast<Attr*>(A);
+    HLSLExperimentalAttr *ACast = static_cast<HLSLExperimentalAttr*>(noconst);
+    Indent(Indentation, Out);
+    Out << "[experimental(\"" << ACast->getName() << "\", \"" << ACast->getValue() << "\")]\n";
+    break;
+  }
+
   case clang::attr::HLSLMaxVertexCount:
   {
     Attr * noconst = const_cast<Attr*>(A);

+ 15 - 0
tools/clang/test/CodeGenHLSL/quick-test/fn_attr_experimental.hlsl

@@ -0,0 +1,15 @@
+// RUN: %dxc -T lib_6_1 %s | FileCheck %s
+
+// CHECK: define void
+// CHECK: fn1
+// @"\01?fn1@@YA?AV?$vector@M$03@@V1@@Z"
+// CHECK: #0
+// CHECK: attributes #0
+// CHECK: "exp-foo"="bar"
+// CHECK: "exp-zzz" "
+
+[experimental("foo", "bar")]
+[experimental("zzz", "")]
+float4 fn1(float4 Input){
+  return Input * 5.0f;
+}