|
12 | 12 |
|
13 | 13 | #include "CGBuiltin.h" |
14 | 14 | #include "CGHLSLRuntime.h" |
| 15 | +#include "CodeGenFunction.h" |
15 | 16 |
|
16 | 17 | using namespace clang; |
17 | 18 | using namespace CodeGen; |
@@ -774,6 +775,77 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, |
774 | 775 | return EmitRuntimeCall( |
775 | 776 | Intrinsic::getOrInsertDeclaration(&CGM.getModule(), ID)); |
776 | 777 | } |
| 778 | + case Builtin::BI__builtin_get_spirv_spec_constant_bool: |
| 779 | + case Builtin::BI__builtin_get_spirv_spec_constant_short: |
| 780 | + case Builtin::BI__builtin_get_spirv_spec_constant_ushort: |
| 781 | + case Builtin::BI__builtin_get_spirv_spec_constant_int: |
| 782 | + case Builtin::BI__builtin_get_spirv_spec_constant_uint: |
| 783 | + case Builtin::BI__builtin_get_spirv_spec_constant_longlong: |
| 784 | + case Builtin::BI__builtin_get_spirv_spec_constant_ulonglong: |
| 785 | + case Builtin::BI__builtin_get_spirv_spec_constant_half: |
| 786 | + case Builtin::BI__builtin_get_spirv_spec_constant_float: |
| 787 | + case Builtin::BI__builtin_get_spirv_spec_constant_double: { |
| 788 | + llvm::Function *SpecConstantFn = getSpecConstantFunction(E->getType()); |
| 789 | + llvm::Value *SpecId = EmitScalarExpr(E->getArg(0)); |
| 790 | + llvm::Value *DefaultVal = EmitScalarExpr(E->getArg(1)); |
| 791 | + llvm::Value *Args[] = {SpecId, DefaultVal}; |
| 792 | + return Builder.CreateCall(SpecConstantFn, Args); |
| 793 | + } |
777 | 794 | } |
778 | 795 | return nullptr; |
779 | 796 | } |
| 797 | + |
| 798 | +llvm::Function *clang::CodeGen::CodeGenFunction::getSpecConstantFunction( |
| 799 | + const clang::QualType &SpecConstantType) { |
| 800 | + |
| 801 | + // Find or create the declaration for the function. |
| 802 | + llvm::Module *M = &CGM.getModule(); |
| 803 | + std::string MangledName = getSpecConstantFunctionName(SpecConstantType); |
| 804 | + llvm::Function *SpecConstantFn = M->getFunction(MangledName); |
| 805 | + |
| 806 | + if (!SpecConstantFn) { |
| 807 | + llvm::Type *IntType = ConvertType(getContext().IntTy); |
| 808 | + llvm::Type *RetTy = ConvertType(SpecConstantType); |
| 809 | + llvm::Type *ArgTypes[] = {IntType, RetTy}; |
| 810 | + llvm::FunctionType *FnTy = llvm::FunctionType::get(RetTy, ArgTypes, false); |
| 811 | + SpecConstantFn = llvm::Function::Create( |
| 812 | + FnTy, llvm::GlobalValue::ExternalLinkage, MangledName, M); |
| 813 | + } |
| 814 | + return SpecConstantFn; |
| 815 | +} |
| 816 | + |
| 817 | +std::string clang::CodeGen::CodeGenFunction::getSpecConstantFunctionName( |
| 818 | + const clang::QualType &SpecConstantType) { |
| 819 | + // The parameter types for our conceptual intrinsic function. |
| 820 | + ASTContext &Context = getContext(); |
| 821 | + QualType ClangParamTypes[] = {Context.IntTy, SpecConstantType}; |
| 822 | + |
| 823 | + // Create a temporary FunctionDecl for the builtin fuction. It won't be |
| 824 | + // added to the AST. |
| 825 | + FunctionProtoType::ExtProtoInfo EPI; |
| 826 | + QualType FnType = |
| 827 | + Context.getFunctionType(SpecConstantType, ClangParamTypes, EPI); |
| 828 | + DeclarationName FuncName = &Context.Idents.get("__spirv_SpecConstant"); |
| 829 | + FunctionDecl *FnDeclForMangling = FunctionDecl::Create( |
| 830 | + Context, Context.getTranslationUnitDecl(), SourceLocation(), |
| 831 | + SourceLocation(), FuncName, FnType, /*TSI=*/nullptr, SC_Extern); |
| 832 | + |
| 833 | + // Attach the created parameter declarations to the function declaration. |
| 834 | + SmallVector<ParmVarDecl *, 2> ParamDecls; |
| 835 | + for (QualType ParamType : ClangParamTypes) { |
| 836 | + ParmVarDecl *PD = ParmVarDecl::Create( |
| 837 | + Context, FnDeclForMangling, SourceLocation(), SourceLocation(), |
| 838 | + /*IdentifierInfo*/ nullptr, ParamType, /*TSI*/ nullptr, SC_None, |
| 839 | + /*DefaultArg*/ nullptr); |
| 840 | + ParamDecls.push_back(PD); |
| 841 | + } |
| 842 | + FnDeclForMangling->setParams(ParamDecls); |
| 843 | + |
| 844 | + // Get the mangled name. |
| 845 | + std::string Name; |
| 846 | + llvm::raw_string_ostream MangledNameStream(Name); |
| 847 | + MangleContext *Mangler = Context.createMangleContext(); |
| 848 | + Mangler->mangleName(FnDeclForMangling, MangledNameStream); |
| 849 | + MangledNameStream.flush(); |
| 850 | + return Name; |
| 851 | +} |
0 commit comments