From 1e5ec5ca8c73e91c63b787e69c7286728f510b5e Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Wed, 4 Dec 2019 13:49:26 -0500 Subject: Setting downstream compiler (#1144) * WIP setting downstream compiler. * Setting default downstream compiler for a source type. --- source/slang/slang-compiler.cpp | 42 ++++++-------------- source/slang/slang-compiler.h | 10 +++++ source/slang/slang-diagnostic-defs.h | 5 ++- source/slang/slang-emit.cpp | 5 ++- source/slang/slang-options.cpp | 52 ++++++++++++++++++++++++ source/slang/slang-profile.h | 1 + source/slang/slang.cpp | 77 ++++++++++++++++++++++++++++++++++++ 7 files changed, 159 insertions(+), 33 deletions(-) (limited to 'source') diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index 64be1505e..1385118fc 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -1233,50 +1233,34 @@ SlangResult dissassembleDXILUsingDXC( { auto sink = slangRequest->getSink(); + auto session = slangRequest->getSession(); + const String originalSourcePath = calcSourcePathForEntryPoint(endToEndReq, entryPointIndex); outBin.clear(); outSharedLib.setNull(); - CPPCompilerSet* compilerSet = slangRequest->getSession()->requireCPPCompilerSet(); + PassThroughMode downstreamCompiler = endToEndReq->passThrough; - // Determine compiler to use - CPPCompiler* compiler = nullptr; - switch (endToEndReq->passThrough) + // If we are not in pass through, lookup the default compiler for the emitted source type + if (downstreamCompiler == PassThroughMode::None) { - case PassThroughMode::None: - case PassThroughMode::GenericCCpp: - { - // If there is no pass through... still need a compiler - compiler = compilerSet->getDefaultCompiler(); - break; - } - case PassThroughMode::Clang: - { - compiler = CPPCompilerUtil::findCompiler(compilerSet, CPPCompilerUtil::MatchType::Newest, CPPCompiler::Desc(CPPCompiler::CompilerType::Clang)); - break; - } - case PassThroughMode::VisualStudio: - { - compiler = CPPCompilerUtil::findCompiler(compilerSet, CPPCompilerUtil::MatchType::Newest, CPPCompiler::Desc(CPPCompiler::CompilerType::VisualStudio)); - break; - } - case PassThroughMode::Gcc: - { - compiler = CPPCompilerUtil::findCompiler(compilerSet, CPPCompilerUtil::MatchType::Newest, CPPCompiler::Desc(CPPCompiler::CompilerType::GCC)); - break; - } + downstreamCompiler = PassThroughMode(session->getDefaultDownstreamCompiler(SLANG_SOURCE_LANGUAGE_CPP)); } + + // Get the required downstream CPP compiler + CPPCompiler* compiler = session->getCPPCompiler(downstreamCompiler); if (!compiler) { - if (endToEndReq->passThrough != PassThroughMode::None) + auto compilerName = _getPassThroughAsText(downstreamCompiler); + if (downstreamCompiler != PassThroughMode::None) { - sink->diagnose(SourceLoc(), Diagnostics::passThroughCompilerNotFound, _getPassThroughAsText(endToEndReq->passThrough)); + sink->diagnose(SourceLoc(), Diagnostics::passThroughCompilerNotFound, compilerName); } else { - sink->diagnose(SourceLoc(), Diagnostics::cppCompilerNotFound); + sink->diagnose(SourceLoc(), Diagnostics::cppCompilerNotFound, compilerName); } return SLANG_FAIL; } diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index 1a2076c93..f125a4730 100644 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -1910,6 +1910,15 @@ namespace Slang SLANG_NO_THROW const char* SLANG_MCALL getBuildTagString() override; + SLANG_NO_THROW SlangResult SLANG_MCALL setDefaultDownstreamCompiler(SlangSourceLanguage sourceLanguage, SlangPassThrough defaultCompiler) override; + + SLANG_NO_THROW SlangPassThrough SLANG_MCALL getDefaultDownstreamCompiler(SlangSourceLanguage sourceLanguage) override; + + /// Get the specified compiler + CPPCompiler* getCPPCompiler(PassThroughMode downstreamCompiler); + /// Get the default cpp compiler for a language + CPPCompiler* getDefaultCPPCompiler(SourceLanguage sourceLanguage); + enum class SharedLibraryFuncType { Glslang_Compile, @@ -2065,6 +2074,7 @@ namespace Slang String m_downstreamCompilerPaths[int(PassThroughMode::CountOf)]; ///< Paths for each pass through String m_downstreamCompilerPreludes[int(PassThroughMode::CountOf)]; ///< Prelude for each type of target + PassThroughMode m_defaultDownstreamCompilers[int(SourceLanguage::CountOf)]; }; diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index 67b4be449..15d8b6fcd 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -116,9 +116,10 @@ DIAGNOSTIC( 84, Error, unableToReadModuleContainer, "unable to read module co DIAGNOSTIC( 85, Error, unableToAddReferenceToModuleContainer, "unable to add a reference to a module container"); DIAGNOSTIC( 86, Error, unableToCreateModuleContainer, "unable to create module container"); +DIAGNOSTIC( 87, Error, unableToSetDefaultDownstreamCompiler, "unable to set default downstream compiler for source language '%0' to '%1'"); // -// 1xxxx - Lexical anaylsis +// 1xxxx - Lexical analysis // DIAGNOSTIC(10000, Error, illegalCharacterPrint, "illegal character '$0'"); @@ -497,7 +498,7 @@ DIAGNOSTIC(52000, Error, multiLevelBreakUnsupported, "control flow appears to re DIAGNOSTIC(52001, Warning, dxilNotFound, "dxil shared library not found, so 'dxc' output cannot be signed! Shader code will not be runnable in non-development environments."); DIAGNOSTIC(52002, Error, passThroughCompilerNotFound, "Could not find a suitable pass-through compiler for '$0'."); -DIAGNOSTIC(52003, Error, cppCompilerNotFound, "Could not find a suitable C/C++ compiler."); +DIAGNOSTIC(52003, Error, cppCompilerNotFound, "Could not find a suitable C/C++ compiler for '$0'."); DIAGNOSTIC(52004, Error, unableToWriteFile, "Unable to write file '$0'"); DIAGNOSTIC(52005, Error, unableToReadFile, "Unable to read file '$0'"); diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index f4db3c5c1..710c1731f 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -581,8 +581,9 @@ String emitEntryPointSource( // If generic CPP work out what compiler will actually be used if (passThru == PassThroughMode::GenericCCpp) { - CPPCompilerSet* compilerSet = session->requireCPPCompilerSet(); - CPPCompiler* compiler = compilerSet->getDefaultCompiler(); + const SourceLanguage sourceLanguage = (sourceStyle == SourceStyle::C) ? SourceLanguage::C : SourceLanguage::CPP; + // Get the compiler used for the language + CPPCompiler* compiler = session->getDefaultCPPCompiler(sourceLanguage); if (compiler) { passThru = getPassThroughModeForCPPCompiler(compiler->getDesc().type); diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp index 92310c1c1..1523170cf 100644 --- a/source/slang/slang-options.cpp +++ b/source/slang/slang-options.cpp @@ -65,6 +65,31 @@ static SlangResult _parsePassThrough(const UnownedStringSlice& name, SlangPassTh return SLANG_FAIL; } +static SlangSourceLanguage _findSourceLanguage(const UnownedStringSlice& text) +{ + if (text == "c" || text == "C") + { + return SLANG_SOURCE_LANGUAGE_C; + } + else if (text == "cpp" || text == "c++" || text == "C++" || text == "cxx") + { + return SLANG_SOURCE_LANGUAGE_CPP; + } + else if (text == "slang") + { + return SLANG_SOURCE_LANGUAGE_SLANG; + } + else if (text == "glsl") + { + return SLANG_SOURCE_LANGUAGE_GLSL; + } + else if (text == "hlsl") + { + return SLANG_SOURCE_LANGUAGE_HLSL; + } + return SLANG_SOURCE_LANGUAGE_UNKNOWN; +} + UnownedStringSlice getPassThroughName(SlangPassThrough passThru) { #define SLANG_PASS_THROUGH_TYPE_TO_NAME(x, y) \ @@ -962,6 +987,33 @@ struct OptionsParser { requestImpl->getBackEndReq()->shouldEmitSPIRVDirectly = true; } + else if (argStr == "-default-downstream-compiler") + { + String sourceLanguageText; + SLANG_RETURN_ON_FAIL(tryReadCommandLineArgument(sink, arg, &argCursor, argEnd, sourceLanguageText)); + String compilerText; + SLANG_RETURN_ON_FAIL(tryReadCommandLineArgument(sink, arg, &argCursor, argEnd, compilerText)); + + SlangSourceLanguage sourceLanguage = _findSourceLanguage(sourceLanguageText.getUnownedSlice()); + if (sourceLanguage == SLANG_SOURCE_LANGUAGE_UNKNOWN) + { + sink->diagnose(SourceLoc(), Diagnostics::unknownSourceLanguage, sourceLanguageText); + return SLANG_FAIL; + } + + SlangPassThrough compiler; + if (SLANG_FAILED(_parsePassThrough(compilerText.getUnownedSlice(), compiler))) + { + sink->diagnose(SourceLoc(), Diagnostics::unknownPassThroughTarget, compilerText); + return SLANG_FAIL; + } + + if (SLANG_FAILED(session->setDefaultDownstreamCompiler(sourceLanguage, compiler))) + { + sink->diagnose(SourceLoc(), Diagnostics::unableToSetDefaultDownstreamCompiler, compilerText, sourceLanguageText, compilerText); + return SLANG_FAIL; + } + } else if (argStr == "--") { // The `--` option causes us to stop trying to parse options, diff --git a/source/slang/slang-profile.h b/source/slang/slang-profile.h index 7c801cc7e..b174245ba 100644 --- a/source/slang/slang-profile.h +++ b/source/slang/slang-profile.h @@ -15,6 +15,7 @@ namespace Slang GLSL = SLANG_SOURCE_LANGUAGE_GLSL, C = SLANG_SOURCE_LANGUAGE_C, CPP = SLANG_SOURCE_LANGUAGE_CPP, + CountOf = SLANG_SOURCE_LANGUAGE_COUNT_OF, }; // TODO(tfoley): This should merge with the above... diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 98ef7400e..72014ef77 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -99,6 +99,15 @@ Session::Session() addBuiltinSource(coreLanguageScope, "core", getCoreLibraryCode()); addBuiltinSource(hlslLanguageScope, "hlsl", getHLSLLibraryCode()); + + { + for (Index i = 0; i < Index(SourceLanguage::CountOf); ++i) + { + m_defaultDownstreamCompilers[i] = PassThroughMode::None; + } + m_defaultDownstreamCompilers[Index(SourceLanguage::C)] = PassThroughMode::GenericCCpp; + m_defaultDownstreamCompilers[Index(SourceLanguage::CPP)] = PassThroughMode::GenericCCpp; + } } ISlangUnknown* Session::getInterface(const Guid& guid) @@ -220,6 +229,74 @@ SLANG_NO_THROW const char* SLANG_MCALL Session::getBuildTagString() return SLANG_TAG_VERSION; } +static bool _canCompile(PassThroughMode compiler, SourceLanguage sourceLanguage) +{ + switch (compiler) + { + case PassThroughMode::Fxc: + case PassThroughMode::Dxc: + { + return sourceLanguage == SourceLanguage::HLSL; + } + case PassThroughMode::Glslang: + { + return sourceLanguage == SourceLanguage::GLSL; + } + case PassThroughMode::Clang: + case PassThroughMode::VisualStudio: + case PassThroughMode::Gcc: + case PassThroughMode::GenericCCpp: + { + return sourceLanguage == SourceLanguage::C || sourceLanguage == SourceLanguage::CPP; + } + default: break; + } + return false; +} + +SLANG_NO_THROW SlangResult SLANG_MCALL Session::setDefaultDownstreamCompiler(SlangSourceLanguage inSourceLanguage, SlangPassThrough defaultCompiler) +{ + auto sourceLanguage = SourceLanguage(inSourceLanguage); + auto compiler = PassThroughMode(defaultCompiler); + + if (sourceLanguage == SourceLanguage::C || sourceLanguage == SourceLanguage::CPP) + { + if (_canCompile(compiler, sourceLanguage)) + { + m_defaultDownstreamCompilers[int(sourceLanguage)] = compiler; + return SLANG_OK; + } + } + + return SLANG_FAIL; +} + +SlangPassThrough SLANG_MCALL Session::getDefaultDownstreamCompiler(SlangSourceLanguage inSourceLanguage) +{ + SLANG_ASSERT(inSourceLanguage >= 0 && inSourceLanguage < SLANG_SOURCE_LANGUAGE_COUNT_OF); + auto sourceLanguage = SourceLanguage(inSourceLanguage); + return SlangPassThrough(m_defaultDownstreamCompilers[int(sourceLanguage)]); +} + +CPPCompiler* Session::getCPPCompiler(PassThroughMode compiler) +{ + CPPCompilerSet* compilerSet = requireCPPCompilerSet(); + switch (compiler) + { + case PassThroughMode::GenericCCpp: return compilerSet->getDefaultCompiler(); + case PassThroughMode::Clang: return CPPCompilerUtil::findCompiler(compilerSet, CPPCompilerUtil::MatchType::Newest, CPPCompiler::Desc(CPPCompiler::CompilerType::Clang)); + case PassThroughMode::VisualStudio: return CPPCompilerUtil::findCompiler(compilerSet, CPPCompilerUtil::MatchType::Newest, CPPCompiler::Desc(CPPCompiler::CompilerType::VisualStudio)); + case PassThroughMode::Gcc: return CPPCompilerUtil::findCompiler(compilerSet, CPPCompilerUtil::MatchType::Newest, CPPCompiler::Desc(CPPCompiler::CompilerType::GCC)); + default: break; + } + return nullptr; +} + +CPPCompiler* Session::getDefaultCPPCompiler(SourceLanguage sourceLanguage) +{ + return getCPPCompiler(m_defaultDownstreamCompilers[int(sourceLanguage)]); +} + struct IncludeHandlerImpl : IncludeHandler { Linkage* linkage; -- cgit v1.2.3