diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2019-03-12 12:24:03 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-03-12 12:24:03 -0700 |
| commit | 3cfccfd4991df01deaf132f11b4eaa6848a32c4e (patch) | |
| tree | f94567d7e6f7601c67b7c201add21fc644ba18fd | |
| parent | 9722990745f4e91ab1bf9fb682c72e173cd123b4 (diff) | |
Add options to control optimization and debug information (#897)
The short version for command-line users is:
* Use `-g` to get debug info in the output, where supported
* Use `-O0` to disable optimizations, in case that improves debugability
* Use `-O2` for optimized/release builds where you can spend the extra compile time
The command-line options are matched with new API functions `spSetDebugInfoLevel()` and `spSetOptimizationLevel()` that set the equivalent information.
Right now these settings only affect how we invoke fxc and dxc. In the longer run I expect we will want to use them to control other things:
* Once we are emitting our own SPIR-V, the `-g` option should control what source-level name information we include in it.
* Whether or not `-g` is used could be used to decide whether we preserve the "name hints" in the IR, which in turn decide whether we output GLSL/HLSL source that uses names based on the original program.
* We will eventually need/want to include some amount of optimization passes on the Slang IR, and the `-O` options should control which of those passes are enabled on a particular invocation.
In this change I decided to expose the options at the level of the entire compile request for API users, and to store the actual information on the Linkage. We might want to revisit this decision and instead allow for the level of optimization to be chosen per-target as part of back-end state. Similarly, we might want to have more fine-grained control over the level of debug output per-target (although we'd still need a front-end setting to determine what debug info is generated into the Slang IR).
| -rw-r--r-- | docs/command-line-slangc.md | 8 | ||||
| -rw-r--r-- | slang.h | 34 | ||||
| -rw-r--r-- | source/slang/compiler.cpp | 22 | ||||
| -rw-r--r-- | source/slang/compiler.h | 20 | ||||
| -rw-r--r-- | source/slang/diagnostic-defs.h | 2 | ||||
| -rw-r--r-- | source/slang/dxc-support.cpp | 22 | ||||
| -rw-r--r-- | source/slang/options.cpp | 45 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 24 |
8 files changed, 176 insertions, 1 deletions
diff --git a/docs/command-line-slangc.md b/docs/command-line-slangc.md index 5e706f695..65ac7411b 100644 --- a/docs/command-line-slangc.md +++ b/docs/command-line-slangc.md @@ -135,6 +135,14 @@ For completeness, here are the options that `slangc` currently accepts: * `-verbose-paths`: When displaying diagnostic output aim to display more detailed path information. In practice this is typically the complete 'canonical' path to the source file used. +* `-g`: Include debug information in the generated code, where possible. Currently only supported for DXBC and DXIL output (not SPIR-V). + +* `-O`: Control optimization levels. This currently only affects DXBC and DXIL generation. + * `-O0`: Disable all optimizations + * `-O1`, `-O`: Enable a default level of optimization. This is the default if no `-O` options are used. + * `-O2`: Enable aggressive optimizations for speed. + * `-O3`: Enable further optimizations, which might have a significant impact on compile time, or involve unwanted tradeoffs in terms of code size. + * `--`: Stop parsing options, and treat the rest of the command line as input paths ### Specifying where dlls/shared libraries are loaded from @@ -535,7 +535,25 @@ extern "C" SLANG_STAGE_PIXEL = SLANG_STAGE_FRAGMENT, }; - + typedef SlangUInt32 SlangDebugInfoLevel; + enum + { + SLANG_DEBUG_INFO_LEVEL_NONE = 0, /**< Don't emit debug information at all. */ + SLANG_DEBUG_INFO_LEVEL_MINIMAL, /**< Emit as little debug information as possible, while still supporting stack trackes. */ + SLANG_DEBUG_INFO_LEVEL_STANDARD, /**< Emit whatever is the standard level of debug information for each target. */ + SLANG_DEBUG_INFO_LEVEL_MAXIMAL, /**< Emit as much debug infromation as possible for each target. */ + + }; + + typedef SlangUInt32 SlangOptimizationLevel; + enum + { + SLANG_OPTIMIZATION_LEVEL_NONE = 0, /**< Don't optimize at all. */ + SLANG_OPTIMIZATION_LEVEL_DEFAULT, /**< Default optimization level: balance code quality and compilation time. */ + SLANG_OPTIMIZATION_LEVEL_HIGH, /**< Optimize aggressively. */ + SLANG_OPTIMIZATION_LEVEL_MAXIMAL, /**< Include optimizations that may take a very long time, or may involve severe space-vs-speed tradeoffs */ + }; + /** A result code for a Slang API operation. This type is generally compatible with the Windows API `HRESULT` type. In particular, negative values indicate @@ -1103,6 +1121,20 @@ extern "C" SlangMatrixLayoutMode mode); /*! + @brief Set the level of debug information to produce. + */ + SLANG_API void spSetDebugInfoLevel( + SlangCompileRequest* request, + SlangDebugInfoLevel level); + + /*! + @brief Set the level of optimization to perform. + */ + SLANG_API void spSetOptimizationLevel( + SlangCompileRequest* request, + SlangOptimizationLevel level); + + /*! @brief Set the container format to be used for binary output. */ SLANG_API void spSetOutputContainerFormat( diff --git a/source/slang/compiler.cpp b/source/slang/compiler.cpp index bc4152244..1222d91d2 100644 --- a/source/slang/compiler.cpp +++ b/source/slang/compiler.cpp @@ -746,6 +746,28 @@ namespace Slang flags |= D3DCOMPILE_ENABLE_STRICTNESS; flags |= D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES; + auto linkage = compileRequest->getLinkage(); + switch( linkage->optimizationLevel ) + { + default: + break; + + case OptimizationLevel::None: flags |= D3DCOMPILE_OPTIMIZATION_LEVEL0; break; + case OptimizationLevel::Default: flags |= D3DCOMPILE_OPTIMIZATION_LEVEL1; break; + case OptimizationLevel::High: flags |= D3DCOMPILE_OPTIMIZATION_LEVEL2; break; + case OptimizationLevel::Maximal: flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3; break; + } + + switch( linkage->debugInfoLevel ) + { + case DebugInfoLevel::None: + break; + + default: + flags |= D3DCOMPILE_DEBUG; + break; + } + const String sourcePath = calcSourcePathForEntryPoint(endToEndReq, entryPointIndex); ComPtr<ID3DBlob> codeBlob; diff --git a/source/slang/compiler.h b/source/slang/compiler.h index 71cd0adbf..a0568a047 100644 --- a/source/slang/compiler.h +++ b/source/slang/compiler.h @@ -89,6 +89,22 @@ namespace Slang kMatrixLayoutMode_ColumnMajor = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR, }; + enum class DebugInfoLevel : SlangDebugInfoLevel + { + None = SLANG_DEBUG_INFO_LEVEL_NONE, + Minimal = SLANG_DEBUG_INFO_LEVEL_MINIMAL, + Standard = SLANG_DEBUG_INFO_LEVEL_STANDARD, + Maximal = SLANG_DEBUG_INFO_LEVEL_MAXIMAL, + }; + + enum class OptimizationLevel : SlangOptimizationLevel + { + None = SLANG_OPTIMIZATION_LEVEL_NONE, + Default = SLANG_OPTIMIZATION_LEVEL_DEFAULT, + High = SLANG_OPTIMIZATION_LEVEL_HIGH, + Maximal = SLANG_OPTIMIZATION_LEVEL_MAXIMAL, + }; + class Linkage; class Module; class Program; @@ -697,6 +713,10 @@ namespace Slang MatrixLayoutMode defaultMatrixLayoutMode = kMatrixLayoutMode_ColumnMajor; MatrixLayoutMode getDefaultMatrixLayoutMode() { return defaultMatrixLayoutMode; } + DebugInfoLevel debugInfoLevel = DebugInfoLevel::None; + + OptimizationLevel optimizationLevel = OptimizationLevel::Default; + private: Session* m_session = nullptr; diff --git a/source/slang/diagnostic-defs.h b/source/slang/diagnostic-defs.h index c773cc4ed..3947d8b19 100644 --- a/source/slang/diagnostic-defs.h +++ b/source/slang/diagnostic-defs.h @@ -74,6 +74,8 @@ DIAGNOSTIC( 21, Error, expectedArgumentForOption, "expected an argument for c DIAGNOSTIC( 24, Error, unknownLineDirectiveMode, "unknown '#line' directive mode '$0'"); DIAGNOSTIC( 25, Error, unknownFloatingPointMode, "unknown floating-point mode '$0'"); +DIAGNOSTIC( 26, Error, unknownOptimiziationLevel, "unknown optimization level '$0'"); +DIAGNOSTIC( 27, Error, uknownDebugInfoLevel, "unknown debug info level '$0'"); DIAGNOSTIC( 30, Warning, sameStageSpecifiedMoreThanOnce, "the stage '$0' was specified more than once for entry point '$1'") DIAGNOSTIC( 31, Error, conflictingStagesForEntryPoint, "conflicting stages have been specified for entry point '$0'") diff --git a/source/slang/dxc-support.cpp b/source/slang/dxc-support.cpp index 603a59ea7..cab94e74b 100644 --- a/source/slang/dxc-support.cpp +++ b/source/slang/dxc-support.cpp @@ -141,6 +141,28 @@ namespace Slang break; } + auto linkage = compileRequest->getLinkage(); + switch( linkage->optimizationLevel ) + { + default: + break; + + case OptimizationLevel::None: args[argCount++] = L"-Od"; break; + case OptimizationLevel::Default: args[argCount++] = L"-O1"; break; + case OptimizationLevel::High: args[argCount++] = L"-O2"; break; + case OptimizationLevel::Maximal: args[argCount++] = L"-O3"; break; + } + + switch( linkage->debugInfoLevel ) + { + case DebugInfoLevel::None: + break; + + default: + args[argCount++] = L"-Zi"; + break; + } + // Slang strives to produce correct code, and by default // we do not show the user warnings produced by a downstream // compiler. When the downstream compiler *does* produce an diff --git a/source/slang/options.cpp b/source/slang/options.cpp index 65fbfe068..a7334f13b 100644 --- a/source/slang/options.cpp +++ b/source/slang/options.cpp @@ -727,6 +727,51 @@ struct OptionsParser setFloatingPointMode(getCurrentTarget(), mode); } + else if( argStr[1] == 'O' ) + { + char const* name = arg + 2; + SlangOptimizationLevel level = SLANG_OPTIMIZATION_LEVEL_DEFAULT; + + bool invalidOptimizationLevel = strlen(name) > 2; + switch( name[0] ) + { + case '0': level = SLANG_OPTIMIZATION_LEVEL_NONE; break; + case '1': level = SLANG_OPTIMIZATION_LEVEL_DEFAULT; break; + case '2': level = SLANG_OPTIMIZATION_LEVEL_HIGH; break; + case '3': level = SLANG_OPTIMIZATION_LEVEL_MAXIMAL; break; + case 0 : level = SLANG_OPTIMIZATION_LEVEL_DEFAULT; break; + default: + invalidOptimizationLevel = true; + break; + } + if( invalidOptimizationLevel ) + { + sink->diagnose(SourceLoc(), Diagnostics::unknownOptimiziationLevel, name); + return SLANG_FAIL; + } + + spSetOptimizationLevel(compileRequest, level); + } + + // Note: unlike with `-O` above, we have to consider that other + // options might have names that start with `-g` and so cannot + // just detect it as a prefix. + else if( argStr == "-g" || argStr == "-g2" ) + { + spSetDebugInfoLevel(compileRequest, SLANG_DEBUG_INFO_LEVEL_STANDARD); + } + else if( argStr == "-g0" ) + { + spSetDebugInfoLevel(compileRequest, SLANG_DEBUG_INFO_LEVEL_NONE); + } + else if( argStr == "-g1" ) + { + spSetDebugInfoLevel(compileRequest, SLANG_DEBUG_INFO_LEVEL_MINIMAL); + } + else if( argStr == "-g3" ) + { + spSetDebugInfoLevel(compileRequest, SLANG_DEBUG_INFO_LEVEL_MAXIMAL); + } else if (argStr == "--") { // The `--` option causes us to stop trying to parse options, diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index e97f5bb1b..affce384b 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -1831,6 +1831,30 @@ SLANG_API void spSetTargetMatrixLayoutMode( spSetMatrixLayoutMode(request, mode); } +/*! +@brief Set the level of debug information to produce. +*/ +SLANG_API void spSetDebugInfoLevel( + SlangCompileRequest* request, + SlangDebugInfoLevel level) +{ + auto req = convert(request); + auto linkage = req->getLinkage(); + linkage->debugInfoLevel = Slang::DebugInfoLevel(level); +} + +/*! +@brief Set the level of optimization to perform. +*/ +SLANG_API void spSetOptimizationLevel( + SlangCompileRequest* request, + SlangOptimizationLevel level) +{ + auto req = convert(request); + auto linkage = req->getLinkage(); + linkage->optimizationLevel = Slang::OptimizationLevel(level); +} + SLANG_API void spSetOutputContainerFormat( SlangCompileRequest* request, |
