diff options
| author | Yong He <yonghe@outlook.com> | 2024-02-20 12:24:00 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-20 12:24:00 -0800 |
| commit | 4d20fd329956ac89408b1628a8291fea01bc9a6d (patch) | |
| tree | 8e62d9c1ec05142fd25d0b31073fdb56d44691b0 /source | |
| parent | 8e9b61e3bac69dbb37a1451b62302e688a017ced (diff) | |
Refactor compiler option representations. (#3598)
* Refactor compiler option representation.
* Fix binary compatibility.
* Add a test for specifying compiler options at link time.
* Fix binary compatibility.
* Fix binary compatibility.
* Fix backward compatibility on matrix layout.
* Fix.
* Fix.
* Fix.
* Fix gfx.
* Fix gfx.
* Fix dynamic dispatch.
* Polish.
Diffstat (limited to 'source')
79 files changed, 1663 insertions, 1267 deletions
diff --git a/source/compiler-core/slang-command-line-args.cpp b/source/compiler-core/slang-command-line-args.cpp index 813d2dd26..b69836030 100644 --- a/source/compiler-core/slang-command-line-args.cpp +++ b/source/compiler-core/slang-command-line-args.cpp @@ -2,7 +2,8 @@ #include "../core/slang-process-util.h" #include "../core/slang-string-escape-util.h" - +#include "../core/slang-string-util.h" +#include "../core/slang-type-text-util.h" #include "slang-core-diagnostics.h" namespace Slang { @@ -63,6 +64,27 @@ bool CommandLineArgs::hasArgs(const char*const* args, Index count) const return true; } +String CommandLineArgs::serialize() +{ + StringBuilder sb; + for (auto& arg : m_args) + sb << arg.value << "\n"; + return sb.produceString(); +} + +void CommandLineArgs::deserialize(String content) +{ + List<UnownedStringSlice> slices; + StringUtil::split(content.getUnownedSlice(), '\n', slices); + for (auto arg : slices) + { + Arg v; + v.value = arg; + v.loc = SourceLoc(); + m_args.add(v); + } +} + /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CommandLineReader @@ -118,6 +140,24 @@ SlangResult CommandLineReader::expectArg(CommandLineArg& outArg) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ +DownstreamArgs::DownstreamArgs(CommandLineContext* context) + : m_context(context) +{ + // Add all of the possible names we allow for downstream tools + { + for (Index i = SLANG_PASS_THROUGH_NONE + 1; i < SLANG_PASS_THROUGH_COUNT_OF; ++i) + { + addName(TypeTextUtil::getPassThroughName(SlangPassThrough(i))); + } + + // Generic downstream tool + addName("downstream"); + // Generic downstream linker + addName("linker"); + } +} + + Index DownstreamArgs::addName(const String& name) { Index index = findName(name); diff --git a/source/compiler-core/slang-command-line-args.h b/source/compiler-core/slang-command-line-args.h index b2bd48c61..0c11a3c46 100644 --- a/source/compiler-core/slang-command-line-args.h +++ b/source/compiler-core/slang-command-line-args.h @@ -69,6 +69,9 @@ struct CommandLineArgs //String m_executablePath; ///< Can be optionally be set List<Arg> m_args; ///< The args RefPtr<CommandLineContext> m_context; ///< The context, which mainly has source manager + + String serialize(); + void deserialize(String content); }; struct CommandLineReader @@ -155,18 +158,16 @@ struct DownstreamArgs CommandLineContext* getContext() const { return m_context; } /// Ctor - DownstreamArgs(CommandLineContext* context): - m_context(context) - { - } + DownstreamArgs(CommandLineContext* context); + /// Default ctor - for convenience, should really use with context normally DownstreamArgs() {} + List<Entry> m_entries; ///< All of the entries + protected: Index _findOrAddName(SourceLoc loc, const UnownedStringSlice& name, Flags flags, DiagnosticSink* sink); - List<Entry> m_entries; ///< All of the entries - RefPtr<CommandLineContext> m_context; ///< The context that is being used (primarily for loc tracking) across all entries/args }; diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index f1409efe1..3fb2725e2 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -1687,7 +1687,7 @@ namespace Slang } } - if (getLinkage()->getAllowGLSLInput()) + if (getModuleDecl(varDecl)->hasModifier<GLSLModuleModifier>()) { // If we are in GLSL compatiblity mode, we want to treat all global variables // without any `uniform` modifiers as true global variables by default. diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h index 28ed47c53..3af85b73d 100644 --- a/source/slang/slang-check-impl.h +++ b/source/slang/slang-check-impl.h @@ -563,6 +563,11 @@ namespace Slang return m_sink; } + CompilerOptionSet& getOptionSet() + { + return m_linkage->m_optionSet; + } + // We need to track what has been `import`ed into // the scope of this semantic checking session, // and also to avoid importing the same thing more @@ -975,7 +980,10 @@ namespace Slang : Super(context) {} - + CompilerOptionSet& getOptionSet() + { + return getShared()->getOptionSet(); + } public: // Translate Types diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp index 2627ab8e8..9117eb6ec 100644 --- a/source/slang/slang-check-modifier.cpp +++ b/source/slang/slang-check-modifier.cpp @@ -1162,7 +1162,7 @@ namespace Slang if (auto decl = as<Decl>(syntaxNode)) { auto moduleDecl = getModuleDecl(decl); - bool isGLSLInput = getLinkage()->getAllowGLSLInput(); + bool isGLSLInput = getOptionSet().getBoolOption(CompilerOptionName::AllowGLSL); if (!isGLSLInput && moduleDecl && moduleDecl->findModifier<GLSLModuleModifier>()) isGLSLInput = true; if (!isModifierAllowedOnDecl(isGLSLInput, m->astNodeType, decl)) diff --git a/source/slang/slang-compiler-options.cpp b/source/slang/slang-compiler-options.cpp new file mode 100644 index 000000000..aca5fb8db --- /dev/null +++ b/source/slang/slang-compiler-options.cpp @@ -0,0 +1,226 @@ +#include "slang-compiler-options.h" +#include "slang-compiler.h" + +namespace Slang +{ + void CompilerOptionSet::load(uint32_t count, slang::CompilerOptionEntry* entries) + { + for (uint32_t i = 0; i < count; i++) + { + CompilerOptionValue value; + value.kind = entries[i].value.kind; + value.intValue = entries[i].value.intValue0; + value.intValue2 = entries[i].value.intValue1; + if (value.kind == CompilerOptionValueKind::String) + { + value.stringValue = entries[i].value.stringValue0; + value.stringValue2 = entries[i].value.stringValue1; + } + add(entries[i].name, value); + } + } + + void CompilerOptionSet::buildHash(DigestBuilder<SHA1>& builder) + { + for (auto& kv : options) + { + builder.append(kv.key); + builder.append(kv.value.getCount()); + for (auto& v : kv.value) + { + if (v.kind == CompilerOptionValueKind::Int) + { + builder.append(v.intValue); + } + else + { + builder.append(v.stringValue); + builder.append(v.stringValue2); + } + } + } + } + + bool CompilerOptionSet::allowDuplicate(CompilerOptionName name) + { + switch (name) + { + case CompilerOptionName::Include: + case CompilerOptionName::MacroDefine: + case CompilerOptionName::WarningsAsErrors: + case CompilerOptionName::DisableWarning: + case CompilerOptionName::DisableWarnings: + case CompilerOptionName::EnableWarning: + case CompilerOptionName::Capability: + case CompilerOptionName::DownstreamArgs: + case CompilerOptionName::VulkanBindShift: + case CompilerOptionName::VulkanBindShiftAll: + return true; + } + return false; + } + CompilerOptionValue Slang::CompilerOptionSet::getDefault(CompilerOptionName name) + { + switch (name) + { + case CompilerOptionName::Optimization: + return CompilerOptionValue::fromEnum(OptimizationLevel::Default); + default: + return CompilerOptionValue(); + } + } + + SlangTargetFlags CompilerOptionSet::getTargetFlags() + { + SlangTargetFlags result = 0; + if (getBoolOption(CompilerOptionName::DumpIr)) + result |= SLANG_TARGET_FLAG_DUMP_IR; + if (getBoolOption(CompilerOptionName::GenerateWholeProgram)) + result |= SLANG_TARGET_FLAG_GENERATE_WHOLE_PROGRAM; + if (getBoolOption(CompilerOptionName::EmitSpirvDirectly)) + result |= SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY; + if (getBoolOption(CompilerOptionName::ParameterBlocksUseRegisterSpaces)) + result |= SLANG_TARGET_FLAG_PARAMETER_BLOCKS_USE_REGISTER_SPACES; + return result; + } + + void CompilerOptionSet::setTargetFlags(SlangTargetFlags flags) + { + set(CompilerOptionName::DumpIr, (flags & SLANG_TARGET_FLAG_DUMP_IR) != 0); + set(CompilerOptionName::GenerateWholeProgram, (flags & SLANG_TARGET_FLAG_GENERATE_WHOLE_PROGRAM) != 0); + set(CompilerOptionName::EmitSpirvDirectly, (flags & SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY) != 0); + set(CompilerOptionName::ParameterBlocksUseRegisterSpaces, (flags & SLANG_TARGET_FLAG_PARAMETER_BLOCKS_USE_REGISTER_SPACES) != 0); + } + + void CompilerOptionSet::addTargetFlags(SlangTargetFlags flags) + { + if ((flags & SLANG_TARGET_FLAG_DUMP_IR)) + set(CompilerOptionName::DumpIr, true); + + if ((flags & SLANG_TARGET_FLAG_GENERATE_WHOLE_PROGRAM) != 0) + set(CompilerOptionName::GenerateWholeProgram, true); + + if ((flags & SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY) != 0) + set(CompilerOptionName::EmitSpirvDirectly, true); + + if ((flags & SLANG_TARGET_FLAG_PARAMETER_BLOCKS_USE_REGISTER_SPACES) != 0) + set(CompilerOptionName::ParameterBlocksUseRegisterSpaces, true); + } + MatrixLayoutMode CompilerOptionSet::getMatrixLayoutMode() + { + if (getBoolOption(CompilerOptionName::MatrixLayoutRow)) + return kMatrixLayoutMode_RowMajor; + if (getBoolOption(CompilerOptionName::MatrixLayoutColumn)) + return kMatrixLayoutMode_ColumnMajor; + + return (MatrixLayoutMode)kMatrixLayoutMode_RowMajor; + } + + void CompilerOptionSet::setMatrixLayoutMode(MatrixLayoutMode mode) + { + options.remove(CompilerOptionName::MatrixLayoutColumn); + options.remove(CompilerOptionName::MatrixLayoutRow); + if (mode == kMatrixLayoutMode_ColumnMajor) + set(CompilerOptionName::MatrixLayoutColumn, true); + if (mode == kMatrixLayoutMode_RowMajor) + set(CompilerOptionName::MatrixLayoutRow, true); + } + + Profile CompilerOptionSet::getProfile() + { + if (auto profileRaw = getEnumOption<Profile::RawEnum>(CompilerOptionName::Profile)) + return Profile(profileRaw); + return Profile(); + } + + void CompilerOptionSet::setProfile(Profile profile) + { + set(CompilerOptionName::Profile, (int)profile.raw); + } + + ProfileVersion CompilerOptionSet::getProfileVersion() + { + if (auto profileRaw = getEnumOption<Profile::RawEnum>(CompilerOptionName::Profile)) + return Profile(profileRaw).getVersion(); + return ProfileVersion::Unknown; + } + + void CompilerOptionSet::setProfileVersion(ProfileVersion version) + { + Profile profile; + if (auto profileRaw = getEnumOption<Profile::RawEnum>(CompilerOptionName::Profile)) + profile = Profile(profileRaw); + profile.setVersion(version); + set(CompilerOptionName::Profile, (int)profile.raw); + } + + void CompilerOptionSet::addCapabilityAtom(CapabilityName cap) + { + add(CompilerOptionName::Capability, cap); + } + + List<String> CompilerOptionSet::getDownstreamArgs(String downstreamToolName) + { + List<String> result; + auto downstreamArgsArray = getArray(CompilerOptionName::DownstreamArgs); + for (auto& argSet : downstreamArgsArray) + { + if (argSet.stringValue == downstreamToolName) + { + CommandLineArgs args; + args.deserialize(argSet.stringValue2); + for (auto arg : args.m_args) + result.add(arg.value); + break; + } + } + return result; + } + + void CompilerOptionSet::serialize(SerializedOptionsData* outData) + { + for (auto& option : options) + { + for (auto val : option.value) + { + slang::CompilerOptionEntry entry = {}; + entry.name = option.key; + entry.value.kind = val.kind; + entry.value.intValue0 = val.intValue; + entry.value.intValue1 = val.intValue2; + outData->stringPool.add(val.stringValue); + entry.value.stringValue0 = val.stringValue.getBuffer(); + outData->stringPool.add(val.stringValue2); + entry.value.stringValue1 = val.stringValue.getBuffer(); + outData->entries.add(entry); + } + } + } + + void applySettingsToDiagnosticSink(DiagnosticSink* targetSink, DiagnosticSink* outputSink, CompilerOptionSet& options) + { + auto disableArray = options.getArray(CompilerOptionName::DisableWarning); + for (auto& element : disableArray) + { + overrideDiagnostic(targetSink, outputSink, element.stringValue.getUnownedSlice(), Severity::Warning, Severity::Disable); + } + disableArray = options.getArray(CompilerOptionName::DisableWarnings); + for (auto& element : disableArray) + { + overrideDiagnostics(targetSink, outputSink, element.stringValue.getUnownedSlice(), Severity::Warning, Severity::Disable); + } + auto enableArray = options.getArray(CompilerOptionName::EnableWarning); + for (auto& element : enableArray) + { + overrideDiagnostics(targetSink, outputSink, element.stringValue.getUnownedSlice(), Severity::Warning, Severity::Warning); + } + auto warningsAsErrorsArray = options.getArray(CompilerOptionName::WarningsAsErrors); + for (auto& element : warningsAsErrorsArray) + { + if (element.stringValue == "all") + targetSink->setFlag(DiagnosticSink::Flag::TreatWarningsAsErrors); + else + overrideDiagnostics(targetSink, outputSink, element.stringValue.getUnownedSlice(), Severity::Warning, Severity::Error); + } + } +} diff --git a/source/slang/slang-compiler-options.h b/source/slang/slang-compiler-options.h new file mode 100644 index 000000000..0b35f9a29 --- /dev/null +++ b/source/slang/slang-compiler-options.h @@ -0,0 +1,393 @@ +#ifndef SLANG_COMPILER_OPTIONS_H +#define SLANG_COMPILER_OPTIONS_H + +#include "../../slang.h" +#include "../core/slang-basic.h" +#include "../core/slang-crypto.h" +#include "slang-generated-capability-defs.h" +#include "slang-profile.h" + +namespace Slang +{ + using slang::CompilerOptionName; + using slang::CompilerOptionValueKind; + enum MatrixLayoutMode : SlangMatrixLayoutModeIntegral; + enum class LineDirectiveMode : SlangLineDirectiveModeIntegral; + enum class FloatingPointMode : SlangFloatingPointModeIntegral; + enum class OptimizationLevel : SlangOptimizationLevelIntegral; + enum class DebugInfoLevel : SlangDebugInfoLevelIntegral; + enum class CodeGenTarget : SlangCompileTargetIntegral; + + struct CompilerOptionValue + { + CompilerOptionValueKind kind = CompilerOptionValueKind::Int; + int intValue = 0; + int intValue2 = 0; + String stringValue; + String stringValue2; + + template<typename T> + static CompilerOptionValue fromEnum(T val) + { + static_assert(std::is_enum<T>::value); + CompilerOptionValue value; + value.intValue = (int)val; + value.kind = CompilerOptionValueKind::Int; + return value; + } + + static CompilerOptionValue fromInt(int val) + { + CompilerOptionValue value; + value.intValue = val; + value.kind = CompilerOptionValueKind::Int; + return value; + } + + static CompilerOptionValue fromInt2(int val, int val2) + { + CompilerOptionValue value; + value.intValue = val; + value.intValue2 = val2; + value.kind = CompilerOptionValueKind::Int; + return value; + } + + void unpackInt3(uint8_t& v0, int& v1, int& v2) + { + v0 = intValue >> 24; + v1 = intValue & 0xFFFFFF; + v2 = intValue2; + } + + static CompilerOptionValue fromInt3(uint8_t v0, int v1, int v2) + { + CompilerOptionValue value; + value.intValue = (v0 << 24) + (v1 & 0xFFFFFF); + value.intValue2 = v2; + value.kind = CompilerOptionValueKind::Int; + return value; + } + + static CompilerOptionValue fromString(String val) + { + CompilerOptionValue value; + value.stringValue = val; + value.kind = CompilerOptionValueKind::String; + return value; + } + }; + + struct SerializedOptionsData + { + List<slang::CompilerOptionEntry> entries; + List<String> stringPool; + }; + + struct CompilerOptionSet + { + void load(uint32_t count, slang::CompilerOptionEntry* entries); + + void buildHash(DigestBuilder<SHA1>& builder); + + static bool allowDuplicate(CompilerOptionName name); + + OrderedDictionary<CompilerOptionName, List<CompilerOptionValue>> options; + + bool hasOption(CompilerOptionName name) + { + return options.containsKey(name); + } + + void set(CompilerOptionName name, CompilerOptionValue value) + { + if (auto v = options.tryGetValue(name)) + { + v->clear(); + v->add(value); + return; + } + options[name] = List<CompilerOptionValue>{ value }; + } + + void set(CompilerOptionName name, const List<CompilerOptionValue>& value) + { + if (auto v = options.tryGetValue(name)) + { + v->clear(); + v->addRange(value); + return; + } + options[name] = List<CompilerOptionValue>{ value }; + } + + void add(CompilerOptionName name, CompilerOptionValue value) + { + if (auto v = options.tryGetValue(name)) + { + v->add(value); + return; + } + options[name] = List<CompilerOptionValue>{ value }; + } + + void add(CompilerOptionName name, const List<CompilerOptionValue>& value, bool replaceDuplicate = true) + { + if (auto v = options.tryGetValue(name)) + { + for (auto element : value) + { + Index index = -1; + // We don't deduplicate downstream args. + if (name != CompilerOptionName::DownstreamArgs) + { + v->findFirstIndex([&](const CompilerOptionValue& existingVal) + { + if (existingVal.kind == CompilerOptionValueKind::Int) + return existingVal.intValue == element.intValue; + else + return existingVal.stringValue == element.stringValue; + }); + } + if (index != -1) + { + if (replaceDuplicate) + { + (*v)[index].intValue2 = element.intValue; + (*v)[index].stringValue2 = element.stringValue2; + } + } + else + { + v->add(element); + } + } + return; + } + options[name] = List<CompilerOptionValue>{ value }; + } + + // Copy settings from other, and replace the current setting. + void overrideWith(const CompilerOptionSet& other) + { + for (auto& kv : other.options) + { + if (allowDuplicate(kv.key)) + add(kv.key, kv.value, true); + else + set(kv.key, kv.value); + } + } + + // Copy settings from other, but do not replace the current setting + void inheritFrom(const CompilerOptionSet& other) + { + for (auto& kv : other.options) + { + if (allowDuplicate(kv.key)) + add(kv.key, kv.value, false); + else + { + if (options.containsKey(kv.key)) + continue; + set(kv.key, kv.value); + } + } + } + + void add(CompilerOptionName name, int intVal) + { + add(name, CompilerOptionValue::fromInt(intVal)); + } + void add(CompilerOptionName name, int intVal, int intVal2) + { + add(name, CompilerOptionValue::fromInt2(intVal, intVal2)); + } + void add(CompilerOptionName name, uint8_t intVal, int intVal2, int intVal3) + { + add(name, CompilerOptionValue::fromInt3(intVal, intVal2, intVal3)); + } + void add(CompilerOptionName name, String stringVal) + { + add(name, CompilerOptionValue::fromString(stringVal)); + } + void add(CompilerOptionName name, UnownedStringSlice stringVal) + { + add(name, CompilerOptionValue::fromString(stringVal)); + } + void add(CompilerOptionName name, bool boolVal) + { + add(name, CompilerOptionValue::fromInt(boolVal ? 1 : 0)); + } + + template<typename EnumType> + void add(CompilerOptionName name, EnumType enumVal) + { + static_assert(std::is_enum<EnumType>::value); + add(name, (int)enumVal); + } + + void set(CompilerOptionName name, int intVal) + { + set(name, CompilerOptionValue::fromInt(intVal)); + } + void set(CompilerOptionName name, int intVal1, int intVal2) + { + set(name, CompilerOptionValue::fromInt2(intVal1, intVal2)); + } + void set(CompilerOptionName name, uint8_t intVal1, int intVal2, int intVal3) + { + set(name, CompilerOptionValue::fromInt3(intVal1, intVal2, intVal3)); + } + void set(CompilerOptionName name, String stringVal) + { + set(name, CompilerOptionValue::fromString(stringVal)); + } + void set(CompilerOptionName name, bool boolVal) + { + set(name, CompilerOptionValue::fromInt(boolVal ? 1 : 0)); + } + + template<typename EnumType> + void set(CompilerOptionName name, EnumType enumVal) + { + static_assert(std::is_enum<EnumType>::value); + set(name, (int)enumVal); + } + + static CompilerOptionValue getDefault(CompilerOptionName name); + bool getBoolOption(CompilerOptionName name) + { + if (auto result = options.tryGetValue(name)) + { + SLANG_ASSERT(result->getCount() != 0 && (*result)[0].kind == CompilerOptionValueKind::Int); + return result->getCount() != 0 && (*result)[0].intValue != 0; + } + return getDefault(name).intValue != 0; + } + int getIntOption(CompilerOptionName name) + { + if (auto result = options.tryGetValue(name)) + { + SLANG_ASSERT(result->getCount() != 0 && (*result)[0].kind == CompilerOptionValueKind::Int); + return (*result)[0].intValue; + } + return getDefault(name).intValue != 0; + } + String getStringOption(CompilerOptionName name) + { + if (auto result = options.tryGetValue(name)) + { + SLANG_ASSERT(result->getCount() != 0 && (*result)[0].kind == CompilerOptionValueKind::String); + return (*result)[0].stringValue; + } + return getDefault(name).stringValue; + } + + template<typename EnumType> + EnumType getEnumOption(CompilerOptionName name) + { + static_assert(std::is_enum<EnumType>::value); + return (EnumType)getIntOption(name); + } + ArrayView<CompilerOptionValue> getArray(CompilerOptionName name) + { + if (auto result = options.tryGetValue(name)) + { + return result->getArrayView(); + } + return ArrayView<CompilerOptionValue>(); + } + + CodeGenTarget getTarget() + { + return getEnumOption<CodeGenTarget>(CompilerOptionName::Target); + } + + SlangTargetFlags getTargetFlags(); + void setTargetFlags(SlangTargetFlags flags); + void addTargetFlags(SlangTargetFlags flags); + + MatrixLayoutMode getMatrixLayoutMode(); + + void setMatrixLayoutMode(MatrixLayoutMode mode); + + ProfileVersion getProfileVersion(); + + Profile getProfile(); + void setProfile(Profile profile); + + void setProfileVersion(ProfileVersion version); + + void addCapabilityAtom(CapabilityName cap); + + void addPreprocessorDefine(String name, String value) + { + CompilerOptionValue v; + v.stringValue = name; + v.stringValue2 = value; + v.kind = CompilerOptionValueKind::String; + add(CompilerOptionName::MacroDefine, v); + } + + void addSearchPath(String path) + { + add(CompilerOptionName::Include, String(path)); + } + + bool shouldEmitSPIRVDirectly() + { + return getBoolOption(CompilerOptionName::EmitSpirvDirectly); + } + + bool shouldUseScalarLayout() + { + return getBoolOption(CompilerOptionName::GLSLForceScalarLayout); + } + + bool shouldDumpIntermediates() + { + return getBoolOption(CompilerOptionName::DumpIntermediates); + } + + bool shouldDumpIR() + { + return getBoolOption(CompilerOptionName::DumpIr); + } + + bool shouldObfuscateCode() + { + return getBoolOption(CompilerOptionName::Obfuscate); + } + + FloatingPointMode getFloatingPointMode() + { + return getEnumOption<FloatingPointMode>(CompilerOptionName::FloatingPointMode); + } + + LineDirectiveMode getLineDirectiveMode() + { + return getEnumOption<LineDirectiveMode>(CompilerOptionName::LineDirectiveMode); + } + + OptimizationLevel getOptimizationLevel() + { + return getEnumOption<OptimizationLevel>(CompilerOptionName::Optimization); + } + + DebugInfoLevel getDebugInfoLevel() + { + return getEnumOption<DebugInfoLevel>(CompilerOptionName::DebugInformation); + } + + List<String> getDownstreamArgs(String downstreamToolName); + + void serialize(SerializedOptionsData* outData); + }; + + class DiagnosticSink; + void applySettingsToDiagnosticSink(DiagnosticSink* targetSink, DiagnosticSink* outputSink, CompilerOptionSet& options); + +} + +#endif diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index c77f736bc..c0be68723 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -964,13 +964,11 @@ namespace Slang return desc.style == ArtifactStyle::Host; } - static bool _shouldSetEntryPointName(TargetRequest* targetReq) + static bool _shouldSetEntryPointName(TargetProgram* targetProgram) { - if (!isKhronosTarget(targetReq)) + if (!isKhronosTarget(targetProgram->getTargetReq())) return true; - if (!targetReq->getHLSLToVulkanLayoutOptions()) - return false; - if (targetReq->getHLSLToVulkanLayoutOptions()->getUseOriginalEntryPointName()) + if (targetProgram->getOptionSet().getBoolOption(CompilerOptionName::VulkanUseEntryPointName)) return true; return false; } @@ -1102,25 +1100,19 @@ namespace Slang // Set compiler specific args { - auto linkage = getLinkage(); - auto name = TypeTextUtil::getPassThroughName((SlangPassThrough)compilerType); - const Index nameIndex = linkage->m_downstreamArgs.findName(name); - if (nameIndex >= 0) + List<String> downstreamArgs = getTargetProgram()->getOptionSet().getDownstreamArgs(name); + for (const auto& arg : downstreamArgs) { - auto& args = linkage->m_downstreamArgs.getArgsAt(nameIndex); - for (const auto& arg : args.m_args) + // We special case some kinds of args, that can be handled directly + if (arg.startsWith("-I")) { - // We special case some kinds of args, that can be handled directly - if (arg.value.startsWith("-I")) - { - // We handle the -I option, by just adding to the include paths - includePaths.add(arg.value.getUnownedSlice().tail(2)); - } - else - { - compilerSpecificArguments.add(arg.value); - } + // We handle the -I option, by just adding to the include paths + includePaths.add(arg.getUnownedSlice().tail(2)); + } + else + { + compilerSpecificArguments.add(arg); } } } @@ -1150,8 +1142,8 @@ namespace Slang sourceTarget = CodeGenTarget(TypeConvertUtil::getCompileTargetFromSourceLanguage((SlangSourceLanguage)sourceLanguage)); // If it's pass through we accumulate the preprocessor definitions. - for (const auto& define : translationUnit->compileRequest->preprocessorDefinitions) - preprocessorDefinitions.add(define); + for (const auto& define : endToEndReq->getOptionSet().getArray(CompilerOptionName::MacroDefine)) + preprocessorDefinitions.add(define.stringValue, define.stringValue2); for (const auto& define : translationUnit->preprocessorDefinitions) preprocessorDefinitions.add(define); @@ -1229,10 +1221,11 @@ namespace Slang // // That said it's very convenient and provides way to control aspects // of downstream compilation. - - auto linkage = getLinkage(); - for (const auto& define : linkage->preprocessorDefinitions) - preprocessorDefinitions.add(define); + + for (const auto& define : getTargetProgram()->getOptionSet().getArray(CompilerOptionName::MacroDefine)) + { + preprocessorDefinitions.addIfNotExists(define.stringValue, define.stringValue2); + } } @@ -1295,12 +1288,12 @@ namespace Slang // * 'doesn't build into an executable/kernel' // // So in some sense it is a library - if (targetReq->isWholeProgramRequest()) + if (getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::GenerateWholeProgram)) { if (compilerType == PassThroughMode::Dxc) { // Can support no entry points on DXC because we can build libraries - profile = targetReq->getTargetProfile(); + profile = Profile(getTargetProgram()->getOptionSet().getEnumOption<Profile::RawEnum>(CompilerOptionName::Profile)); } else { @@ -1318,7 +1311,7 @@ namespace Slang auto entryPoint = getEntryPoint(entryPointIndex); profile = getEffectiveProfile(entryPoint, targetReq); - if (_shouldSetEntryPointName(getTargetReq())) + if (_shouldSetEntryPointName(getTargetProgram())) { options.entryPointName = allocator.allocate(getText(entryPoint->getName())); auto entryPointNameOverride = getProgram()->getEntryPointNameOverride(entryPointIndex); @@ -1356,7 +1349,7 @@ namespace Slang } // Set the matrix layout - options.matrixLayout = SlangMatrixLayoutMode(getTargetReq()->getDefaultMatrixLayoutMode()); + options.matrixLayout = (SlangMatrixLayoutMode)getTargetProgram()->getOptionSet().getMatrixLayoutMode(); } // Set the profile @@ -1394,7 +1387,7 @@ namespace Slang { auto linkage = getLinkage(); - switch (linkage->optimizationLevel) + switch (getTargetProgram()->getOptionSet().getEnumOption<OptimizationLevel>(CompilerOptionName::Optimization)) { case OptimizationLevel::None: options.optimizationLevel = DownstreamCompileOptions::OptimizationLevel::None; break; case OptimizationLevel::Default: options.optimizationLevel = DownstreamCompileOptions::OptimizationLevel::Default; break; @@ -1403,7 +1396,7 @@ namespace Slang default: SLANG_ASSERT(!"Unhandled optimization level"); break; } - switch (linkage->debugInfoLevel) + switch (getTargetProgram()->getOptionSet().getEnumOption<DebugInfoLevel>(CompilerOptionName::DebugInformation)) { case DebugInfoLevel::None: options.debugInfoType = DownstreamCompileOptions::DebugInfoType::None; break; case DebugInfoLevel::Minimal: options.debugInfoType = DownstreamCompileOptions::DebugInfoType::Minimal; break; @@ -1413,7 +1406,7 @@ namespace Slang default: SLANG_ASSERT(!"Unhandled debug level"); break; } - switch( getTargetReq()->getFloatingPointMode()) + switch (getTargetProgram()->getOptionSet().getEnumOption<FloatingPointMode>(CompilerOptionName::FloatingPointMode)) { case FloatingPointMode::Default: options.floatingPointMode = DownstreamCompileOptions::FloatingPointMode::Default; break; case FloatingPointMode::Precise: options.floatingPointMode = DownstreamCompileOptions::FloatingPointMode::Precise; break; @@ -1568,7 +1561,7 @@ namespace Slang return SLANG_OK; } case CodeGenTarget::SPIRV: - if (getTargetReq()->shouldEmitSPIRVDirectly()) + if (getTargetProgram()->getOptionSet().shouldEmitSPIRVDirectly()) { SLANG_RETURN_ON_FAIL(emitSPIRVForEntryPointsDirectly(this, outArtifact)); return SLANG_OK; @@ -1844,12 +1837,11 @@ namespace Slang TargetProgram* targetProgram) { auto program = targetProgram->getProgram(); - auto targetReq = targetProgram->getTargetReq(); // Generate target code any entry points that // have been requested for compilation. auto entryPointCount = program->getEntryPointCount(); - if (targetReq->isWholeProgramRequest()) + if (targetProgram->getOptionSet().getBoolOption(CompilerOptionName::GenerateWholeProgram)) { targetProgram->_createWholeProgramResult(getSink(), this); } @@ -1869,7 +1861,7 @@ namespace Slang bool _shouldWriteSourceLocs(Linkage* linkage) { // If debug information or source manager are not avaiable we can't/shouldn't write out locs - if (linkage->debugInfoLevel == DebugInfoLevel::None || + if (linkage->m_optionSet.getEnumOption<DebugInfoLevel>(CompilerOptionName::DebugInformation) == DebugInfoLevel::None || linkage->getSourceManager() == nullptr) { return false; @@ -1886,8 +1878,8 @@ namespace Slang // Set up options SerialContainerUtil::WriteOptions options; - options.compressionType = linkage->serialCompressionType; - if (linkage->m_obfuscateCode) + options.compressionType = linkage->m_optionSet.getEnumOption<SerialCompressionType>(CompilerOptionName::IrCompression); + if (linkage->m_optionSet.getBoolOption(CompilerOptionName::Obfuscate)) { // If code is obfuscated, we *disable* AST output as it is not obfuscated and will reveal // too much about IR. @@ -1942,7 +1934,7 @@ namespace Slang { auto targetProgram = program->getTargetProgram(targetReq); - if (targetReq->isWholeProgramRequest()) + if (targetProgram->getOptionSet().getBoolOption(CompilerOptionName::GenerateWholeProgram)) { if (auto artifact = targetProgram->getExistingWholeProgramResult()) { @@ -2029,6 +2021,16 @@ namespace Slang return SLANG_OK; } + CompilerOptionSet& EndToEndCompileRequest::getTargetOptionSet(TargetRequest* req) + { + return req->getOptionSet(); + } + + CompilerOptionSet& EndToEndCompileRequest::getTargetOptionSet(Index targetIndex) + { + return m_linkage->targets[targetIndex]->getOptionSet(); + } + SlangResult EndToEndCompileRequest::maybeWriteContainer(const String& fileName) { // If there is no container, or filename, don't write anything @@ -2118,7 +2120,7 @@ namespace Slang // Iterate over all the targets and their outputs for (const auto& targetReq : linkage->targets) { - if (targetReq->isWholeProgramRequest()) + if (compileRequest->getTargetOptionSet(targetReq).getBoolOption(CompilerOptionName::GenerateWholeProgram)) { RefPtr<EndToEndCompileRequest::TargetInfo> targetInfo; if (compileRequest->m_targetInfos.tryGetValue(targetReq, targetInfo)) @@ -2157,7 +2159,7 @@ namespace Slang // and report them as an error. // auto specializationParamCount = program->getSpecializationParamCount(); - if (disableDynamicDispatch && specializationParamCount != 0) + if (getOptionSet().getBoolOption(CompilerOptionName::DisableDynamicDispatch) && specializationParamCount != 0) { auto sink = getSink(); @@ -2193,7 +2195,6 @@ namespace Slang } } - void EndToEndCompileRequest::generateOutput() { generateOutput(getSpecializedGlobalAndEntryPointsComponentType()); @@ -2211,7 +2212,7 @@ namespace Slang { auto targetProgram = program->getTargetProgram(targetReq); - if (targetReq->isWholeProgramRequest()) + if (targetProgram->getOptionSet().getBoolOption(CompilerOptionName::GenerateWholeProgram)) { if (const auto artifact = targetProgram->getExistingWholeProgramResult()) { @@ -2337,85 +2338,43 @@ namespace Slang bool CodeGenContext::shouldValidateIR() { - if (auto endToEndReq = isEndToEndCompile()) - { - if (endToEndReq->getFrontEndReq()->shouldValidateIR) - return true; - } - - return false; + return getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::ValidateIr); } bool CodeGenContext::shouldSkipSPIRVValidation() { - if (auto endToEndReq = isEndToEndCompile()) - { - if (endToEndReq->m_skipSPIRVValidation) - return true; - } - - return false; + return getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::SkipSPIRVValidation); } bool CodeGenContext::shouldDumpIR() { - if (getTargetReq()->getTargetFlags() & SLANG_TARGET_FLAG_DUMP_IR) - return true; - - if (auto endToEndReq = isEndToEndCompile()) - { - if (endToEndReq->getFrontEndReq()->shouldDumpIR) - return true; - } - - return false; + return getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::DumpIr); } bool CodeGenContext::shouldDumpIntermediates() { - if (getTargetReq()->shouldDumpIntermediates()) - return true; - if (auto endToEndReq = isEndToEndCompile()) - { - if (endToEndReq->shouldDumpIntermediates) - return true; - } - return false; + return getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::DumpIntermediates); } bool CodeGenContext::shouldTrackLiveness() { - auto endToEndReq = isEndToEndCompile(); - return (endToEndReq && endToEndReq->enableLivenessTracking) || - getTargetReq()->shouldTrackLiveness(); + return getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::TrackLiveness); } String CodeGenContext::getIntermediateDumpPrefix() { - if (auto endToEndReq = isEndToEndCompile()) - { - return endToEndReq->m_dumpIntermediatePrefix; - } - return String(); + return getTargetProgram()->getOptionSet().getStringOption(CompilerOptionName::DumpIntermediatePrefix); } bool CodeGenContext::getUseUnknownImageFormatAsDefault() { - if (auto endToEndReq = isEndToEndCompile()) - { - return endToEndReq->useUnknownImageFormatAsDefault; - } - return false; + return getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::DefaultImageFormatUnknown); } bool CodeGenContext::isSpecializationDisabled() { - if (auto endToEndReq = isEndToEndCompile()) - { - return endToEndReq->disableSpecialization; - } - return false; + return getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::DisableSpecialization); } SLANG_NO_THROW SlangResult SLANG_MCALL Module::serialize(ISlangBlob** outSerializedBlob) diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index d93eff0a6..7da003b8a 100755 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -32,7 +32,7 @@ #include "slang-content-assist-info.h" #include "slang-hlsl-to-vulkan-layout-options.h" - +#include "slang-compiler-options.h" #include "slang-serialize-ir-types.h" #include "../compiler-core/slang-artifact-representation-impl.h" @@ -332,6 +332,14 @@ namespace Slang SlangInt targetIndex, slang::IBlob** outHash) SLANG_OVERRIDE; + SLANG_NO_THROW SlangResult SLANG_MCALL linkWithOptions( + slang::IComponentType** outLinkedComponentType, + uint32_t count, + slang::CompilerOptionEntry* entries, + ISlangBlob** outDiagnostics) override; + + CompilerOptionSet& getOptionSet() { return m_optionSet; } + /// Get the linkage (aka "session" in the public API) for this component type. Linkage* getLinkage() { return m_linkage; } @@ -521,6 +529,8 @@ namespace Slang private: Linkage* m_linkage; + + CompilerOptionSet m_optionSet; // Cache of target-specific programs for each target. Dictionary<TargetRequest*, RefPtr<TargetProgram>> m_targetPrograms; @@ -891,6 +901,15 @@ namespace Slang outDiagnostics); } + virtual SLANG_NO_THROW SlangResult SLANG_MCALL linkWithOptions( + slang::IComponentType** outLinkedComponentType, + uint32_t count, + slang::CompilerOptionEntry* entries, + ISlangBlob** outDiagnostics) override + { + return Super::linkWithOptions(outLinkedComponentType, count, entries, outDiagnostics); + } + SLANG_NO_THROW SlangResult SLANG_MCALL getEntryPointHostCallable( int entryPointIndex, int targetIndex, @@ -1113,6 +1132,15 @@ namespace Slang return Super::link(outLinkedComponentType, outDiagnostics); } + virtual SLANG_NO_THROW SlangResult SLANG_MCALL linkWithOptions( + slang::IComponentType** outLinkedComponentType, + uint32_t count, + slang::CompilerOptionEntry* entries, + ISlangBlob** outDiagnostics) override + { + return Super::linkWithOptions(outLinkedComponentType, count, entries, outDiagnostics); + } + SLANG_NO_THROW SlangResult SLANG_MCALL getEntryPointHostCallable( int entryPointIndex, int targetIndex, @@ -1315,6 +1343,14 @@ namespace Slang return SLANG_OK; } + virtual SLANG_NO_THROW SlangResult SLANG_MCALL linkWithOptions( + slang::IComponentType** outLinkedComponentType, + uint32_t count, + slang::CompilerOptionEntry* entries, + ISlangBlob** outDiagnostics) override + { + return Super::linkWithOptions(outLinkedComponentType, count, entries, outDiagnostics); + } // SLANG_NO_THROW void SLANG_MCALL getEntryPointHash( @@ -1623,67 +1659,15 @@ namespace Slang class TargetRequest : public RefObject { public: - TargetRequest(Linkage* linkage, CodeGenTarget format); - void addTargetFlags(SlangTargetFlags flags) - { - targetFlags |= flags; - } - void setTargetProfile(Slang::Profile profile) - { - targetProfile = profile; - } - void setFloatingPointMode(FloatingPointMode mode) - { - floatingPointMode = mode; - } - void setLineDirectiveMode(LineDirectiveMode mode) - { - lineDirectiveMode = mode; - } - - void setDumpIntermediates(bool value) - { - dumpIntermediates = value; - } - void setForceGLSLScalarBufferLayout(bool value) - { - forceGLSLScalarBufferLayout = value; - } - - void addCapability(CapabilityName capability); - - bool shouldEmitSPIRVDirectly() - { - return isKhronosTarget(this) && ((targetFlags & SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY) != 0); - } - - bool isWholeProgramRequest() - { - return (targetFlags & SLANG_TARGET_FLAG_GENERATE_WHOLE_PROGRAM) != 0; - } - - void setHLSLToVulkanLayoutOptions(HLSLToVulkanLayoutOptions* opts); - - const HLSLToVulkanLayoutOptions* getHLSLToVulkanLayoutOptions() const { return hlslToVulkanLayoutOptions; } - - bool shouldDumpIntermediates() { return dumpIntermediates; } - - void setTrackLiveness(bool enable) { enableLivenessTracking = enable; } - - bool shouldTrackLiveness() { return enableLivenessTracking; } + TargetRequest(const TargetRequest& other); Linkage* getLinkage() { return linkage; } - CodeGenTarget getTarget() { return format; } - Profile getTargetProfile() { return targetProfile; } - FloatingPointMode getFloatingPointMode() { return floatingPointMode; } - LineDirectiveMode getLineDirectiveMode() { return lineDirectiveMode; } - SlangTargetFlags getTargetFlags() { return targetFlags; } - CapabilitySet getTargetCaps(); - bool getForceGLSLScalarBufferLayout() { return forceGLSLScalarBufferLayout; } + Session* getSession(); - MatrixLayoutMode getDefaultMatrixLayoutMode(); + + CodeGenTarget getTarget() { return optionSet.getEnumOption<CodeGenTarget>(CompilerOptionName::Target); } // TypeLayouts created on the fly by reflection API Dictionary<Type*, RefPtr<TypeLayout>> typeLayouts; @@ -1692,27 +1676,24 @@ namespace Slang TypeLayout* getTypeLayout(Type* type); + CompilerOptionSet& getOptionSet() { return optionSet; } + + CapabilitySet getTargetCaps(); + + HLSLToVulkanLayoutOptions* getHLSLToVulkanLayoutOptions(); + private: Linkage* linkage = nullptr; - CodeGenTarget format = CodeGenTarget::Unknown; - SlangTargetFlags targetFlags = kDefaultTargetFlags; - Slang::Profile targetProfile = Slang::Profile(); - FloatingPointMode floatingPointMode = FloatingPointMode::Default; - List<CapabilityName> rawCapabilities; + CompilerOptionSet optionSet; CapabilitySet cookedCapabilities; - LineDirectiveMode lineDirectiveMode = LineDirectiveMode::Default; - bool dumpIntermediates = false; - bool forceGLSLScalarBufferLayout = false; - bool enableLivenessTracking = false; - - RefPtr<HLSLToVulkanLayoutOptions> hlslToVulkanLayoutOptions; ///< Optional vulkan layout options + RefPtr<HLSLToVulkanLayoutOptions> hlslToVulkanOptions; }; /// Given a target request returns which (if any) intermediate source language is required /// to produce it. /// /// If no intermediate source language is required, will return SourceLanguage::Unknown - SourceLanguage getIntermediateSourceLanguageForTarget(TargetRequest* req); + SourceLanguage getIntermediateSourceLanguageForTarget(TargetProgram* req); /// Are resource types "bindless" (implemented as ordinary data) on the given `target`? bool areResourceTypesBindlessOnTarget(TargetRequest* target); @@ -1773,6 +1754,8 @@ namespace Slang public: SLANG_REF_OBJECT_IUNKNOWN_ALL + CompilerOptionSet m_optionSet; + ISlangUnknown* getInterface(const Guid& guid); SLANG_NO_THROW slang::IGlobalSession* SLANG_MCALL getGlobalSession() override; @@ -1857,50 +1840,22 @@ namespace Slang /// Dtor ~Linkage(); - slang::SessionFlags m_flag = 0; - void setFlags(slang::SessionFlags flags) { m_flag = flags; } bool isInLanguageServer() { return contentAssistInfo.checkingMode != ContentAssistCheckingMode::None; } /// Get the parent session for this linkage Session* getSessionImpl() { return m_session; } - bool getEnableEffectAnnotations() - { - return m_enableEffectAnnotations; - } - void setEnableEffectAnnotations(bool value) - { - m_enableEffectAnnotations = value; - } - bool getAllowGLSLInput() - { - return m_allowGLSLInput; - } - void setAllowGLSLInput(bool value) - { - m_allowGLSLInput = value; - } - // Information on the targets we are being asked to // generate code for. List<RefPtr<TargetRequest>> targets; // Directories to search for `#include` files or `import`ed modules - SearchDirectoryList searchDirectories; - - SearchDirectoryList const& getSearchDirectories() { return searchDirectories; } - - // Definitions to provide during preprocessing - Dictionary<String, String> preprocessorDefinitions; + SearchDirectoryList& getSearchDirectories(); // Source manager to help track files loaded SourceManager m_defaultSourceManager; SourceManager* m_sourceManager = nullptr; - - bool m_obfuscateCode = false; - - /// Holds any args that are destined for downstream compilers/tools etc - DownstreamArgs m_downstreamArgs; + RefPtr<CommandLineContext> m_cmdLineContext; // Name pool for looking up names NamePool namePool; @@ -1909,7 +1864,6 @@ namespace Slang ASTBuilder* getASTBuilder() { return m_astBuilder; } - RefPtr<ASTBuilder> m_astBuilder; // Cache for container types. @@ -1939,6 +1893,8 @@ namespace Slang // Counters for allocating sequential IDs to witness tables conforming to each interface type. Dictionary<String, uint32_t> mapInterfaceMangledNameToSequentialIDCounters; + SearchDirectoryList searchDirectoryCache; + // The resulting specialized IR module for each entry point request List<RefPtr<IRModule>> compiledModules; @@ -2043,23 +1999,9 @@ namespace Slang void setFileSystem(ISlangFileSystem* fileSystem); - /// The layout to use for matrices by default (row/column major) - MatrixLayoutMode defaultMatrixLayoutMode = kMatrixLayoutMode_ColumnMajor; - MatrixLayoutMode getDefaultMatrixLayoutMode() { return defaultMatrixLayoutMode; } - - DebugInfoLevel debugInfoLevel = DebugInfoLevel::None; - DebugInfoFormat debugInfoFormat = DebugInfoFormat::Default; - - OptimizationLevel optimizationLevel = OptimizationLevel::Default; - - SerialCompressionType serialCompressionType = SerialCompressionType::VariableByteLite; - DiagnosticSink::Flags diagnosticSinkFlags = 0; bool m_requireCacheFileSystem = false; - bool m_useFalcorCustomSharedKeywordSemantics = false; - bool m_enableEffectAnnotations = false; - bool m_allowGLSLInput = false; // Modules that have been read in with the -r option List<ComPtr<IArtifact>> m_libModules; @@ -2151,17 +2093,6 @@ namespace Slang ISlangFileSystemExt* getFileSystemExt() { return getLinkage()->getFileSystemExt(); } SlangResult loadFile(String const& path, PathInfo& outPathInfo, ISlangBlob** outBlob) { return getLinkage()->loadFile(path, outPathInfo, outBlob); } - bool shouldDumpIR = false; - bool shouldValidateIR = false; - - bool shouldDumpAST = false; - bool shouldDocument = false; - - bool outputPreprocessor = false; - - /// If true will after lexical analysis output the hierarchy of includes to stdout - bool outputIncludes = false; - protected: CompileRequestBase( Linkage* linkage, @@ -2196,9 +2127,6 @@ namespace Slang RefPtr<TranslationUnitRequest> getTranslationUnit(UInt index) { return translationUnits[index]; } - // Compile flags to be shared by all translation units - SlangCompileFlags compileFlags = 0; - // If true then generateIR will serialize out IR, and serialize back in again. Making // serialization a bottleneck or firewall between the front end and the backend bool useSerialIRBottleneck = false; @@ -2206,22 +2134,14 @@ namespace Slang // If true will serialize and de-serialize with debug information bool verifyDebugSerialization = false; + CompilerOptionSet optionSet; + List<RefPtr<FrontEndEntryPointRequest>> m_entryPointReqs; List<RefPtr<FrontEndEntryPointRequest>> const& getEntryPointReqs() { return m_entryPointReqs; } UInt getEntryPointReqCount() { return m_entryPointReqs.getCount(); } FrontEndEntryPointRequest* getEntryPointReq(UInt index) { return m_entryPointReqs[index]; } - // Directories to search for `#include` files or `import`ed modules - // NOTE! That for now these search directories are not settable via the API - // so the search directories on Linkage is used for #include as well as for modules. - SearchDirectoryList searchDirectories; - - SearchDirectoryList const& getSearchDirectories() { return searchDirectories; } - - // Definitions to provide during preprocessing - Dictionary<String, String> preprocessorDefinitions; - void parseTranslationUnit( TranslationUnitRequest* translationUnit); @@ -2421,6 +2341,10 @@ namespace Slang return m_irModuleForLayout; } + CompilerOptionSet& getOptionSet() { return m_optionSet; } + + HLSLToVulkanLayoutOptions* getHLSLToVulkanLayoutOptions() { return m_targetReq->getHLSLToVulkanLayoutOptions(); } + private: RefPtr<IRModule> createIRModuleForLayout(DiagnosticSink* sink); @@ -2433,6 +2357,8 @@ namespace Slang // The computed layout, if it has been generated yet RefPtr<ProgramLayout> m_layout; + CompilerOptionSet m_optionSet; + // Generated compile results for each entry point // in the parent `Program` (indexing matches // the order they are given in the `Program`) @@ -2772,7 +2698,7 @@ namespace Slang virtual SLANG_NO_THROW void SLANG_MCALL setReportPerfBenchmark(bool value) SLANG_OVERRIDE; virtual SLANG_NO_THROW void SLANG_MCALL setSkipSPIRVValidation(bool value) SLANG_OVERRIDE; - void setHLSLToVulkanLayoutOptions(int targetIndex, HLSLToVulkanLayoutOptions* vulkanLayoutOptions); + void setTrackLiveness(bool v); EndToEndCompileRequest( Session* session); @@ -2814,35 +2740,14 @@ namespace Slang /// Source code for the specialization arguments to use for the global specialization parameters of the program. List<String> m_globalSpecializationArgStrings; - bool m_shouldSkipCodegen = false; - // Are we being driven by the command-line `slangc`, and should act accordingly? bool m_isCommandLineCompile = false; - - bool m_reportDownstreamCompileTime = false; - - // If set, will print out compiler performance benchmark results. - bool m_reportPerfBenchmark = false; - - bool m_skipSPIRVValidation = false; String m_diagnosticOutput; - - // If set, will dump the compilation state - String m_dumpRepro; - - /// If set, if a compilation failure occurs will attempt to save off a dump repro with a unique name - bool m_dumpReproOnError = false; - /// A blob holding the diagnostic output ComPtr<ISlangBlob> m_diagnosticOutputBlob; - /// Line directive mode for new targets to be added to this request. - /// This is needed to support the legacy `setLineDirectiveMode` API. - /// We can remove this field if we move to `setTargetLineDirectiveMode`. - LineDirectiveMode m_lineDirectiveMode = LineDirectiveMode::Default; - /// Per-entry-point information not tracked by other compile requests class EntryPointInfo : public RefObject { @@ -2861,9 +2766,14 @@ namespace Slang // the given entry point. Dictionary<Int, String> entryPointOutputPaths; String wholeTargetOutputPath; + CompilerOptionSet targetOptions; }; Dictionary<TargetRequest*, RefPtr<TargetInfo>> m_targetInfos; - + + CompilerOptionSet& getTargetOptionSet(TargetRequest* req); + + CompilerOptionSet& getTargetOptionSet(Index targetIndex); + String m_dependencyOutputPath; /// Writes the modules in a container to the stream @@ -2894,9 +2804,6 @@ namespace Slang DiagnosticSink* getSink() { return &m_sink; } NamePool* getNamePool() { return getLinkage()->getNamePool(); } - void setHLSLToVulkanLayoutOptions(HLSLToVulkanLayoutOptions* hlslToVulkanLayoutOptions) { m_hlslToVulkanLayoutOptions = hlslToVulkanLayoutOptions; } - HLSLToVulkanLayoutOptions* getHLSLToVulkanLayoutOptions() const { return m_hlslToVulkanLayoutOptions; } - FrontEndCompileRequest* getFrontEndReq() { return m_frontEndReq; } ComponentType* getUnspecializedGlobalComponentType() { return getFrontEndReq()->getGlobalComponentType(); } @@ -2917,36 +2824,7 @@ namespace Slang void generateOutput(); - void setTrackLiveness(bool enable); - - // Note: The following settings used to be considered part of the "back-end" compile - // request, but were only being used as part of end-to-end compilation anyway, - // so they were moved here. - // - - // Should we dump intermediate results along the way, for debugging? - bool shouldDumpIntermediates = false; - - // True if liveness tracking is enabled - bool enableLivenessTracking = false; - - // Should R/W images without explicit formats be assumed to have "unknown" format? - // - // The default behavior is to make a best-effort guess as to what format is intended. - // - bool useUnknownImageFormatAsDefault = false; - - // If true will disable generics/existential value specialization pass. - bool disableSpecialization = false; - - // If true will disable generating dynamic dispatch code. - bool disableDynamicDispatch = false; - - // The default IR dumping options -// IRDumpOptions m_irDumpOptions; - - String m_dumpIntermediatePrefix; - + CompilerOptionSet& getOptionSet() { return m_linkage->m_optionSet; } private: String _getWholeProgramPath(TargetRequest* targetReq); @@ -2973,8 +2851,6 @@ namespace Slang RefPtr<ComponentType> m_specializedGlobalComponentType; RefPtr<ComponentType> m_specializedGlobalAndEntryPointsComponentType; List<RefPtr<ComponentType>> m_specializedEntryPoints; - - RefPtr<HLSLToVulkanLayoutOptions> m_hlslToVulkanLayoutOptions; // For output @@ -3103,6 +2979,9 @@ namespace Slang SLANG_NO_THROW SlangResult SLANG_MCALL setSPIRVCoreGrammar(char const* jsonPath) override; + SLANG_NO_THROW SlangResult SLANG_MCALL parseCommandLineArguments( + int argc, const char* const* argv, slang::SessionDesc* outSessionDesc, ISlangUnknown** outAllocation) override; + /// Get the downstream compiler for a transition IDownstreamCompiler* getDownstreamCompiler(CodeGenTarget source, CodeGenTarget target); diff --git a/source/slang/slang-diagnostics.cpp b/source/slang/slang-diagnostics.cpp index 08ab829b9..df8c4c0d2 100644 --- a/source/slang/slang-diagnostics.cpp +++ b/source/slang/slang-diagnostics.cpp @@ -4,10 +4,10 @@ #include "../core/slang-memory-arena.h" #include "../core/slang-dictionary.h" #include "../core/slang-string-util.h" +#include "../core/slang-char-util.h" #include "../compiler-core/slang-name.h" #include "../compiler-core/slang-core-diagnostics.h" - namespace Slang { @@ -60,4 +60,66 @@ const DiagnosticsLookup* getDiagnosticsLookup() return _getDiagnosticLookupSingleton(); } + +SlangResult overrideDiagnostic(DiagnosticSink* sink, DiagnosticSink* outDiagnostic, const UnownedStringSlice& identifier, Severity originalSeverity, Severity overrideSeverity) +{ + auto diagnosticsLookup = getDiagnosticsLookup(); + + const DiagnosticInfo* diagnostic = nullptr; + Int diagnosticId = -1; + + // If it starts with a digit we assume it a number + if (identifier.getLength() > 0 && (CharUtil::isDigit(identifier[0]) || identifier[0] == '-')) + { + if (SLANG_FAILED(StringUtil::parseInt(identifier, diagnosticId))) + { + outDiagnostic->diagnose(SourceLoc(), Diagnostics::unknownDiagnosticName, identifier); + return SLANG_FAIL; + } + + // If we use numbers, we don't worry if we can't find a diagnostic + // and silently ignore. This was the previous behavior, and perhaps + // provides a way to safely disable warnings, without worrying about + // the version of the compiler. + diagnostic = diagnosticsLookup->getDiagnosticById(diagnosticId); + } + else + { + diagnostic = diagnosticsLookup->findDiagnosticByName(identifier); + if (!diagnostic) + { + outDiagnostic->diagnose(SourceLoc(), Diagnostics::unknownDiagnosticName, identifier); + return SLANG_FAIL; + } + diagnosticId = diagnostic->id; + } + + // If we are only allowing certain original severities check it's the right type + if (diagnostic && originalSeverity != Severity::Disable && diagnostic->severity != originalSeverity) + { + // Strictly speaking the diagnostic name is known, but it's not the right severity + // to be converted from, so it is an 'unknown name' in the context of severity... + // Or perhaps we want another diagnostic + outDiagnostic->diagnose(SourceLoc(), Diagnostics::unknownDiagnosticName, identifier); + return SLANG_FAIL; + } + + // Override the diagnostic severity in the sink + sink->overrideDiagnosticSeverity(int(diagnosticId), overrideSeverity, diagnostic); + + return SLANG_OK; +} + +SlangResult overrideDiagnostics(DiagnosticSink* sink, DiagnosticSink* outDiagnostic, const UnownedStringSlice& identifierList, Severity originalSeverity, Severity overrideSeverity) +{ + List<UnownedStringSlice> slices; + StringUtil::split(identifierList, ',', slices); + + for (const auto& slice : slices) + { + SLANG_RETURN_ON_FAIL(overrideDiagnostic(sink, outDiagnostic, slice, originalSeverity, overrideSeverity)); + } + return SLANG_OK; +} + } // namespace Slang diff --git a/source/slang/slang-diagnostics.h b/source/slang/slang-diagnostics.h index 917187007..299b63827 100644 --- a/source/slang/slang-diagnostics.h +++ b/source/slang/slang-diagnostics.h @@ -14,6 +14,8 @@ namespace Slang { DiagnosticInfo const* findDiagnosticByName(UnownedStringSlice const& name); const DiagnosticsLookup* getDiagnosticsLookup(); + SlangResult overrideDiagnostic(DiagnosticSink* sink, DiagnosticSink* outDiagnostic, const UnownedStringSlice& identifier, Severity originalSeverity, Severity overrideSeverity); + SlangResult overrideDiagnostics(DiagnosticSink* sink, DiagnosticSink* outDiagnostic, const UnownedStringSlice& identifierList, Severity originalSeverity, Severity overrideSeverity); namespace Diagnostics { diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp index 58c635d90..48832f497 100644 --- a/source/slang/slang-emit-cpp.cpp +++ b/source/slang/slang-emit-cpp.cpp @@ -1795,7 +1795,7 @@ void CPPSourceEmitter::_getExportStyle(IRInst* inst, bool& outIsExport, bool& ou outIsExport = false; outIsExternC = false; // Specially handle export, as we don't want to emit it multiple times - if (getTargetReq()->isWholeProgramRequest()) + if (getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::GenerateWholeProgram)) { if (auto nameHint = inst->findDecoration<IRNameHintDecoration>()) { diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp index e394804c7..55f6d140c 100644 --- a/source/slang/slang-emit-glsl.cpp +++ b/source/slang/slang-emit-glsl.cpp @@ -54,7 +54,7 @@ SlangResult GLSLSourceEmitter::init() default: break; } - if (getTargetReq()->getForceGLSLScalarBufferLayout()) + if (getTargetProgram()->getOptionSet().shouldUseScalarLayout()) { m_glslExtensionTracker->requireExtension( UnownedStringSlice::fromLiteral("GL_EXT_scalar_block_layout")); @@ -128,7 +128,7 @@ void GLSLSourceEmitter::_emitGLSLStructuredBuffer(IRGlobalParam* varDecl, IRHLSL switch (layoutTypeOp) { case kIROp_DefaultBufferLayoutType: - m_writer->emit(getTargetReq()->getForceGLSLScalarBufferLayout() ? "scalar" : "std430"); + m_writer->emit(getTargetProgram()->getOptionSet().shouldUseScalarLayout() ? "scalar" : "std430"); break; case kIROp_Std430BufferLayoutType: m_writer->emit("std430"); @@ -241,14 +241,14 @@ void GLSLSourceEmitter::emitSSBOHeader(IRGlobalParam* varDecl, IRType* bufferTyp if (layoutOp == kIROp_DefaultBufferLayoutType) { - m_writer->emit(getTargetReq()->getForceGLSLScalarBufferLayout() ? "scalar" : "std430"); + m_writer->emit(getTargetProgram()->getOptionSet().shouldUseScalarLayout() ? "scalar" : "std430"); } else { switch (layoutOp) { case kIROp_DefaultBufferLayoutType: - m_writer->emit(getTargetReq()->getForceGLSLScalarBufferLayout() ? "scalar" : "std430"); + m_writer->emit(getTargetProgram()->getOptionSet().shouldUseScalarLayout() ? "scalar" : "std430"); break; case kIROp_Std430BufferLayoutType: m_writer->emit("std430"); @@ -391,7 +391,7 @@ void GLSLSourceEmitter::_emitGLSLParameterGroup(IRGlobalParam* varDecl, IRUnifor { // Is writable m_writer->emit("layout("); - m_writer->emit(getTargetReq()->getForceGLSLScalarBufferLayout() ? "scalar" : "std430"); + m_writer->emit(getTargetProgram()->getOptionSet().shouldUseScalarLayout() ? "scalar" : "std430"); m_writer->emit(") buffer "); } // TODO: what to do with HLSL `tbuffer` style buffers? @@ -399,7 +399,7 @@ void GLSLSourceEmitter::_emitGLSLParameterGroup(IRGlobalParam* varDecl, IRUnifor { // uniform is implicitly read only m_writer->emit("layout("); - m_writer->emit(getTargetReq()->getForceGLSLScalarBufferLayout() ? "scalar" : "std140"); + m_writer->emit(getTargetProgram()->getOptionSet().shouldUseScalarLayout() ? "scalar" : "std140"); m_writer->emit(") uniform "); } @@ -2196,7 +2196,7 @@ void GLSLSourceEmitter::emitFrontMatterImpl(TargetRequest* targetReq) // calls them, because what they call "columns" // are what we call "rows." // - switch (targetReq->getDefaultMatrixLayoutMode()) + switch (getTargetProgram()->getOptionSet().getMatrixLayoutMode()) { case kMatrixLayoutMode_RowMajor: default: diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp index 416e8b0a1..fcab737e1 100644 --- a/source/slang/slang-emit-hlsl.cpp +++ b/source/slang/slang-emit-hlsl.cpp @@ -755,7 +755,7 @@ static bool _canEmitExport(const Profile& profile) /* virtual */void HLSLSourceEmitter::emitFuncDecorationsImpl(IRFunc* func) { // Specially handle export, as we don't want to emit it multiple times - if (getTargetReq()->isWholeProgramRequest() && + if (getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::GenerateWholeProgram) && _canEmitExport(m_effectiveProfile)) { for (auto decoration : func->getDecorations()) @@ -1260,7 +1260,7 @@ void HLSLSourceEmitter::handleRequiredCapabilitiesImpl(IRInst* inst) } } -void HLSLSourceEmitter::emitFrontMatterImpl(TargetRequest* targetReq) +void HLSLSourceEmitter::emitFrontMatterImpl(TargetRequest*) { if (m_extensionTracker->m_requiresNVAPI) { @@ -1314,7 +1314,7 @@ void HLSLSourceEmitter::emitFrontMatterImpl(TargetRequest* targetReq) // Emit any layout declarations - switch (targetReq->getDefaultMatrixLayoutMode()) + switch (getTargetProgram()->getOptionSet().getMatrixLayoutMode()) { case kMatrixLayoutMode_RowMajor: default: diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index d5d00e417..784ded1c9 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -1291,9 +1291,7 @@ struct SPIRVEmitContext bool shouldEmitSPIRVReflectionInfo() { - if (!m_targetRequest->getHLSLToVulkanLayoutOptions()) - return false; - return m_targetRequest->getHLSLToVulkanLayoutOptions()->shouldEmitSPIRVReflectionInfo(); + return m_targetProgram->getOptionSet().getBoolOption(CompilerOptionName::VulkanEmitReflection); } void requireVariablePointers() @@ -1401,7 +1399,7 @@ struct SPIRVEmitContext if (m_decoratedSpvInsts.add(getID(resultSpvType))) { IRSizeAndAlignment sizeAndAlignment; - getNaturalSizeAndAlignment(m_targetRequest, ptrType->getValueType(), &sizeAndAlignment); + getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), ptrType->getValueType(), &sizeAndAlignment); emitOpDecorateArrayStride( getSection(SpvLogicalSectionID::Annotations), nullptr, @@ -1465,7 +1463,7 @@ struct SPIRVEmitContext else { IRSizeAndAlignment sizeAndAlignment; - getNaturalSizeAndAlignment(m_targetRequest, elementType, &sizeAndAlignment); + getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), elementType, &sizeAndAlignment); stride = (int)sizeAndAlignment.getStride(); } emitOpDecorateArrayStride( @@ -3182,7 +3180,7 @@ struct SPIRVEmitContext } else { - getOffset(m_targetRequest, IRTypeLayoutRules::get(layoutRuleName), field, &offset); + getOffset(m_targetProgram->getOptionSet(), IRTypeLayoutRules::get(layoutRuleName), field, &offset); } emitOpMemberDecorateOffset( getSection(SpvLogicalSectionID::Annotations), @@ -3207,7 +3205,7 @@ struct SPIRVEmitContext IRIntegerValue matrixStride = 0; auto rule = IRTypeLayoutRules::get(layoutRuleName); IRSizeAndAlignment elementSizeAlignment; - getSizeAndAlignment(m_targetRequest, rule, matrixType->getElementType(), &elementSizeAlignment); + getSizeAndAlignment(m_targetProgram->getOptionSet(), rule, matrixType->getElementType(), &elementSizeAlignment); // Reminder: the meaning of row/column major layout // in our semantics is the *opposite* of what GLSL/SPIRV @@ -4153,7 +4151,7 @@ struct SPIRVEmitContext if (ptrType && ptrType->getAddressSpace() == SpvStorageClassPhysicalStorageBuffer) { IRSizeAndAlignment sizeAndAlignment; - getNaturalSizeAndAlignment(m_targetRequest, ptrType->getValueType(), &sizeAndAlignment); + getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), ptrType->getValueType(), &sizeAndAlignment); return emitOpLoadAligned(parent, inst, inst->getDataType(), inst->getPtr(), SpvLiteralInteger::from32(sizeAndAlignment.alignment)); } else @@ -4168,7 +4166,7 @@ struct SPIRVEmitContext if (ptrType && ptrType->getAddressSpace() == SpvStorageClassPhysicalStorageBuffer) { IRSizeAndAlignment sizeAndAlignment; - getNaturalSizeAndAlignment(m_targetRequest, ptrType->getValueType(), &sizeAndAlignment); + getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), ptrType->getValueType(), &sizeAndAlignment); return emitOpStoreAligned(parent, inst, inst->getPtr(), inst->getVal(), SpvLiteralInteger::from32(sizeAndAlignment.alignment)); } else @@ -5223,8 +5221,8 @@ struct SPIRVEmitContext } } - SPIRVEmitContext(IRModule* module, TargetRequest* target, DiagnosticSink* sink) - : SPIRVEmitSharedContext(module, target, sink) + SPIRVEmitContext(IRModule* module, TargetProgram* program, DiagnosticSink* sink) + : SPIRVEmitSharedContext(module, program, sink) , m_irModule(module) , m_memoryArena(2048) { @@ -5239,7 +5237,6 @@ SlangResult emitSPIRVFromIR( { spirvOut.clear(); - auto targetRequest = codeGenContext->getTargetReq(); auto sink = codeGenContext->getSink(); #if 0 @@ -5254,7 +5251,7 @@ SlangResult emitSPIRVFromIR( } #endif - SPIRVEmitContext context(irModule, targetRequest, sink); + SPIRVEmitContext context(irModule, codeGenContext->getTargetProgram(), sink); legalizeIRForSPIRV(&context, irModule, irEntryPoints, codeGenContext); #if 0 diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index 311fce83d..763d96840 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -214,6 +214,7 @@ Result linkAndOptimizeIR( auto sink = codeGenContext->getSink(); auto target = codeGenContext->getTargetFormat(); auto targetRequest = codeGenContext->getTargetReq(); + auto targetProgram = codeGenContext->getTargetProgram(); // Get the artifact desc for the target const auto artifactDesc = ArtifactDescUtil::makeDescForCompileTarget(asExternal(target)); @@ -234,7 +235,6 @@ Result linkAndOptimizeIR( dumpIRIfEnabled(codeGenContext, irModule, "LINKED"); #endif - validateIRModuleIfEnabled(codeGenContext, irModule); // If the user specified the flag that they want us to dump @@ -351,7 +351,7 @@ Result linkAndOptimizeIR( case CodeGenTarget::HostCPPSource: { lowerComInterfaces(irModule, artifactDesc.style, sink); - generateDllImportFuncs(codeGenContext->getTargetReq(), irModule, sink); + generateDllImportFuncs(codeGenContext->getTargetProgram(), irModule, sink); generateDllExportFuncs(irModule, sink); break; } @@ -367,12 +367,12 @@ Result linkAndOptimizeIR( validateIRModuleIfEnabled(codeGenContext, irModule); // Lower all the LValue implict casts (used for out/inout/ref scenarios) - lowerLValueCast(targetRequest, irModule); + lowerLValueCast(targetProgram, irModule); - simplifyIR(targetRequest, irModule, IRSimplificationOptions::getDefault(), sink); + simplifyIR(targetProgram, irModule, IRSimplificationOptions::getDefault(), sink); // Fill in default matrix layout into matrix types that left layout unspecified. - specializeMatrixLayout(codeGenContext->getTargetReq(), irModule); + specializeMatrixLayout(codeGenContext->getTargetProgram(), irModule); // It's important that this takes place before defunctionalization as we // want to be able to easily discover the cooperate and fallback funcitons @@ -406,14 +406,12 @@ Result linkAndOptimizeIR( for (;;) { bool changed = false; - //auto b1 = dumpIRToString(irModule->getModuleInst()); dumpIRIfEnabled(codeGenContext, irModule, "BEFORE-SPECIALIZE"); if (!codeGenContext->isSpecializationDisabled()) - changed |= specializeModule(codeGenContext->getTargetReq(), irModule, codeGenContext->getSink()); + changed |= specializeModule(targetProgram, irModule, codeGenContext->getSink()); if (codeGenContext->getSink()->getErrorCount() != 0) return SLANG_FAIL; dumpIRIfEnabled(codeGenContext, irModule, "AFTER-SPECIALIZE"); - //auto b2 = dumpIRToString(irModule->getModuleInst()); applySparseConditionalConstantPropagation(irModule, codeGenContext->getSink()); eliminateDeadCode(irModule); @@ -427,7 +425,7 @@ Result linkAndOptimizeIR( // Unroll loops. if (codeGenContext->getSink()->getErrorCount() == 0) { - if (!unrollLoopsInModule(targetRequest, irModule, codeGenContext->getSink())) + if (!unrollLoopsInModule(targetProgram, irModule, codeGenContext->getSink())) return SLANG_FAIL; } @@ -440,7 +438,7 @@ Result linkAndOptimizeIR( dumpIRIfEnabled(codeGenContext, irModule, "BEFORE-AUTODIFF"); enableIRValidationAtInsert(); - changed |= processAutodiffCalls(targetRequest, irModule, sink); + changed |= processAutodiffCalls(targetProgram, irModule, sink); disableIRValidationAtInsert(); dumpIRIfEnabled(codeGenContext, irModule, "AFTER-AUTODIFF"); @@ -448,7 +446,7 @@ Result linkAndOptimizeIR( break; } - finalizeAutoDiffPass(targetRequest, irModule); + finalizeAutoDiffPass(targetProgram, irModule); finalizeSpecialization(irModule); @@ -479,11 +477,11 @@ Result linkAndOptimizeIR( SLANG_RETURN_ON_FAIL(performStringInlining(irModule, sink)); } - lowerReinterpret(targetRequest, irModule, sink); + lowerReinterpret(targetProgram, irModule, sink); validateIRModuleIfEnabled(codeGenContext, irModule); - simplifyIR(targetRequest, irModule, IRSimplificationOptions::getFast(), sink); + simplifyIR(targetProgram, irModule, IRSimplificationOptions::getFast(), sink); if (!ArtifactDescUtil::isCpuLikeTarget(artifactDesc)) { @@ -495,7 +493,7 @@ Result linkAndOptimizeIR( // generics / interface types to ordinary functions and types using // function pointers. dumpIRIfEnabled(codeGenContext, irModule, "BEFORE-LOWER-GENERICS"); - lowerGenerics(targetRequest, irModule, sink); + lowerGenerics(targetProgram, irModule, sink); dumpIRIfEnabled(codeGenContext, irModule, "AFTER-LOWER-GENERICS"); if (sink->getErrorCount() != 0) @@ -512,7 +510,7 @@ Result linkAndOptimizeIR( // up downstream passes like type legalization, so we // will run a DCE pass to clean up after the specialization. // - simplifyIR(targetRequest, irModule, IRSimplificationOptions::getDefault(), sink); + simplifyIR(targetProgram, irModule, IRSimplificationOptions::getDefault(), sink); validateIRModuleIfEnabled(codeGenContext, irModule); @@ -521,7 +519,7 @@ Result linkAndOptimizeIR( // of `RWStructuredBuffer` typed fields now. if (target != CodeGenTarget::HLSL) { - lowerAppendConsumeStructuredBuffers(targetRequest, irModule, sink); + lowerAppendConsumeStructuredBuffers(targetProgram, irModule, sink); } // We don't need the legalize pass for C/C++ based types @@ -598,7 +596,7 @@ Result linkAndOptimizeIR( // to see if we can clean up any temporaries created by legalization. // (e.g., things that used to be aggregated might now be split up, // so that we can work with the individual fields). - simplifyIR(targetRequest, irModule, IRSimplificationOptions::getFast(), sink); + simplifyIR(targetProgram, irModule, IRSimplificationOptions::getFast(), sink); #if 0 dumpIRIfEnabled(codeGenContext, irModule, "AFTER SSA"); @@ -721,7 +719,7 @@ Result linkAndOptimizeIR( { case CodeGenTarget::HLSL: { - auto profile = targetRequest->getTargetProfile(); + auto profile = codeGenContext->getTargetProgram()->getOptionSet().getProfile(); if( profile.getFamily() == ProfileFamily::DX ) { if(profile.getVersion() <= ProfileVersion::DX_5_0) @@ -742,7 +740,7 @@ Result linkAndOptimizeIR( break; } - legalizeByteAddressBufferOps(session, targetRequest, irModule, byteAddressBufferOptions); + legalizeByteAddressBufferOps(session, targetProgram, irModule, byteAddressBufferOptions); } // For CUDA targets only, we will need to turn operations @@ -909,7 +907,7 @@ Result linkAndOptimizeIR( { // We need to lower any types used in a buffer resource (e.g. ContantBuffer or StructuredBuffer) into // a simple storage type that has target independent layout based on the kind of buffer resource. - lowerBufferElementTypeToStorageType(targetRequest, irModule); + lowerBufferElementTypeToStorageType(targetProgram, irModule); } // Rewrite functions that return arrays to return them via `out` parameter, @@ -919,20 +917,21 @@ Result linkAndOptimizeIR( if (isKhronosTarget(targetRequest) || target == CodeGenTarget::HLSL) { legalizeUniformBufferLoad(irModule); - if (targetRequest->getHLSLToVulkanLayoutOptions() && targetRequest->getHLSLToVulkanLayoutOptions()->shouldInvertY()) + if (targetProgram->getOptionSet().getBoolOption(CompilerOptionName::VulkanInvertY)) invertYOfPositionOutput(irModule); } // Lower sizeof/alignof - lowerSizeOfLike(targetRequest, irModule, sink); + lowerSizeOfLike(targetProgram, irModule, sink); // Lower all bit_cast operations on complex types into leaf-level // bit_cast on basic types. - lowerBitCast(targetRequest, irModule); + lowerBitCast(targetProgram, irModule); + bool emitSpirvDirectly = targetProgram->getOptionSet().shouldEmitSPIRVDirectly(); - if (isKhronosTarget(targetRequest) && targetRequest->shouldEmitSPIRVDirectly()) + if (isKhronosTarget(targetRequest) && emitSpirvDirectly) { performIntrinsicFunctionInlining(irModule); eliminateDeadCode(irModule); @@ -942,7 +941,7 @@ Result linkAndOptimizeIR( { IRSimplificationOptions simplificationOptions = IRSimplificationOptions::getFast(); simplificationOptions.cfgOptions.removeTrivialSingleIterationLoops = true; - simplifyIR(targetRequest, irModule, simplificationOptions, sink); + simplifyIR(targetProgram, irModule, simplificationOptions, sink); } // As a late step, we need to take the SSA-form IR and move things *out* @@ -971,7 +970,7 @@ Result linkAndOptimizeIR( // We only want to accumulate locations if liveness tracking is enabled. PhiEliminationOptions phiEliminationOptions; - if (isKhronosTarget(targetRequest) && targetRequest->shouldEmitSPIRVDirectly()) + if (isKhronosTarget(targetRequest) && emitSpirvDirectly) { phiEliminationOptions.eliminateCompositeTypedPhiOnly = false; phiEliminationOptions.useRegisterAllocation = true; @@ -1020,7 +1019,7 @@ Result linkAndOptimizeIR( } // Run a final round of simplifications to clean up unused things after phi-elimination. - simplifyNonSSAIR(targetRequest, irModule, IRSimplificationOptions::getFast()); + simplifyNonSSAIR(targetProgram, irModule, IRSimplificationOptions::getFast()); // We include one final step to (optionally) dump the IR and validate // it after all of the optimization passes are complete. This should @@ -1052,8 +1051,9 @@ SlangResult CodeGenContext::emitEntryPointsSourceFromIR(ComPtr<IArtifact>& outAr auto sourceManager = getSourceManager(); auto target = getTargetFormat(); auto targetRequest = getTargetReq(); + auto targetProgram = getTargetProgram(); - auto lineDirectiveMode = targetRequest->getLineDirectiveMode(); + auto lineDirectiveMode = targetProgram->getOptionSet().getEnumOption<LineDirectiveMode>(CompilerOptionName::LineDirectiveMode); // To try to make the default behavior reasonable, we will // always use C-style line directives (to give the user // good source locations on error messages from downstream @@ -1088,7 +1088,7 @@ SlangResult CodeGenContext::emitEntryPointsSourceFromIR(ComPtr<IArtifact>& outAr else { desc.entryPointStage = Stage::Unknown; - desc.effectiveProfile = targetRequest->getTargetProfile(); + desc.effectiveProfile = targetProgram->getOptionSet().getProfile(); } desc.sourceWriter = &sourceWriter; @@ -1310,8 +1310,7 @@ SlangResult emitSPIRVForEntryPointsDirectly( downstreamOptions.sourceArtifacts = makeSlice(artifact.readRef(), 1); downstreamOptions.targetType = SLANG_SPIRV; downstreamOptions.sourceLanguage = SLANG_SOURCE_LANGUAGE_SPIRV; - auto linkage = codeGenContext->getLinkage(); - switch (linkage->optimizationLevel) + switch (codeGenContext->getTargetProgram()->getOptionSet().getEnumOption<OptimizationLevel>(CompilerOptionName::Optimization)) { case OptimizationLevel::None: downstreamOptions.optimizationLevel = DownstreamCompileOptions::OptimizationLevel::None; break; case OptimizationLevel::Default: downstreamOptions.optimizationLevel = DownstreamCompileOptions::OptimizationLevel::Default; break; diff --git a/source/slang/slang-hlsl-to-vulkan-layout-options.cpp b/source/slang/slang-hlsl-to-vulkan-layout-options.cpp index 36044e43a..0e6f70294 100644 --- a/source/slang/slang-hlsl-to-vulkan-layout-options.cpp +++ b/source/slang/slang-hlsl-to-vulkan-layout-options.cpp @@ -1,6 +1,7 @@ // slang-hlsl-to-vulkan-layout-options.cpp #include "slang-hlsl-to-vulkan-layout-options.h" +#include "slang-compiler-options.h" namespace Slang { @@ -27,6 +28,37 @@ static NamesDescriptionValue s_vulkanShiftKinds[] = return makeConstArrayView(s_vulkanShiftKinds); } +void HLSLToVulkanLayoutOptions::loadFromOptionSet(CompilerOptionSet& optionSet) +{ + auto allShift = optionSet.getArray(CompilerOptionName::VulkanBindShiftAll); + for (auto v : allShift) + { + setAllShift((Kind)v.intValue, v.intValue2); + } + auto shifts = optionSet.getArray(CompilerOptionName::VulkanBindShift); + for (auto v : shifts) + { + uint8_t kind; + int set; + int shift; + v.unpackInt3(kind, set, shift); + setShift((Kind)kind, set, shift); + } + m_emitSPIRVReflectionInfo = optionSet.getBoolOption(CompilerOptionName::VulkanEmitReflection); + if (auto bindGlobals = optionSet.options.tryGetValue(CompilerOptionName::VulkanBindGlobals)) + { + if (bindGlobals->getCount()) + { + m_globalsBinding.index = (*bindGlobals)[0].intValue; + m_globalsBinding.set = (*bindGlobals)[0].intValue2; + } + } + m_invertY = optionSet.getBoolOption(CompilerOptionName::VulkanInvertY); + m_useGLLayout = optionSet.getBoolOption(CompilerOptionName::VulkanUseGLLayout); + m_useOriginalEntryPointName = optionSet.getBoolOption(CompilerOptionName::VulkanUseEntryPointName); + +} + HLSLToVulkanLayoutOptions::HLSLToVulkanLayoutOptions() { // Clear the all shifts diff --git a/source/slang/slang-hlsl-to-vulkan-layout-options.h b/source/slang/slang-hlsl-to-vulkan-layout-options.h index 97de2a610..2b8ec973c 100644 --- a/source/slang/slang-hlsl-to-vulkan-layout-options.h +++ b/source/slang/slang-hlsl-to-vulkan-layout-options.h @@ -15,6 +15,9 @@ https://github.com/microsoft/DirectXShaderCompiler/blob/main/docs/SPIR-V.rst#des Options that allow for infering Vulkan bindings based on HLSL register bindings */ + +struct CompilerOptionSet; + struct HLSLToVulkanLayoutOptions : public RefObject { public: @@ -61,7 +64,7 @@ public: /// Constant buffer (b) /// /// ConstantBufferViews, CBuffer - ConstantBuffer, + ConstantBuffer, CountOf, }; @@ -157,6 +160,8 @@ public: void setEmitSPIRVReflectionInfo(bool value) { m_emitSPIRVReflectionInfo = value; } + void loadFromOptionSet(CompilerOptionSet& optionSet); + /// Ctor HLSLToVulkanLayoutOptions(); diff --git a/source/slang/slang-ir-any-value-inference.cpp b/source/slang/slang-ir-any-value-inference.cpp index ae3e67397..b1e82623f 100644 --- a/source/slang/slang-ir-any-value-inference.cpp +++ b/source/slang/slang-ir-any-value-inference.cpp @@ -86,7 +86,7 @@ namespace Slang } void inferAnyValueSizeWhereNecessary( - TargetRequest* targetReq, + TargetProgram* targetProgram, IRModule* module) { // Go through the global insts and collect all interface types. @@ -213,7 +213,7 @@ namespace Slang for (auto implType : mapInterfaceToImplementations[interfaceType]) { IRSizeAndAlignment sizeAndAlignment; - getNaturalSizeAndAlignment(targetReq, (IRType*)implType, &sizeAndAlignment); + getNaturalSizeAndAlignment(targetProgram->getOptionSet(), (IRType*)implType, &sizeAndAlignment); maxAnyValueSize = Math::Max(maxAnyValueSize, sizeAndAlignment.size); } diff --git a/source/slang/slang-ir-any-value-inference.h b/source/slang/slang-ir-any-value-inference.h index a7911ff23..d1b6702f4 100644 --- a/source/slang/slang-ir-any-value-inference.h +++ b/source/slang/slang-ir-any-value-inference.h @@ -9,6 +9,6 @@ namespace Slang { void inferAnyValueSizeWhereNecessary( - TargetRequest* targetReq, + TargetProgram* targetProgram, IRModule* module); } diff --git a/source/slang/slang-ir-autodiff-fwd.cpp b/source/slang/slang-ir-autodiff-fwd.cpp index 632f99480..2f61dfa72 100644 --- a/source/slang/slang-ir-autodiff-fwd.cpp +++ b/source/slang/slang-ir-autodiff-fwd.cpp @@ -1642,7 +1642,7 @@ SlangResult ForwardDiffTranscriber::prepareFuncForForwardDiff(IRFunc* func) if (SLANG_SUCCEEDED(result)) { disableIRValidationAtInsert(); - simplifyFunc(autoDiffSharedContext->targetRequest, func, IRSimplificationOptions::getDefault()); + simplifyFunc(autoDiffSharedContext->targetProgram, func, IRSimplificationOptions::getDefault()); enableIRValidationAtInsert(); } return result; diff --git a/source/slang/slang-ir-autodiff.cpp b/source/slang/slang-ir-autodiff.cpp index 2605dd028..2cc4e3b57 100644 --- a/source/slang/slang-ir-autodiff.cpp +++ b/source/slang/slang-ir-autodiff.cpp @@ -339,8 +339,8 @@ IRInst* DifferentialPairTypeBuilder::lowerDiffPairType( return result; } -AutoDiffSharedContext::AutoDiffSharedContext(TargetRequest* target, IRModuleInst* inModuleInst) - : moduleInst(inModuleInst), targetRequest(target) +AutoDiffSharedContext::AutoDiffSharedContext(TargetProgram* target, IRModuleInst* inModuleInst) + : moduleInst(inModuleInst), targetProgram(target) { differentiableInterfaceType = as<IRInterfaceType>(findDifferentiableInterface()); if (differentiableInterfaceType) @@ -1979,7 +1979,7 @@ protected: }; bool processAutodiffCalls( - TargetRequest* target, + TargetProgram* target, IRModule* module, DiagnosticSink* sink, IRAutodiffPassOptions const&) @@ -2078,7 +2078,7 @@ void releaseNullDifferentialType(AutoDiffSharedContext* context) } } -bool finalizeAutoDiffPass(TargetRequest* target, IRModule* module) +bool finalizeAutoDiffPass(TargetProgram* target, IRModule* module) { bool modified = false; diff --git a/source/slang/slang-ir-autodiff.h b/source/slang/slang-ir-autodiff.h index a3e8c8de7..811002091 100644 --- a/source/slang/slang-ir-autodiff.h +++ b/source/slang/slang-ir-autodiff.h @@ -59,7 +59,7 @@ struct DiffTranscriberSet struct AutoDiffSharedContext { - TargetRequest* targetRequest = nullptr; + TargetProgram* targetProgram = nullptr; IRModuleInst* moduleInst = nullptr; @@ -115,7 +115,7 @@ struct AutoDiffSharedContext DiffTranscriberSet transcriberSet; - AutoDiffSharedContext(TargetRequest* target, IRModuleInst* inModuleInst); + AutoDiffSharedContext(TargetProgram* target, IRModuleInst* inModuleInst); private: @@ -359,12 +359,12 @@ struct IRAutodiffPassOptions }; bool processAutodiffCalls( - TargetRequest* target, + TargetProgram* target, IRModule* module, DiagnosticSink* sink, IRAutodiffPassOptions const& options = IRAutodiffPassOptions()); -bool finalizeAutoDiffPass(TargetRequest* target, IRModule* module); +bool finalizeAutoDiffPass(TargetProgram* target, IRModule* module); // Utility methods diff --git a/source/slang/slang-ir-byte-address-legalize.cpp b/source/slang/slang-ir-byte-address-legalize.cpp index fd2b599f8..c1e22c89f 100644 --- a/source/slang/slang-ir-byte-address-legalize.cpp +++ b/source/slang/slang-ir-byte-address-legalize.cpp @@ -24,6 +24,7 @@ struct ByteAddressBufferLegalizationContext // that control what constructs we legalize, and how. // Session* m_session = nullptr; + TargetProgram* m_targetProgram = nullptr; TargetRequest* m_target = nullptr; ByteAddressBufferLegalizationOptions m_options; @@ -204,22 +205,22 @@ struct ByteAddressBufferLegalizationContext return false; } - SlangResult getOffset(TargetRequest* target, IRStructField* field, IRIntegerValue* outOffset) + SlangResult getOffset(TargetProgram* target, IRStructField* field, IRIntegerValue* outOffset) { if (target->getHLSLToVulkanLayoutOptions() && target->getHLSLToVulkanLayoutOptions()->shouldUseGLLayout()) { - return getStd430Offset(target, field, outOffset); + return getStd430Offset(target->getOptionSet(), field, outOffset); } - return getNaturalOffset(target, field, outOffset); + return getNaturalOffset(target->getOptionSet(), field, outOffset); } - SlangResult getSizeAndAlignment(TargetRequest* target, IRType* type, IRSizeAndAlignment* outSizeAlignment) + SlangResult getSizeAndAlignment(TargetProgram* target, IRType* type, IRSizeAndAlignment* outSizeAlignment) { if (target->getHLSLToVulkanLayoutOptions() && target->getHLSLToVulkanLayoutOptions()->shouldUseGLLayout()) { - return getStd430SizeAndAlignment(target, type, outSizeAlignment); + return getStd430SizeAndAlignment(target->getOptionSet(), type, outSizeAlignment); } - return getNaturalSizeAndAlignment(target, type, outSizeAlignment); + return getNaturalSizeAndAlignment(target->getOptionSet(), type, outSizeAlignment); } // The core workhorse routine for the load case is `emitLegalLoad`, @@ -275,7 +276,7 @@ struct ByteAddressBufferLegalizationContext // then we fail to legalize this load. // IRIntegerValue fieldOffset = 0; - SLANG_RETURN_NULL_ON_FAIL(getOffset(m_target, field, &fieldOffset)); + SLANG_RETURN_NULL_ON_FAIL(getOffset(m_targetProgram, field, &fieldOffset)); // Otherwise, we load the field by recursively calling this function // on the field type, with an adjusted immediate offset. @@ -338,7 +339,7 @@ struct ByteAddressBufferLegalizationContext auto rowCount = (Index)getIntVal(matType->getRowCount()); auto colVectorType = m_builder.getVectorType(matType->getElementType(), rowCount); IRSizeAndAlignment colVectorSizeAlignment; - getSizeAndAlignment(m_target, colVectorType, &colVectorSizeAlignment); + getSizeAndAlignment(m_targetProgram, colVectorType, &colVectorSizeAlignment); for (Index c = 0; c < colCount; c++) { auto colVector = emitLegalLoad(colVectorType, buffer, baseOffset, immediateOffset); @@ -456,7 +457,7 @@ struct ByteAddressBufferLegalizationContext // the "stride" of the element type. // IRSizeAndAlignment elementLayout; - SLANG_RETURN_NULL_ON_FAIL(getNaturalSizeAndAlignment(m_target, elementType, &elementLayout)); + SLANG_RETURN_NULL_ON_FAIL(getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), elementType, &elementLayout)); IRIntegerValue elementStride = elementLayout.getStride(); // We will collect all the element values into an array so @@ -546,7 +547,7 @@ struct ByteAddressBufferLegalizationContext auto offsetType = offset->getDataType(); IRSizeAndAlignment typeLayout; - SLANG_RETURN_NULL_ON_FAIL(getNaturalSizeAndAlignment(m_target, type, &typeLayout)); + SLANG_RETURN_NULL_ON_FAIL(getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), type, &typeLayout)); auto typeStrideVal = typeLayout.getStride(); auto typeStrideInst = m_builder.getIntValue(offsetType, typeStrideVal); @@ -858,7 +859,7 @@ struct ByteAddressBufferLegalizationContext auto fieldType = field->getFieldType(); IRIntegerValue fieldOffset; - SLANG_RETURN_ON_FAIL(getOffset(m_target, field, &fieldOffset)); + SLANG_RETURN_ON_FAIL(getOffset(m_targetProgram, field, &fieldOffset)); auto fieldVal = m_builder.emitFieldExtract(fieldType, value, field->getKey()); SLANG_RETURN_ON_FAIL(emitLegalStore(fieldType, buffer, baseOffset, immediateOffset + fieldOffset, fieldVal)); @@ -907,7 +908,7 @@ struct ByteAddressBufferLegalizationContext auto colVectorType = m_builder.getVectorType(matType->getElementType(), rowCount); auto colVector = m_builder.emitMakeVector(colVectorType, colVectorArgs); IRSizeAndAlignment colVectorSizeAlignment; - getSizeAndAlignment(m_target, colVectorType, &colVectorSizeAlignment); + getSizeAndAlignment(m_targetProgram, colVectorType, &colVectorSizeAlignment); emitLegalStore(colVectorType, buffer, baseOffset, immediateOffset, colVector); immediateOffset += colVectorSizeAlignment.getStride(); } @@ -967,7 +968,7 @@ struct ByteAddressBufferLegalizationContext auto indexType = offset->getDataType(); IRSizeAndAlignment typeLayout; - SLANG_RETURN_ON_FAIL(getNaturalSizeAndAlignment(m_target, type, &typeLayout)); + SLANG_RETURN_ON_FAIL(getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), type, &typeLayout)); auto typeStride = m_builder.getIntValue(indexType, typeLayout.getStride()); @@ -995,7 +996,7 @@ struct ByteAddressBufferLegalizationContext // We iterate over the elements and fetch then store each one. // IRSizeAndAlignment elementLayout; - SLANG_RETURN_ON_FAIL(getNaturalSizeAndAlignment(m_target, elementType, &elementLayout)); + SLANG_RETURN_ON_FAIL(getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), elementType, &elementLayout)); IRIntegerValue elementStride = elementLayout.getStride(); auto indexType = m_builder.getIntType(); @@ -1013,14 +1014,15 @@ struct ByteAddressBufferLegalizationContext void legalizeByteAddressBufferOps( Session* session, - TargetRequest* target, + TargetProgram* program, IRModule* module, ByteAddressBufferLegalizationOptions const& options) { ByteAddressBufferLegalizationContext context; context.m_session = session; - context.m_target = target; + context.m_target = program->getTargetReq(); context.m_options = options; + context.m_targetProgram = program; context.processModule(module); } diff --git a/source/slang/slang-ir-byte-address-legalize.h b/source/slang/slang-ir-byte-address-legalize.h index c01c0c34d..996a93c73 100644 --- a/source/slang/slang-ir-byte-address-legalize.h +++ b/source/slang/slang-ir-byte-address-legalize.h @@ -4,7 +4,7 @@ namespace Slang { class Session; -class TargetRequest; +class TargetProgram; struct IRModule; struct ByteAddressBufferLegalizationOptions @@ -22,7 +22,7 @@ struct ByteAddressBufferLegalizationOptions /// void legalizeByteAddressBufferOps( Session* session, - TargetRequest* target, + TargetProgram* target, IRModule* module, ByteAddressBufferLegalizationOptions const& options); } diff --git a/source/slang/slang-ir-dll-import.cpp b/source/slang/slang-ir-dll-import.cpp index fbb473ea2..6855e262c 100644 --- a/source/slang/slang-ir-dll-import.cpp +++ b/source/slang/slang-ir-dll-import.cpp @@ -13,7 +13,7 @@ struct DllImportContext { IRModule* module; DiagnosticSink* diagnosticSink; - TargetRequest* targetReq; + TargetProgram* targetProgram; IRFunc* loadDllFunc = nullptr; IRFunc* loadFuncPtrFunc = nullptr; @@ -91,7 +91,7 @@ struct DllImportContext for (auto param : func->getParams()) { IRSizeAndAlignment sizeAndAlignment; - getNaturalSizeAndAlignment(targetReq, param->getDataType(), &sizeAndAlignment); + getNaturalSizeAndAlignment(targetProgram->getOptionSet(), param->getDataType(), &sizeAndAlignment); result += (uint32_t)align(sizeAndAlignment.size, 4); } return result; @@ -188,11 +188,11 @@ struct DllImportContext } }; -void generateDllImportFuncs(TargetRequest* targetReq, IRModule* module, DiagnosticSink* sink) +void generateDllImportFuncs(TargetProgram* targetProgram, IRModule* module, DiagnosticSink* sink) { DllImportContext context; context.module = module; - context.targetReq = targetReq; + context.targetProgram = targetProgram; context.diagnosticSink = sink; return context.processModule(); } diff --git a/source/slang/slang-ir-dll-import.h b/source/slang/slang-ir-dll-import.h index 8ea97527b..dd8e5dc44 100644 --- a/source/slang/slang-ir-dll-import.h +++ b/source/slang/slang-ir-dll-import.h @@ -5,7 +5,7 @@ namespace Slang { struct IRModule; class DiagnosticSink; - class TargetRequest; + class TargetProgram; /// Generate implementations for functions marked as [DllImport]. - void generateDllImportFuncs(TargetRequest* targetReq, IRModule* module, DiagnosticSink* sink); + void generateDllImportFuncs(TargetProgram* targetReq, IRModule* module, DiagnosticSink* sink); } diff --git a/source/slang/slang-ir-extract-value-from-type.cpp b/source/slang/slang-ir-extract-value-from-type.cpp index fa8c6e441..8db4bb7ef 100644 --- a/source/slang/slang-ir-extract-value-from-type.cpp +++ b/source/slang/slang-ir-extract-value-from-type.cpp @@ -16,7 +16,7 @@ struct FindLeafValueResult }; FindLeafValueResult findLeafValueAtOffset( - TargetRequest* targetReq, + TargetProgram* targetProgram, IRBuilder& builder, IRType* dataType, IRSizeAndAlignment& layout, @@ -42,8 +42,8 @@ FindLeafValueResult findLeafValueAtOffset( { IRIntegerValue fieldOffset = 0; IRSizeAndAlignment fieldLayout; - CHECK(getNaturalSizeAndAlignment(targetReq, field->getFieldType(), &fieldLayout)); - CHECK(getNaturalOffset(targetReq, field, &fieldOffset)); + CHECK(getNaturalSizeAndAlignment(targetProgram->getOptionSet(), field->getFieldType(), &fieldLayout)); + CHECK(getNaturalOffset(targetProgram->getOptionSet(), field, &fieldOffset)); if (fieldOffset + fieldLayout.size > offset) { if (fieldOffset > offset) @@ -62,7 +62,7 @@ FindLeafValueResult findLeafValueAtOffset( auto fieldValue = builder.emitFieldExtract(field->getFieldType(), src, field->getKey()); return findLeafValueAtOffset( - targetReq, + targetProgram, builder, field->getFieldType(), fieldLayout, @@ -81,7 +81,7 @@ FindLeafValueResult findLeafValueAtOffset( auto arrayType = as<IRArrayType>(dataType); auto elementType = arrayType->getElementType(); IRSizeAndAlignment elementLayout; - CHECK(getNaturalSizeAndAlignment(targetReq, elementType, &elementLayout)); + CHECK(getNaturalSizeAndAlignment(targetProgram->getOptionSet(), elementType, &elementLayout)); if (elementLayout.getStride() == 0) { result.leafValue = builder.getIntValue(builder.getUIntType(), 0); @@ -93,7 +93,7 @@ FindLeafValueResult findLeafValueAtOffset( auto elementValue = builder.emitElementExtract( elementType, src, builder.getIntValue(builder.getUIntType(), index)); return findLeafValueAtOffset( - targetReq, + targetProgram, builder, elementType, elementLayout, @@ -106,13 +106,13 @@ FindLeafValueResult findLeafValueAtOffset( auto vectorType = as<IRVectorType>(dataType); auto elementType = vectorType->getElementType(); IRSizeAndAlignment elementLayout; - CHECK(getNaturalSizeAndAlignment(targetReq, elementType, &elementLayout)); + CHECK(getNaturalSizeAndAlignment(targetProgram->getOptionSet(), elementType, &elementLayout)); uint32_t index = elementLayout.getStride() == 0 ? 0 : (uint32_t)(offset / elementLayout.getStride()); auto elementValue = builder.emitElementExtract( elementType, src, builder.getIntValue(builder.getUIntType(), index)); return findLeafValueAtOffset( - targetReq, + targetProgram, builder, elementType, elementLayout, @@ -129,14 +129,14 @@ FindLeafValueResult findLeafValueAtOffset( auto columnCount = as<IRIntLit>(matrixType->getColumnCount())->value.intVal; auto rowType = builder.getVectorType(elementType, matrixType->getColumnCount()); IRSizeAndAlignment rowLayout; - CHECK(getNaturalSizeAndAlignment(targetReq, rowType, &rowLayout)); + CHECK(getNaturalSizeAndAlignment(targetProgram->getOptionSet(), rowType, &rowLayout)); uint32_t rowIndex = rowLayout.getStride() == 0 ? 0 : (uint32_t)(offset / (columnCount * rowLayout.getStride())); auto rowValue = builder.emitElementExtract( rowType, src, builder.getIntValue(builder.getUIntType(), rowIndex)); return findLeafValueAtOffset( - targetReq, + targetProgram, builder, rowType, rowLayout, @@ -157,13 +157,13 @@ FindLeafValueResult findLeafValueAtOffset( IRInst* extractByteAtOffset( IRBuilder& builder, - TargetRequest* targetReq, + TargetProgram* targetProgram, IRType* dataType, IRSizeAndAlignment& layout, IRInst* src, uint32_t offset) { - auto leaf = findLeafValueAtOffset(targetReq, builder, dataType, layout, src, offset); + auto leaf = findLeafValueAtOffset(targetProgram, builder, dataType, layout, src, offset); IRType* uintType = nullptr; if (leaf.valueSize <= 4) { @@ -188,7 +188,7 @@ IRInst* extractByteAtOffset( IRInst* extractMultiByteValueAtOffset( IRBuilder& builder, - TargetRequest* targetReq, + TargetProgram* targetProgram, IRType* dataType, IRSizeAndAlignment& layout, IRInst* src, @@ -196,9 +196,9 @@ IRInst* extractMultiByteValueAtOffset( uint32_t offset) { if (size == 1) - return extractByteAtOffset(builder, targetReq, dataType, layout, src, offset); + return extractByteAtOffset(builder, targetProgram, dataType, layout, src, offset); - auto leaf = findLeafValueAtOffset(targetReq, builder, dataType, layout, src, offset); + auto leaf = findLeafValueAtOffset(targetProgram, builder, dataType, layout, src, offset); auto resultValue = leaf.leafValue; IRType* uintType = nullptr; if (leaf.valueSize <= 4) @@ -246,9 +246,9 @@ IRInst* extractMultiByteValueAtOffset( // The requested value crosses the boundaries of different fields. // We need to extract first and second half separately, and combine them together. auto firstHalf = extractMultiByteValueAtOffset( - builder, targetReq, dataType, layout, src, size / 2, offset); + builder, targetProgram, dataType, layout, src, size / 2, offset); auto secondHalf = extractMultiByteValueAtOffset( - builder, targetReq, dataType, layout, src, size / 2, offset + size / 2); + builder, targetProgram, dataType, layout, src, size / 2, offset + size / 2); uint32_t shift = (size / 2) * 8; resultValue = builder.emitAdd( builder.getUIntType(), @@ -262,17 +262,17 @@ IRInst* extractMultiByteValueAtOffset( } IRInst* extractValueAtOffset( - IRBuilder& builder, TargetRequest* targetReq, IRInst* src, uint32_t offset, uint32_t size) + IRBuilder& builder, TargetProgram* targetProgram, IRInst* src, uint32_t offset, uint32_t size) { auto dataType = src->getDataType(); IRSizeAndAlignment typeLayout; - SLANG_RETURN_NULL_ON_FAIL(getNaturalSizeAndAlignment(targetReq, dataType, &typeLayout)); + SLANG_RETURN_NULL_ON_FAIL(getNaturalSizeAndAlignment(targetProgram->getOptionSet(), dataType, &typeLayout)); if (offset + size > typeLayout.size) { return builder.getIntValue(builder.getIntType(), 0); } return extractMultiByteValueAtOffset( - builder, targetReq, dataType, typeLayout, src, size, offset); + builder, targetProgram, dataType, typeLayout, src, size, offset); } } // namespace Slang diff --git a/source/slang/slang-ir-extract-value-from-type.h b/source/slang/slang-ir-extract-value-from-type.h index de39ee545..c4419f2a7 100644 --- a/source/slang/slang-ir-extract-value-from-type.h +++ b/source/slang/slang-ir-extract-value-from-type.h @@ -11,6 +11,6 @@ namespace Slang // starting at `offset` in `src`. `src` must be a value of `struct`, array, vector or basic type. // `size` can be either 1, 2 or 4. The resulting `IRInst` value will have an `uint` type. IRInst* extractValueAtOffset( - IRBuilder& builder, TargetRequest* targetReq, IRInst* src, uint32_t offset, uint32_t size); + IRBuilder& builder, TargetProgram* targetReq, IRInst* src, uint32_t offset, uint32_t size); } diff --git a/source/slang/slang-ir-generics-lowering-context.cpp b/source/slang/slang-ir-generics-lowering-context.cpp index 212e16483..a7f75d7be 100644 --- a/source/slang/slang-ir-generics-lowering-context.cpp +++ b/source/slang/slang-ir-generics-lowering-context.cpp @@ -66,7 +66,7 @@ namespace Slang // For now the only type info we encapsualte is type size. IRSizeAndAlignment sizeAndAlignment; - getNaturalSizeAndAlignment(targetReq, (IRType*)typeInst, &sizeAndAlignment); + getNaturalSizeAndAlignment(targetProgram->getOptionSet(), (IRType*)typeInst, &sizeAndAlignment); builder->addRTTITypeSizeDecoration(result, sizeAndAlignment.size); // Give a name to the rtti object. @@ -235,7 +235,7 @@ namespace Slang // value must be stored out-of-line. // IRSizeAndAlignment sizeAndAlignment; - Result result = getNaturalSizeAndAlignment(targetReq, concreteType, &sizeAndAlignment); + Result result = getNaturalSizeAndAlignment(targetProgram->getOptionSet(), concreteType, &sizeAndAlignment); if(SLANG_FAILED(result) || (sizeAndAlignment.size > anyValueSize)) { // If the value must be stored out-of-line, we construct @@ -386,7 +386,7 @@ namespace Slang if (outLimit) *outLimit = anyValueSize; IRSizeAndAlignment sizeAndAlignment; - Result result = getNaturalSizeAndAlignment(targetReq, concreteType, &sizeAndAlignment); + Result result = getNaturalSizeAndAlignment(targetProgram->getOptionSet(), concreteType, &sizeAndAlignment); if (outTypeSize) *outTypeSize = sizeAndAlignment.size; if(SLANG_FAILED(result) || (sizeAndAlignment.size > anyValueSize)) diff --git a/source/slang/slang-ir-generics-lowering-context.h b/source/slang/slang-ir-generics-lowering-context.h index 509df6a33..3f0e09bd2 100644 --- a/source/slang/slang-ir-generics-lowering-context.h +++ b/source/slang/slang-ir-generics-lowering-context.h @@ -22,7 +22,7 @@ namespace Slang // we are processing. IRModule* module; - TargetRequest* targetReq; + TargetProgram* targetProgram; DiagnosticSink* sink; diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp index 0f9e88d20..ca9367ea0 100644 --- a/source/slang/slang-ir-glsl-legalize.cpp +++ b/source/slang/slang-ir-glsl-legalize.cpp @@ -2693,7 +2693,7 @@ void legalizeEntryPointParameterForGLSL( bool shouldUseOriginalEntryPointName(CodeGenContext* codeGenContext) { - if (auto hlslOptions = codeGenContext->getTargetReq()->getHLSLToVulkanLayoutOptions()) + if (auto hlslOptions = codeGenContext->getTargetProgram()->getHLSLToVulkanLayoutOptions()) { if (hlslOptions->getUseOriginalEntryPointName()) { diff --git a/source/slang/slang-ir-layout.cpp b/source/slang/slang-ir-layout.cpp index 7c34cea8d..313761d2c 100644 --- a/source/slang/slang-ir-layout.cpp +++ b/source/slang/slang-ir-layout.cpp @@ -51,7 +51,7 @@ namespace Slang { static Result _calcArraySizeAndAlignment( - TargetRequest* target, + CompilerOptionSet& optionSet, IRTypeLayoutRules* rules, IRType* elementType, IRInst* elementCountInst, @@ -69,7 +69,7 @@ static Result _calcArraySizeAndAlignment( } IRSizeAndAlignment elementTypeLayout; - SLANG_RETURN_ON_FAIL(getSizeAndAlignment(target, rules, elementType, &elementTypeLayout)); + SLANG_RETURN_ON_FAIL(getSizeAndAlignment(optionSet, rules, elementType, &elementTypeLayout)); elementTypeLayout = rules->alignCompositeElement(elementTypeLayout); *outSizeAndAlignment = IRSizeAndAlignment( @@ -85,13 +85,13 @@ IRIntegerValue getIntegerValueFromInst(IRInst* inst) } static Result _calcSizeAndAlignment( - TargetRequest* target, + CompilerOptionSet& optionSet, IRTypeLayoutRules* rules, IRType* type, IRSizeAndAlignment* outSizeAndAlignment) { int kPointerSize = 8; - switch (target->getTarget()) + switch (optionSet.getTarget()) { case CodeGenTarget::HostCPPSource: case CodeGenTarget::HostHostCallable: @@ -161,7 +161,7 @@ case kIROp_##TYPE##Type: \ SLANG_ASSERT(!seenFinalUnsizedArrayField); IRSizeAndAlignment fieldTypeLayout; - SLANG_RETURN_ON_FAIL(getSizeAndAlignment(target, rules, field->getFieldType(), &fieldTypeLayout)); + SLANG_RETURN_ON_FAIL(getSizeAndAlignment(optionSet, rules, field->getFieldType(), &fieldTypeLayout)); seenFinalUnsizedArrayField = fieldTypeLayout.size == IRSizeAndAlignment::kIndeterminateSize; structLayout.size = align(offset, fieldTypeLayout.alignment); @@ -202,7 +202,7 @@ case kIROp_##TYPE##Type: \ auto arrayType = cast<IRArrayType>(type); return _calcArraySizeAndAlignment( - target, + optionSet, rules , arrayType->getElementType(), arrayType->getElementCount(), @@ -213,7 +213,7 @@ case kIROp_##TYPE##Type: \ case kIROp_UnsizedArrayType: { auto unsizedArrayType = cast<IRUnsizedArrayType>(type); - getSizeAndAlignment(target, rules, unsizedArrayType->getElementType(), outSizeAndAlignment); + getSizeAndAlignment(optionSet, rules, unsizedArrayType->getElementType(), outSizeAndAlignment); outSizeAndAlignment->size = IRSizeAndAlignment::kIndeterminateSize; return SLANG_OK; } @@ -223,7 +223,7 @@ case kIROp_##TYPE##Type: \ { auto vecType = cast<IRVectorType>(type); IRSizeAndAlignment elementTypeLayout; - getSizeAndAlignment(target, rules, vecType->getElementType(), &elementTypeLayout); + getSizeAndAlignment(optionSet, rules, vecType->getElementType(), &elementTypeLayout); *outSizeAndAlignment = rules->getVectorSizeAndAlignment(elementTypeLayout, getIntegerValueFromInst(vecType->getElementCount())); return SLANG_OK; } @@ -245,7 +245,7 @@ case kIROp_##TYPE##Type: \ { auto elementType = tupleType->getOperand(i); IRSizeAndAlignment fieldTypeLayout; - SLANG_RETURN_ON_FAIL(getSizeAndAlignment(target, rules, (IRType*)elementType, &fieldTypeLayout)); + SLANG_RETURN_ON_FAIL(getSizeAndAlignment(optionSet, rules, (IRType*)elementType, &fieldTypeLayout)); resultLayout.size = align(resultLayout.size, fieldTypeLayout.alignment); resultLayout.alignment = std::max(resultLayout.alignment, fieldTypeLayout.alignment); } @@ -283,7 +283,7 @@ case kIROp_##TYPE##Type: \ { auto colVector = builder.getVectorType(matType->getElementType(), matType->getRowCount()); return _calcArraySizeAndAlignment( - target, + optionSet, rules, colVector, matType->getColumnCount(), @@ -293,7 +293,7 @@ case kIROp_##TYPE##Type: \ { auto rowVector = builder.getVectorType(matType->getElementType(), matType->getColumnCount()); return _calcArraySizeAndAlignment( - target, + optionSet, rules, rowVector, matType->getRowCount(), @@ -347,7 +347,7 @@ IRSizeAndAlignmentDecoration* findSizeAndAlignmentDecorationForLayout(IRType* ty return nullptr; } -Result getSizeAndAlignment(TargetRequest* target, IRTypeLayoutRules* rules, IRType* type, IRSizeAndAlignment* outSizeAndAlignment) +Result getSizeAndAlignment(CompilerOptionSet& optionSet, IRTypeLayoutRules* rules, IRType* type, IRSizeAndAlignment* outSizeAndAlignment) { if (auto decor = findSizeAndAlignmentDecorationForLayout(type, rules->ruleName)) { @@ -356,7 +356,7 @@ Result getSizeAndAlignment(TargetRequest* target, IRTypeLayoutRules* rules, IRTy } IRSizeAndAlignment sizeAndAlignment; - SLANG_RETURN_ON_FAIL(_calcSizeAndAlignment(target, rules, type, &sizeAndAlignment)); + SLANG_RETURN_ON_FAIL(_calcSizeAndAlignment(optionSet, rules, type, &sizeAndAlignment)); if (auto module = type->getModule()) { @@ -387,7 +387,7 @@ IROffsetDecoration* findOffsetDecorationForLayout(IRStructField* field, IRTypeLa return nullptr; } -Result getOffset(TargetRequest* target, IRTypeLayoutRules* rules, IRStructField* field, IRIntegerValue* outOffset) +Result getOffset(CompilerOptionSet& optionSet, IRTypeLayoutRules* rules, IRStructField* field, IRIntegerValue* outOffset) { if (auto decor = findOffsetDecorationForLayout(field, rules->ruleName)) { @@ -405,7 +405,7 @@ Result getOffset(TargetRequest* target, IRTypeLayoutRules* rules, IRStructField* return SLANG_FAIL; IRSizeAndAlignment structTypeLayout; - SLANG_RETURN_ON_FAIL(getSizeAndAlignment(target, rules, structType, &structTypeLayout)); + SLANG_RETURN_ON_FAIL(getSizeAndAlignment(optionSet, rules, structType, &structTypeLayout)); if (auto decor = findOffsetDecorationForLayout(field, rules->ruleName)) { @@ -492,15 +492,15 @@ struct Std140LayoutRules : IRTypeLayoutRules } }; -Result getNaturalSizeAndAlignment(TargetRequest* target, IRType* type, IRSizeAndAlignment* outSizeAndAlignment) +Result getNaturalSizeAndAlignment(CompilerOptionSet& optionSet, IRType* type, IRSizeAndAlignment* outSizeAndAlignment) { - return getSizeAndAlignment(target, IRTypeLayoutRules::getNatural(), type, outSizeAndAlignment); + return getSizeAndAlignment(optionSet, IRTypeLayoutRules::getNatural(), type, outSizeAndAlignment); } -Result getNaturalOffset(TargetRequest* target, IRStructField* field, IRIntegerValue* outOffset) +Result getNaturalOffset(CompilerOptionSet& optionSet, IRStructField* field, IRIntegerValue* outOffset) { - return getOffset(target, IRTypeLayoutRules::getNatural(), field, outOffset); + return getOffset(optionSet, IRTypeLayoutRules::getNatural(), field, outOffset); } @@ -508,14 +508,14 @@ Result getNaturalOffset(TargetRequest* target, IRStructField* field, IRIntegerVa // Std430 Layout ////////////////////////// -Result getStd430SizeAndAlignment(TargetRequest* target, IRType* type, IRSizeAndAlignment* outSizeAndAlignment) +Result getStd430SizeAndAlignment(CompilerOptionSet& optionSet, IRType* type, IRSizeAndAlignment* outSizeAndAlignment) { - return getSizeAndAlignment(target, IRTypeLayoutRules::getStd430(), type, outSizeAndAlignment); + return getSizeAndAlignment(optionSet, IRTypeLayoutRules::getStd430(), type, outSizeAndAlignment); } -Result getStd430Offset(TargetRequest* target, IRStructField* field, IRIntegerValue* outOffset) +Result getStd430Offset(CompilerOptionSet& optionSet, IRStructField* field, IRIntegerValue* outOffset) { - return getOffset(target, IRTypeLayoutRules::getStd430(), field, outOffset); + return getOffset(optionSet, IRTypeLayoutRules::getStd430(), field, outOffset); } IRTypeLayoutRules* IRTypeLayoutRules::getStd430() diff --git a/source/slang/slang-ir-layout.h b/source/slang/slang-ir-layout.h index 19360aa20..09da2a8f9 100644 --- a/source/slang/slang-ir-layout.h +++ b/source/slang/slang-ir-layout.h @@ -21,7 +21,7 @@ namespace Slang { -class TargetRequest; +struct CompilerOptionSet; /// Align `value` to the next multiple of `alignment`, which must be a power of two. inline IRIntegerValue align(IRIntegerValue value, int alignment) @@ -67,9 +67,9 @@ public: static IRTypeLayoutRules* get(IRTypeLayoutRuleName name); }; -Result getOffset(TargetRequest* target, IRTypeLayoutRules* rules, IRStructField* field, IRIntegerValue* outOffset); +Result getOffset(CompilerOptionSet& optionSet, IRTypeLayoutRules* rules, IRStructField* field, IRIntegerValue* outOffset); -Result getSizeAndAlignment(TargetRequest* target, IRTypeLayoutRules* rules, IRType* type, IRSizeAndAlignment* outSizeAndAlignment); +Result getSizeAndAlignment(CompilerOptionSet& optionSet, IRTypeLayoutRules* rules, IRType* type, IRSizeAndAlignment* outSizeAndAlignment); /// Compute (if necessary) and return the natural size and alignment of `type`. /// @@ -77,7 +77,7 @@ Result getSizeAndAlignment(TargetRequest* target, IRTypeLayoutRules* rules, IRTy /// general-purpose memory for the current target. In that case the /// type is considered to have no natural layout. /// -Result getNaturalSizeAndAlignment(TargetRequest* target, IRType* type, IRSizeAndAlignment* outSizeAndAlignment); +Result getNaturalSizeAndAlignment(CompilerOptionSet& optionSet, IRType* type, IRSizeAndAlignment* outSizeAndAlignment); /// Compute (if necessary) and return the natural offset of `field` /// @@ -85,7 +85,7 @@ Result getNaturalSizeAndAlignment(TargetRequest* target, IRType* type, IRSizeAnd /// that can be stored in general-purpose memory. In that case, the /// field is considered to have no natural offset. /// -Result getNaturalOffset(TargetRequest* target, IRStructField* field, IRIntegerValue* outOffset); +Result getNaturalOffset(CompilerOptionSet& optionSet, IRStructField* field, IRIntegerValue* outOffset); /// Compute (if necessary) and return the std430 size and alignment of `type`. /// @@ -93,7 +93,7 @@ Result getNaturalOffset(TargetRequest* target, IRStructField* field, IRIntegerVa /// general-purpose memory for the current target. In that case the /// type is considered to have no std430 layout. /// -Result getStd430SizeAndAlignment(TargetRequest* target, IRType* type, IRSizeAndAlignment* outSizeAndAlignment); +Result getStd430SizeAndAlignment(CompilerOptionSet& optionSet, IRType* type, IRSizeAndAlignment* outSizeAndAlignment); /// Compute (if necessary) and return the std430 offset of `field` /// @@ -101,7 +101,7 @@ Result getStd430SizeAndAlignment(TargetRequest* target, IRType* type, IRSizeAndA /// that can be stored in general-purpose memory. In that case, the /// field is considered to have no std430 offset. /// -Result getStd430Offset(TargetRequest* target, IRStructField* field, IRIntegerValue* outOffset); +Result getStd430Offset(CompilerOptionSet& optionSet, IRStructField* field, IRIntegerValue* outOffset); } diff --git a/source/slang/slang-ir-loop-unroll.cpp b/source/slang/slang-ir-loop-unroll.cpp index d998f5e61..753c930a8 100644 --- a/source/slang/slang-ir-loop-unroll.cpp +++ b/source/slang/slang-ir-loop-unroll.cpp @@ -67,7 +67,7 @@ static int _getLoopMaxIterationsToUnroll(IRLoop* loopInst) } static void _foldAndSimplifyLoopIteration( - TargetRequest* targetRequest, + TargetProgram* targetProgram, IRBuilder& builder, List<IRBlock*>& clonedBlocks, IRBlock* firstIterationBreakBlock, @@ -81,7 +81,7 @@ static void _foldAndSimplifyLoopIteration( { for (auto inst : b->getChildren()) { - tryReplaceInstUsesWithSimplifiedValue(targetRequest, builder.getModule(), inst); + tryReplaceInstUsesWithSimplifiedValue(targetProgram, builder.getModule(), inst); } } @@ -89,7 +89,7 @@ static void _foldAndSimplifyLoopIteration( // the phi arguments for next iteration evaluated (args in the new loop inst). for (auto inst : firstIterationBreakBlock->getChildren()) { - tryReplaceInstUsesWithSimplifiedValue(targetRequest, builder.getModule(), inst); + tryReplaceInstUsesWithSimplifiedValue(targetProgram, builder.getModule(), inst); } // Fold conditional branches into unconditional branches if the condition is known. @@ -148,7 +148,7 @@ static void _foldAndSimplifyLoopIteration( // Returns true if we can statically determine that the loop terminated within the iteration limit. // This operation assumes the loop does not have `continue` jumps, i.e. continueBlock == targetBlock. static bool _unrollLoop( - TargetRequest* targetRequest, + TargetProgram* targetProgram, IRModule* module, IRLoop* loopInst, List<IRBlock*>& blocks) @@ -341,7 +341,7 @@ static bool _unrollLoop( // conditional jumps can be folded into unconditional jumps. _foldAndSimplifyLoopIteration( - targetRequest, builder, clonedBlocks, firstIterationBreakBlock, unreachableBlock); + targetProgram, builder, clonedBlocks, firstIterationBreakBlock, unreachableBlock); // Now we have peeled off one iteration from the loop, we check if there are any // branches into next iteration, if not, the loop terminates and we are done. @@ -435,7 +435,7 @@ List<IRLoop*> collectLoopsInFunc(IRGlobalValueWithCode* func, const TFunc& filte } bool unrollLoopsInFunc( - TargetRequest* targetRequest, + TargetProgram* targetProgram, IRModule* module, IRGlobalValueWithCode* func, DiagnosticSink* sink) @@ -453,7 +453,7 @@ bool unrollLoopsInFunc( auto blocks = collectBlocksInRegion(func, loop); auto loopLoc = loop->sourceLoc; - if (!_unrollLoop(targetRequest, module, loop, blocks)) + if (!_unrollLoop(targetProgram, module, loop, blocks)) { if (sink) sink->diagnose(loopLoc, Diagnostics::cannotUnrollLoop); @@ -468,7 +468,7 @@ bool unrollLoopsInFunc( return true; } -bool unrollLoopsInModule(TargetRequest* targetRequest, IRModule* module, DiagnosticSink* sink) +bool unrollLoopsInModule(TargetProgram* target, IRModule* module, DiagnosticSink* sink) { SLANG_PROFILE; @@ -479,7 +479,7 @@ bool unrollLoopsInModule(TargetRequest* targetRequest, IRModule* module, Diagnos if (auto func = as<IRGlobalValueWithCode>(inst)) { - bool result = unrollLoopsInFunc(targetRequest, module, func, sink); + bool result = unrollLoopsInFunc(target, module, func, sink); if (!result) return false; } diff --git a/source/slang/slang-ir-loop-unroll.h b/source/slang/slang-ir-loop-unroll.h index 3b42afe80..d3402bf25 100644 --- a/source/slang/slang-ir-loop-unroll.h +++ b/source/slang/slang-ir-loop-unroll.h @@ -10,12 +10,12 @@ namespace Slang class DiagnosticSink; struct IRModule; struct IRBlock; - class TargetRequest; + class TargetProgram; // Return true if successfull, false if errors occurred. - bool unrollLoopsInFunc(TargetRequest*target, IRModule* module, IRGlobalValueWithCode* func, DiagnosticSink* sink); + bool unrollLoopsInFunc(TargetProgram* target, IRModule* module, IRGlobalValueWithCode* func, DiagnosticSink* sink); - bool unrollLoopsInModule(TargetRequest* target, IRModule* module, DiagnosticSink* sink); + bool unrollLoopsInModule(TargetProgram* target, IRModule* module, DiagnosticSink* sink); // Turn a loop with continue block into a loop with only back jumps and breaks. // Each iteration will be wrapped in a breakable region, where everything before `continue` diff --git a/source/slang/slang-ir-lower-append-consume-structured-buffer.cpp b/source/slang/slang-ir-lower-append-consume-structured-buffer.cpp index 1d4f10bb9..6fb1e3140 100644 --- a/source/slang/slang-ir-lower-append-consume-structured-buffer.cpp +++ b/source/slang/slang-ir-lower-append-consume-structured-buffer.cpp @@ -7,7 +7,7 @@ namespace Slang { - static void lowerStructuredBufferType(TargetRequest* target, IRHLSLStructuredBufferTypeBase* type) + static void lowerStructuredBufferType(TargetProgram* target, IRHLSLStructuredBufferTypeBase* type) { IRBuilder builder(type); builder.setInsertBefore(type); @@ -48,7 +48,7 @@ namespace Slang IRTypeLayout::Builder elementTypeLayoutBuilder(&builder); IRSizeAndAlignment elementSize; - getSizeAndAlignment(target, layoutRules, elementType, &elementSize); + getSizeAndAlignment(target->getOptionSet(), layoutRules, elementType, &elementSize); elementTypeLayoutBuilder.addResourceUsage(LayoutResourceKind::Uniform, LayoutSize((LayoutSize::RawValue)elementSize.getStride())); auto elementTypeLayout = elementTypeLayoutBuilder.build(); @@ -253,7 +253,7 @@ namespace Slang type->replaceUsesWith(structType); } - void lowerAppendConsumeStructuredBuffers(TargetRequest* target, IRModule* module, DiagnosticSink* sink) + void lowerAppendConsumeStructuredBuffers(TargetProgram* target, IRModule* module, DiagnosticSink* sink) { SLANG_UNUSED(sink); for (auto globalInst : module->getGlobalInsts()) diff --git a/source/slang/slang-ir-lower-append-consume-structured-buffer.h b/source/slang/slang-ir-lower-append-consume-structured-buffer.h index 81048724d..5030d08ca 100644 --- a/source/slang/slang-ir-lower-append-consume-structured-buffer.h +++ b/source/slang/slang-ir-lower-append-consume-structured-buffer.h @@ -7,11 +7,11 @@ namespace Slang { struct IRModule; class DiagnosticSink; - class TargetRequest; + class TargetProgram; /// For non-hlsl targets, lower append- and consume- structured buffers into `struct` types /// that contains two RWStructuredBuffer typed fields, one to store the elements, and one /// for the atomic buffer. - void lowerAppendConsumeStructuredBuffers(TargetRequest* target, IRModule* module, DiagnosticSink* sink); + void lowerAppendConsumeStructuredBuffers(TargetProgram* target, IRModule* module, DiagnosticSink* sink); } diff --git a/source/slang/slang-ir-lower-bit-cast.cpp b/source/slang/slang-ir-lower-bit-cast.cpp index 79e95f7de..7a9f605d2 100644 --- a/source/slang/slang-ir-lower-bit-cast.cpp +++ b/source/slang/slang-ir-lower-bit-cast.cpp @@ -9,7 +9,7 @@ namespace Slang struct BitCastLoweringContext { - TargetRequest* targetReq; + TargetProgram* targetProgram; IRModule* module; OrderedHashSet<IRInst*> workList; @@ -72,7 +72,7 @@ struct BitCastLoweringContext { IRIntegerValue fieldOffset = 0; SLANG_RELEASE_ASSERT( - getNaturalOffset(targetReq, field, &fieldOffset) == SLANG_OK); + getNaturalOffset(targetProgram->getOptionSet(), field, &fieldOffset) == SLANG_OK); auto fieldType = field->getFieldType(); auto fieldValue = readObject(builder, src, fieldType, (uint32_t)(fieldOffset + offset)); @@ -90,7 +90,7 @@ struct BitCastLoweringContext IRSizeAndAlignment elementLayout; SLANG_RELEASE_ASSERT( getNaturalSizeAndAlignment( - targetReq, arrayType->getElementType(), &elementLayout) == SLANG_OK); + targetProgram->getOptionSet(), arrayType->getElementType(), &elementLayout) == SLANG_OK); for (IRIntegerValue i = 0; i < arrayCount->value.intVal; i++) { elements.add(readObject( @@ -111,7 +111,7 @@ struct BitCastLoweringContext IRSizeAndAlignment elementLayout; SLANG_RELEASE_ASSERT( getNaturalSizeAndAlignment( - targetReq, vectorType->getElementType(), &elementLayout) == SLANG_OK); + targetProgram->getOptionSet(), vectorType->getElementType(), &elementLayout) == SLANG_OK); for (IRIntegerValue i = 0; i < elementCount->value.intVal; i++) { elements.add(readObject( @@ -136,7 +136,7 @@ struct BitCastLoweringContext matrixType->getElementType(), matrixType->getColumnCount()); IRSizeAndAlignment elementLayout; SLANG_RELEASE_ASSERT( - getNaturalSizeAndAlignment(targetReq, elementType, &elementLayout) == SLANG_OK); + getNaturalSizeAndAlignment(targetProgram->getOptionSet(), elementType, &elementLayout) == SLANG_OK); for (IRIntegerValue i = 0; i < elementCount->value.intVal; i++) { elements.add(readObject( @@ -153,7 +153,7 @@ struct BitCastLoweringContext case kIROp_Int16Type: case kIROp_UInt16Type: { - auto object = extractValueAtOffset(builder, targetReq, src, offset, 2); + auto object = extractValueAtOffset(builder, targetProgram, src, offset, 2); return builder.emitBitCast(type, object); } break; @@ -166,7 +166,7 @@ struct BitCastLoweringContext case kIROp_UIntPtrType: #endif { - auto object = extractValueAtOffset(builder, targetReq, src, offset, 4); + auto object = extractValueAtOffset(builder, targetProgram, src, offset, 4); return builder.emitBitCast(type, object); } break; @@ -179,8 +179,8 @@ struct BitCastLoweringContext #endif case kIROp_RawPointerType: { - auto low = extractValueAtOffset(builder, targetReq, src, offset, 4); - auto high = extractValueAtOffset(builder, targetReq, src, offset + 4, 4); + auto low = extractValueAtOffset(builder, targetProgram, src, offset, 4); + auto high = extractValueAtOffset(builder, targetProgram, src, offset + 4, 4); auto combined = builder.emitAdd(builder.getUInt64Type(), low, builder.emitShl( @@ -195,7 +195,7 @@ struct BitCastLoweringContext case kIROp_UInt8Type: case kIROp_Int8Type: { - auto object = extractValueAtOffset(builder, targetReq, src, offset, 1); + auto object = extractValueAtOffset(builder, targetProgram, src, offset, 1); return builder.emitBitCast(type, object); } break; @@ -247,11 +247,11 @@ struct BitCastLoweringContext } }; -void lowerBitCast(TargetRequest* targetReq, IRModule* module) +void lowerBitCast(TargetProgram* targetProgram, IRModule* module) { BitCastLoweringContext context; context.module = module; - context.targetReq = targetReq; + context.targetProgram = targetProgram; context.processModule(); } diff --git a/source/slang/slang-ir-lower-bit-cast.h b/source/slang/slang-ir-lower-bit-cast.h index 4e93dbe4f..cb80d0dab 100644 --- a/source/slang/slang-ir-lower-bit-cast.h +++ b/source/slang/slang-ir-lower-bit-cast.h @@ -8,8 +8,8 @@ namespace Slang { struct IRModule; -class TargetRequest; +class TargetProgram; -void lowerBitCast(TargetRequest* targetReq, IRModule* module); +void lowerBitCast(TargetProgram* targetReq, IRModule* module); } diff --git a/source/slang/slang-ir-lower-buffer-element-type.cpp b/source/slang/slang-ir-lower-buffer-element-type.cpp index 182b101df..5c797ab23 100644 --- a/source/slang/slang-ir-lower-buffer-element-type.cpp +++ b/source/slang/slang-ir-lower-buffer-element-type.cpp @@ -23,9 +23,9 @@ namespace Slang Dictionary<IRType*, LoweredElementTypeInfo> mapLoweredTypeToInfo[(int)IRTypeLayoutRuleName::_Count]; SlangMatrixLayoutMode defaultMatrixLayout = SLANG_MATRIX_LAYOUT_ROW_MAJOR; - TargetRequest* target; + TargetProgram* target; - LoweredElementTypeContext(TargetRequest* target, SlangMatrixLayoutMode inDefaultMatrixLayout) + LoweredElementTypeContext(TargetProgram* target, SlangMatrixLayoutMode inDefaultMatrixLayout) : target(target), defaultMatrixLayout(inDefaultMatrixLayout) {} @@ -230,7 +230,7 @@ namespace Slang { // For spirv, we always want to lower all matrix types, because matrix types // are considered abstract types. - if (!target->shouldEmitSPIRVDirectly()) + if (!target->getOptionSet().shouldEmitSPIRVDirectly()) { // For other targets, we only lower the matrix types if they differ from the default // matrix layout. @@ -257,7 +257,7 @@ namespace Slang auto vectorType = builder.getVectorType(matrixType->getElementType(), isColMajor?matrixType->getRowCount():matrixType->getColumnCount()); IRSizeAndAlignment elementSizeAlignment; - getSizeAndAlignment(target, rules, vectorType, &elementSizeAlignment); + getSizeAndAlignment(target->getOptionSet(), rules, vectorType, &elementSizeAlignment); elementSizeAlignment = rules->alignCompositeElement(elementSizeAlignment); auto arrayType = builder.getArrayType( @@ -279,7 +279,7 @@ namespace Slang // For spirv backend, we always want to lower all array types, even if the element type // comes out the same. This is because different layout rules may have different array // stride requirements. - if (!target->shouldEmitSPIRVDirectly()) + if (!target->getOptionSet().shouldEmitSPIRVDirectly()) { if (!loweredInnerTypeInfo.convertLoweredToOriginal) { @@ -297,7 +297,7 @@ namespace Slang auto structKey = builder.createStructKey(); builder.addNameHintDecoration(structKey, UnownedStringSlice("data")); IRSizeAndAlignment elementSizeAlignment; - getSizeAndAlignment(target, rules, loweredInnerTypeInfo.loweredType, &elementSizeAlignment); + getSizeAndAlignment(target->getOptionSet(), rules, loweredInnerTypeInfo.loweredType, &elementSizeAlignment); elementSizeAlignment = rules->alignCompositeElement(elementSizeAlignment); auto innerArrayType = builder.getArrayType( loweredInnerTypeInfo.loweredType, @@ -326,7 +326,7 @@ namespace Slang // For spirv backend, we always want to lower all array types, even if the element type // comes out the same. This is because different layout rules may have different array // stride requirements. - if (!target->shouldEmitSPIRVDirectly()) + if (!target->getOptionSet().shouldEmitSPIRVDirectly()) { // For non-spirv target, we skip lowering this type if all field types are unchanged. if (isTrivial) @@ -403,9 +403,9 @@ namespace Slang return info; } - if (target->shouldEmitSPIRVDirectly()) + if (target->getOptionSet().shouldEmitSPIRVDirectly()) { - switch (target->getTarget()) + switch (target->getTargetReq()->getTarget()) { case CodeGenTarget::SPIRV: case CodeGenTarget::SPIRVAssembly: @@ -465,7 +465,7 @@ namespace Slang return info; info = getLoweredTypeInfoImpl(type, rules); IRSizeAndAlignment sizeAlignment; - getSizeAndAlignment(target, rules, info.loweredType, &sizeAlignment); + getSizeAndAlignment(target->getOptionSet(), rules, info.loweredType, &sizeAlignment); loweredTypeInfo[(int)rules->ruleName].set(type, info); mapLoweredTypeToInfo[(int)rules->ruleName].set(info.loweredType, info); return info; @@ -801,9 +801,9 @@ namespace Slang } }; - void lowerBufferElementTypeToStorageType(TargetRequest* target, IRModule* module) + void lowerBufferElementTypeToStorageType(TargetProgram* target, IRModule* module) { - SlangMatrixLayoutMode defaultMatrixMode = (SlangMatrixLayoutMode)target->getDefaultMatrixLayoutMode(); + SlangMatrixLayoutMode defaultMatrixMode = (SlangMatrixLayoutMode)target->getOptionSet().getMatrixLayoutMode(); if (defaultMatrixMode == SLANG_MATRIX_LAYOUT_MODE_UNKNOWN) defaultMatrixMode = SLANG_MATRIX_LAYOUT_ROW_MAJOR; LoweredElementTypeContext context(target, defaultMatrixMode); @@ -811,17 +811,17 @@ namespace Slang } - IRTypeLayoutRules* getTypeLayoutRuleForBuffer(TargetRequest* target, IRType* bufferType) + IRTypeLayoutRules* getTypeLayoutRuleForBuffer(TargetProgram* target, IRType* bufferType) { - if (!isKhronosTarget(target)) + if (!isKhronosTarget(target->getTargetReq())) return IRTypeLayoutRules::getNatural(); // If we are just emitting GLSL, we can just use the general layout rule. - if (!target->shouldEmitSPIRVDirectly()) + if (!target->getOptionSet().shouldEmitSPIRVDirectly()) return IRTypeLayoutRules::getNatural(); // If the user specified a scalar buffer layout, then just use that. - if (target->getForceGLSLScalarBufferLayout()) + if (target->getOptionSet().shouldUseScalarLayout()) return IRTypeLayoutRules::getNatural(); // The default behavior is to use std140 for constant buffers and std430 for other buffers. diff --git a/source/slang/slang-ir-lower-buffer-element-type.h b/source/slang/slang-ir-lower-buffer-element-type.h index b96a34c6e..4d0a7eabe 100644 --- a/source/slang/slang-ir-lower-buffer-element-type.h +++ b/source/slang/slang-ir-lower-buffer-element-type.h @@ -4,7 +4,7 @@ namespace Slang { struct IRModule; - class TargetRequest; + class TargetProgram; struct IRTypeLayoutRules; struct IRType; @@ -15,11 +15,11 @@ namespace Slang // This pass needs to take place after type legalization, and before array return type lowering // because it may create functions that returns array typed values. // - void lowerBufferElementTypeToStorageType(TargetRequest* target, IRModule* module); + void lowerBufferElementTypeToStorageType(TargetProgram* target, IRModule* module); // Returns the type layout rules should be used for a buffer resource type. - IRTypeLayoutRules* getTypeLayoutRuleForBuffer(TargetRequest* target, IRType* bufferType); + IRTypeLayoutRules* getTypeLayoutRuleForBuffer(TargetProgram* target, IRType* bufferType); } #endif diff --git a/source/slang/slang-ir-lower-generic-call.cpp b/source/slang/slang-ir-lower-generic-call.cpp index c312d3c88..e67d97a48 100644 --- a/source/slang/slang-ir-lower-generic-call.cpp +++ b/source/slang/slang-ir-lower-generic-call.cpp @@ -243,7 +243,7 @@ namespace Slang // Don't process intrinsic functions. UnownedStringSlice intrinsicDef; if (findTargetIntrinsicDefinition(getResolvedInstForDecorations(loweredFunc), - sharedContext->targetReq->getTargetCaps(), intrinsicDef)) + sharedContext->targetProgram->getTargetReq()->getTargetCaps(), intrinsicDef)) return; // All callees should have already been lowered in lower-generic-functions pass. diff --git a/source/slang/slang-ir-lower-generic-function.cpp b/source/slang/slang-ir-lower-generic-function.cpp index 1e15f4384..47dc6cc79 100644 --- a/source/slang/slang-ir-lower-generic-function.cpp +++ b/source/slang/slang-ir-lower-generic-function.cpp @@ -45,7 +45,7 @@ namespace Slang SLANG_ASSERT(func); // Do not lower intrinsic functions. UnownedStringSlice intrinsicDef; - if (!func->isDefinition() || findTargetIntrinsicDefinition(func, sharedContext->targetReq->getTargetCaps(), intrinsicDef)) + if (!func->isDefinition() || findTargetIntrinsicDefinition(func, sharedContext->targetProgram->getTargetReq()->getTargetCaps(), intrinsicDef)) { sharedContext->loweredGenericFunctions[genericValue] = genericValue; return genericValue; diff --git a/source/slang/slang-ir-lower-generics.cpp b/source/slang/slang-ir-lower-generics.cpp index f3aa2145e..fd8c9257b 100644 --- a/source/slang/slang-ir-lower-generics.cpp +++ b/source/slang/slang-ir-lower-generics.cpp @@ -205,19 +205,19 @@ namespace Slang } void lowerGenerics( - TargetRequest* targetReq, + TargetProgram* targetProgram, IRModule* module, DiagnosticSink* sink) { SLANG_PROFILE; SharedGenericsLoweringContext sharedContext(module); - sharedContext.targetReq = targetReq; + sharedContext.targetProgram = targetProgram; sharedContext.sink = sink; checkTypeConformanceExists(&sharedContext); - inferAnyValueSizeWhereNecessary(targetReq, module); + inferAnyValueSizeWhereNecessary(targetProgram, module); // Replace all `makeExistential` insts with `makeExistentialWithRTTI` // before making any other changes. This is necessary because a parameter of @@ -255,7 +255,7 @@ namespace Slang // real RTTI objects and witness tables. specializeRTTIObjects(&sharedContext, sink); - simplifyIR(sharedContext.targetReq, module, IRSimplificationOptions::getFast()); + simplifyIR(sharedContext.targetProgram, module, IRSimplificationOptions::getFast()); lowerTuples(module, sink); if (sink->getErrorCount() != 0) diff --git a/source/slang/slang-ir-lower-generics.h b/source/slang/slang-ir-lower-generics.h index 3b29219bd..2ec250803 100644 --- a/source/slang/slang-ir-lower-generics.h +++ b/source/slang/slang-ir-lower-generics.h @@ -7,12 +7,12 @@ namespace Slang {
struct IRModule;
class DiagnosticSink;
- class TargetRequest;
+ class TargetProgram;
/// Lower generic and interface-based code to ordinary types and functions using
/// dynamic dispatch mechanisms.
void lowerGenerics(
- TargetRequest* targetReq,
+ TargetProgram* targetReq,
IRModule* module,
DiagnosticSink* sink);
diff --git a/source/slang/slang-ir-lower-l-value-cast.cpp b/source/slang/slang-ir-lower-l-value-cast.cpp index 4548c5156..db0861ca4 100644 --- a/source/slang/slang-ir-lower-l-value-cast.cpp +++ b/source/slang/slang-ir-lower-l-value-cast.cpp @@ -209,24 +209,24 @@ struct LValueCastLoweringContext castInst->removeAndDeallocate(); } - LValueCastLoweringContext(TargetRequest* targetRequest, IRModule* module): - m_targetReq(targetRequest), + LValueCastLoweringContext(TargetProgram* target, IRModule* module): + m_targetProgram(target), m_module(module) { - m_intermediateSourceLanguage = getIntermediateSourceLanguageForTarget(targetRequest); + m_intermediateSourceLanguage = getIntermediateSourceLanguageForTarget(target); } // The intermediate source language used to produce code for the target. // If no intermediate source language is used will be SourceLanguage::Unknown. SourceLanguage m_intermediateSourceLanguage = SourceLanguage::Unknown; - TargetRequest* m_targetReq; + TargetProgram* m_targetProgram; IRModule* m_module; OrderedHashSet<IRInst*> m_workList; }; -void lowerLValueCast(TargetRequest* targetReq, IRModule* module) +void lowerLValueCast(TargetProgram* target, IRModule* module) { - LValueCastLoweringContext context(targetReq, module); + LValueCastLoweringContext context(target, module); context.processModule(); } diff --git a/source/slang/slang-ir-lower-l-value-cast.h b/source/slang/slang-ir-lower-l-value-cast.h index 3d93d1200..ea0daf06b 100644 --- a/source/slang/slang-ir-lower-l-value-cast.h +++ b/source/slang/slang-ir-lower-l-value-cast.h @@ -15,9 +15,9 @@ namespace Slang { struct IRModule; -class TargetRequest; +class TargetProgram; -void lowerLValueCast(TargetRequest* targetReq, IRModule* module); +void lowerLValueCast(TargetProgram* target, IRModule* module); } // namespace Slang diff --git a/source/slang/slang-ir-lower-reinterpret.cpp b/source/slang/slang-ir-lower-reinterpret.cpp index c4d39b635..afc710539 100644 --- a/source/slang/slang-ir-lower-reinterpret.cpp +++ b/source/slang/slang-ir-lower-reinterpret.cpp @@ -10,7 +10,7 @@ namespace Slang struct ReinterpretLoweringContext { - TargetRequest* targetReq; + TargetProgram* targetProgram; DiagnosticSink* sink; IRModule* module; OrderedHashSet<IRInst*> workList; @@ -83,16 +83,16 @@ struct ReinterpretLoweringContext } }; -void lowerReinterpret(TargetRequest* targetReq, IRModule* module, DiagnosticSink* sink) +void lowerReinterpret(TargetProgram* target, IRModule* module, DiagnosticSink* sink) { // Before processing reinterpret insts, ensure that existential types without // user-defined sizes have inferred sizes where possible. // - inferAnyValueSizeWhereNecessary(targetReq, module); + inferAnyValueSizeWhereNecessary(target, module); ReinterpretLoweringContext context; context.module = module; - context.targetReq = targetReq; + context.targetProgram = target; context.sink = sink; context.processModule(); } diff --git a/source/slang/slang-ir-lower-reinterpret.h b/source/slang/slang-ir-lower-reinterpret.h index 623ccb32e..ac49d2492 100644 --- a/source/slang/slang-ir-lower-reinterpret.h +++ b/source/slang/slang-ir-lower-reinterpret.h @@ -8,9 +8,9 @@ namespace Slang { struct IRModule; -class TargetRequest; +class TargetProgram; class DiagnosticSink; -void lowerReinterpret(TargetRequest* targetReq, IRModule* module, DiagnosticSink* sink); +void lowerReinterpret(TargetProgram* targetReq, IRModule* module, DiagnosticSink* sink); } diff --git a/source/slang/slang-ir-lower-size-of.cpp b/source/slang/slang-ir-lower-size-of.cpp index a8b599031..5e7e26824 100644 --- a/source/slang/slang-ir-lower-size-of.cpp +++ b/source/slang/slang-ir-lower-size-of.cpp @@ -55,7 +55,7 @@ struct SizeOfLikeLoweringContext IRSizeAndAlignment sizeAndAlignment; - if (SLANG_FAILED(getNaturalSizeAndAlignment(m_targetReq, typeOperand, &sizeAndAlignment))) + if (SLANG_FAILED(getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), typeOperand, &sizeAndAlignment))) { // Output a diagnostic failure if(sizeOfLikeInst->getOp() == kIROp_AlignOf) @@ -84,22 +84,22 @@ struct SizeOfLikeLoweringContext sizeOfLikeInst->removeAndDeallocate(); } - SizeOfLikeLoweringContext(TargetRequest* targetReq, IRModule* module, DiagnosticSink* sink): + SizeOfLikeLoweringContext(TargetProgram* targetProgram, IRModule* module, DiagnosticSink* sink): m_module(module), - m_targetReq(targetReq), + m_targetProgram(targetProgram), m_sink(sink) { } - TargetRequest* m_targetReq; + TargetProgram* m_targetProgram; DiagnosticSink* m_sink; IRModule* m_module; OrderedHashSet<IRInst*> m_workList; }; -void lowerSizeOfLike(TargetRequest* targetReq, IRModule* module, DiagnosticSink* sink) +void lowerSizeOfLike(TargetProgram* targetProgram, IRModule* module, DiagnosticSink* sink) { - SizeOfLikeLoweringContext context(targetReq, module, sink); + SizeOfLikeLoweringContext context(targetProgram, module, sink); context.processModule(); } diff --git a/source/slang/slang-ir-lower-size-of.h b/source/slang/slang-ir-lower-size-of.h index 4205aa2f0..90ab40fbd 100644 --- a/source/slang/slang-ir-lower-size-of.h +++ b/source/slang/slang-ir-lower-size-of.h @@ -7,10 +7,10 @@ namespace Slang { struct IRModule; -class TargetRequest; +class TargetProgram; class DiagnosticSink; -void lowerSizeOfLike(TargetRequest* target, IRModule* module, DiagnosticSink* sink); +void lowerSizeOfLike(TargetProgram* target, IRModule* module, DiagnosticSink* sink); } // namespace Slang diff --git a/source/slang/slang-ir-peephole.cpp b/source/slang/slang-ir-peephole.cpp index 39a137490..f9fca35e3 100644 --- a/source/slang/slang-ir-peephole.cpp +++ b/source/slang/slang-ir-peephole.cpp @@ -18,7 +18,7 @@ struct PeepholeContext : InstPassBase bool removeOldInst = true; bool isInGeneric = false; - TargetRequest* targetRequest; + TargetProgram* targetProgram; void maybeRemoveOldInst(IRInst* inst) { @@ -965,13 +965,13 @@ struct PeepholeContext : InstPassBase } case kIROp_GetNaturalStride: { - if (targetRequest) + if (targetProgram) { if (isInGeneric) break; auto type = inst->getOperand(0)->getDataType(); IRSizeAndAlignment sizeAlignment; - getNaturalSizeAndAlignment(targetRequest, type, &sizeAlignment); + getNaturalSizeAndAlignment(targetProgram->getOptionSet(), type, &sizeAlignment); IRBuilder builder(module); builder.setInsertBefore(inst); auto stride = builder.getIntValue(inst->getDataType(), sizeAlignment.getStride()); @@ -1069,24 +1069,24 @@ struct PeepholeContext : InstPassBase } }; -bool peepholeOptimize(TargetRequest* target, IRModule* module) +bool peepholeOptimize(TargetProgram* target, IRModule* module) { PeepholeContext context = PeepholeContext(module); - context.targetRequest = target; + context.targetProgram = target; return context.processModule(); } -bool peepholeOptimize(TargetRequest* target, IRInst* func) +bool peepholeOptimize(TargetProgram* target, IRInst* func) { PeepholeContext context = PeepholeContext(func->getModule()); - context.targetRequest = target; + context.targetProgram = target; return context.processFunc(func); } -bool peepholeOptimizeGlobalScope(TargetRequest* target, IRModule* module) +bool peepholeOptimizeGlobalScope(TargetProgram* target, IRModule* module) { PeepholeContext context = PeepholeContext(module); - context.targetRequest = target; + context.targetProgram = target; bool result = false; for (;;) @@ -1101,13 +1101,13 @@ bool peepholeOptimizeGlobalScope(TargetRequest* target, IRModule* module) return result; } -bool tryReplaceInstUsesWithSimplifiedValue(TargetRequest* target, IRModule* module, IRInst* inst) +bool tryReplaceInstUsesWithSimplifiedValue(TargetProgram* target, IRModule* module, IRInst* inst) { if (inst != tryConstantFoldInst(module, inst)) return true; PeepholeContext context = PeepholeContext(inst->getModule()); - context.targetRequest = target; + context.targetProgram = target; context.removeOldInst = false; context.processInst(inst); return context.changed; diff --git a/source/slang/slang-ir-peephole.h b/source/slang/slang-ir-peephole.h index 28edfbe78..9aa2d6164 100644 --- a/source/slang/slang-ir-peephole.h +++ b/source/slang/slang-ir-peephole.h @@ -6,11 +6,11 @@ namespace Slang struct IRModule; struct IRCall; struct IRInst; - class TargetRequest; + class TargetProgram; /// Apply peephole optimizations. - bool peepholeOptimize(TargetRequest* target, IRModule* module); - bool peepholeOptimize(TargetRequest* target, IRInst* func); - bool peepholeOptimizeGlobalScope(TargetRequest* target, IRModule* module); - bool tryReplaceInstUsesWithSimplifiedValue(TargetRequest* target, IRModule* module, IRInst* inst); + bool peepholeOptimize(TargetProgram* target, IRModule* module); + bool peepholeOptimize(TargetProgram* target, IRInst* func); + bool peepholeOptimizeGlobalScope(TargetProgram* target, IRModule* module); + bool tryReplaceInstUsesWithSimplifiedValue(TargetProgram* target, IRModule* module, IRInst* inst); } diff --git a/source/slang/slang-ir-specialize-dispatch.cpp b/source/slang/slang-ir-specialize-dispatch.cpp index d57e1ed96..9eba0aa4f 100644 --- a/source/slang/slang-ir-specialize-dispatch.cpp +++ b/source/slang/slang-ir-specialize-dispatch.cpp @@ -213,7 +213,7 @@ void ensureWitnessTableSequentialIDs(SharedGenericsLoweringContext* sharedContex { StringBuilder generatedMangledName; - auto linkage = sharedContext->targetReq->getLinkage(); + auto linkage = sharedContext->targetProgram->getTargetReq()->getLinkage(); for (auto inst : sharedContext->module->getGlobalInsts()) { if (inst->getOp() == kIROp_WitnessTable) diff --git a/source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp b/source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp index cbc085da5..5a7fd9412 100644 --- a/source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp +++ b/source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp @@ -157,10 +157,6 @@ struct AssociatedTypeLookupSpecializationContext IRBuilder builder(sharedContext->module); builder.setInsertBefore(inst); auto witnessTableArg = inst->getWitnessTable(); - if (witnessTableArg->getDataType()->getOp() == kIROp_WitnessTableType) - { - witnessTableArg = builder.emitGetSequentialIDInst(witnessTableArg); - } auto callInst = builder.emitCallInst( builder.getWitnessTableIDType(interfaceType), func, witnessTableArg); inst->replaceUsesWith(callInst); diff --git a/source/slang/slang-ir-specialize-function-call.cpp b/source/slang/slang-ir-specialize-function-call.cpp index 01cdf4cd9..7e5d9b59c 100644 --- a/source/slang/slang-ir-specialize-function-call.cpp +++ b/source/slang/slang-ir-specialize-function-call.cpp @@ -79,7 +79,6 @@ struct FunctionParameterSpecializationContext // `specializeFunctionParameters` function. // CodeGenContext* codeGenContext; - TargetRequest* targetRequest; IRModule* module; // The condition on which parameters to specialize. @@ -173,7 +172,7 @@ struct FunctionParameterSpecializationContext if(!func->isDefinition()) return false; UnownedStringSlice def; - if (findTargetIntrinsicDefinition(func, targetRequest->getTargetCaps(), def)) + if (findTargetIntrinsicDefinition(func, codeGenContext->getTargetReq()->getTargetCaps(), def)) return false; // With the basic checks out of the way, there are // two conditions we care about: @@ -891,7 +890,7 @@ struct FunctionParameterSpecializationContext // addCallsToWorkListRec(newFunc); - simplifyFunc(targetRequest, newFunc, IRSimplificationOptions::getFast()); + simplifyFunc(codeGenContext->getTargetProgram(), newFunc, IRSimplificationOptions::getFast()); return newFunc; } @@ -908,7 +907,6 @@ bool specializeFunctionCalls( { FunctionParameterSpecializationContext context; context.codeGenContext = codeGenContext; - context.targetRequest = codeGenContext->getTargetReq(); context.module = module; context.condition = condition; diff --git a/source/slang/slang-ir-specialize-matrix-layout.cpp b/source/slang/slang-ir-specialize-matrix-layout.cpp index 5ce61f4cf..8f6ca1b12 100644 --- a/source/slang/slang-ir-specialize-matrix-layout.cpp +++ b/source/slang/slang-ir-specialize-matrix-layout.cpp @@ -24,12 +24,12 @@ namespace Slang } } - void specializeMatrixLayout(TargetRequest* target, IRModule* module) + void specializeMatrixLayout(TargetProgram* target, IRModule* module) { List<IRMatrixType*> typeWorkList; visitParent(typeWorkList, module->getModuleInst()); - IRIntegerValue defaultLayout = target->getDefaultMatrixLayoutMode(); + IRIntegerValue defaultLayout = target->getOptionSet().getMatrixLayoutMode(); if (defaultLayout == SLANG_MATRIX_LAYOUT_MODE_UNKNOWN) defaultLayout = SLANG_MATRIX_LAYOUT_ROW_MAJOR; diff --git a/source/slang/slang-ir-specialize-matrix-layout.h b/source/slang/slang-ir-specialize-matrix-layout.h index 3074f72cf..b0bde29f0 100644 --- a/source/slang/slang-ir-specialize-matrix-layout.h +++ b/source/slang/slang-ir-specialize-matrix-layout.h @@ -4,12 +4,12 @@ namespace Slang { struct IRModule; - class TargetRequest; + class TargetProgram; // Repalce all matrix types whose layout is not specified with the default layout // of the target request. // - void specializeMatrixLayout(TargetRequest* target, IRModule* module); + void specializeMatrixLayout(TargetProgram* target, IRModule* module); } diff --git a/source/slang/slang-ir-specialize-resources.cpp b/source/slang/slang-ir-specialize-resources.cpp index 4fd87e173..af7f41207 100644 --- a/source/slang/slang-ir-specialize-resources.cpp +++ b/source/slang/slang-ir-specialize-resources.cpp @@ -20,6 +20,7 @@ struct ResourceParameterSpecializationCondition : FunctionCallSpecializeConditio // legal for a given target. TargetRequest* targetRequest = nullptr; + TargetProgram* targetProgram = nullptr; bool doesParamWantSpecialization(IRParam* param, IRInst* arg) { @@ -63,7 +64,7 @@ struct ResourceParameterSpecializationCondition : FunctionCallSpecializeConditio // if( isKhronosTarget(targetRequest) ) { - if (targetRequest->shouldEmitSPIRVDirectly()) + if (targetProgram->getOptionSet().shouldEmitSPIRVDirectly()) return isIllegalSPIRVParameterType(type, isArray); else return isIllegalGLSLParameterType(type); @@ -90,6 +91,7 @@ bool specializeResourceParameters( { bool result = false; ResourceParameterSpecializationCondition condition; + condition.targetProgram = codeGenContext->getTargetProgram(); condition.targetRequest = codeGenContext->getTargetReq(); bool changed = true; while (changed) @@ -1186,7 +1188,7 @@ bool specializeResourceUsage( // and turned into SSA temporaries. Such optimization may enable // the following passes to "see" and specialize more cases. // - simplifyIR(codeGenContext->getTargetReq(), irModule, IRSimplificationOptions::getFast()); + simplifyIR(codeGenContext->getTargetProgram(), irModule, IRSimplificationOptions::getFast()); result |= changed; } if (unspecializableFuncs.getCount() == 0) @@ -1206,7 +1208,7 @@ bool specializeResourceUsage( inlineCall(call); }); } - simplifyIR(codeGenContext->getTargetReq(), irModule, IRSimplificationOptions::getFast()); + simplifyIR(codeGenContext->getTargetProgram(), irModule, IRSimplificationOptions::getFast()); } return result; } diff --git a/source/slang/slang-ir-specialize.cpp b/source/slang/slang-ir-specialize.cpp index 9de574a9b..3320a7d09 100644 --- a/source/slang/slang-ir-specialize.cpp +++ b/source/slang/slang-ir-specialize.cpp @@ -47,17 +47,17 @@ struct SpecializationContext // we are specializing. IRModule* module; DiagnosticSink* sink; - TargetRequest* targetRequest; + TargetProgram* targetProgram; bool changed = false; - SpecializationContext(IRModule* inModule, TargetRequest* target) + SpecializationContext(IRModule* inModule, TargetProgram* target) : workList(*inModule->getContainerPool().getList<IRInst>()) , workListSet(*inModule->getContainerPool().getHashSet<IRInst>()) , cleanInsts(*module->getContainerPool().getHashSet<IRInst>()) , module(inModule) - , targetRequest(target) + , targetProgram(target) { } @@ -1524,7 +1524,7 @@ struct SpecializationContext // addToWorkList(newFunc); - simplifyFunc(targetRequest, newFunc, IRSimplificationOptions::getFast()); + simplifyFunc(targetProgram, newFunc, IRSimplificationOptions::getFast()); return newFunc; } @@ -2243,7 +2243,7 @@ struct SpecializationContext }; bool specializeModule( - TargetRequest* target, + TargetProgram* target, IRModule* module, DiagnosticSink* sink) { @@ -2383,7 +2383,7 @@ IRInst* specializeGenericImpl( // the same thing. if (auto func = as<IRFunc>(specializedVal)) { - simplifyFunc(context->targetRequest, func, IRSimplificationOptions::getFast()); + simplifyFunc(context->targetProgram, func, IRSimplificationOptions::getFast()); } return specializedVal; diff --git a/source/slang/slang-ir-specialize.h b/source/slang/slang-ir-specialize.h index 23d523a43..d95fa229a 100644 --- a/source/slang/slang-ir-specialize.h +++ b/source/slang/slang-ir-specialize.h @@ -5,11 +5,11 @@ namespace Slang { struct IRModule; class DiagnosticSink; -class TargetRequest; +class TargetProgram; /// Specialize generic and interface-based code to use concrete types. bool specializeModule( - TargetRequest* target, + TargetProgram* target, IRModule* module, DiagnosticSink* sink); diff --git a/source/slang/slang-ir-spirv-legalize.cpp b/source/slang/slang-ir-spirv-legalize.cpp index 62829f553..f2979cb79 100644 --- a/source/slang/slang-ir-spirv-legalize.cpp +++ b/source/slang/slang-ir-spirv-legalize.cpp @@ -97,14 +97,14 @@ struct SPIRVLegalizationContext : public SourceEmitterBase if (m_loweredStructuredBufferTypes.tryGetValue(inst, result)) return result; - auto layoutRules = getTypeLayoutRuleForBuffer(m_sharedContext->m_targetRequest, inst); + auto layoutRules = getTypeLayoutRuleForBuffer(m_sharedContext->m_targetProgram, inst); IRBuilder builder(m_sharedContext->m_irModule); builder.setInsertBefore(inst); auto elementType = inst->getElementType(); IRSizeAndAlignment elementSize; - getSizeAndAlignment(m_sharedContext->m_targetRequest, layoutRules, elementType, &elementSize); + getSizeAndAlignment(m_sharedContext->m_targetProgram->getOptionSet(), layoutRules, elementType, &elementSize); elementSize = layoutRules->alignCompositeElement(elementSize); const auto arrayType = builder.getUnsizedArrayType(inst->getElementType(), builder.getIntValue(builder.getIntType(), elementSize.getStride())); @@ -112,7 +112,7 @@ struct SPIRVLegalizationContext : public SourceEmitterBase const auto arrayKey = builder.createStructKey(); builder.createStructField(structType, arrayKey, arrayType); IRSizeAndAlignment structSize; - getSizeAndAlignment(m_sharedContext->m_targetRequest, layoutRules, structType, &structSize); + getSizeAndAlignment(m_sharedContext->m_targetProgram->getOptionSet(), layoutRules, structType, &structSize); StringBuilder nameSb; switch (inst->getOp()) @@ -190,9 +190,9 @@ struct SPIRVLegalizationContext : public SourceEmitterBase builder.setInsertBefore(cbParamInst); auto newCbType = builder.getType(cbParamInst->getDataType()->getOp(), structType); cbParamInst->setFullType(newCbType); - auto rules = getTypeLayoutRuleForBuffer(m_sharedContext->m_targetRequest, cbParamInst->getDataType()); + auto rules = getTypeLayoutRuleForBuffer(m_sharedContext->m_targetProgram, cbParamInst->getDataType()); IRSizeAndAlignment sizeAlignment; - getSizeAndAlignment(m_sharedContext->m_targetRequest, rules, structType, &sizeAlignment); + getSizeAndAlignment(m_sharedContext->m_targetProgram->getOptionSet(), rules, structType, &sizeAlignment); traverseUses(cbParamInst, [&](IRUse* use) { builder.setInsertBefore(use->getUser()); @@ -2099,7 +2099,7 @@ void buildEntryPointReferenceGraph(SPIRVEmitSharedContext* context, IRModule* mo visit(workList[i].entryPoint, workList[i].inst); } -void simplifyIRForSpirvLegalization(TargetRequest* target, DiagnosticSink* sink, IRModule* module) +void simplifyIRForSpirvLegalization(TargetProgram* target, DiagnosticSink* sink, IRModule* module) { bool changed = true; const int kMaxIterations = 8; @@ -2147,7 +2147,7 @@ void legalizeIRForSPIRV( { SLANG_UNUSED(entryPoints); legalizeSPIRV(context, module); - simplifyIRForSpirvLegalization(context->m_targetRequest, codeGenContext->getSink(), module); + simplifyIRForSpirvLegalization(context->m_targetProgram, codeGenContext->getSink(), module); buildEntryPointReferenceGraph(context, module); } diff --git a/source/slang/slang-ir-spirv-legalize.h b/source/slang/slang-ir-spirv-legalize.h index c9b75c07f..1064e5aa0 100644 --- a/source/slang/slang-ir-spirv-legalize.h +++ b/source/slang/slang-ir-spirv-legalize.h @@ -17,15 +17,17 @@ struct SPIRVEmitSharedContext { IRModule* m_irModule; TargetRequest* m_targetRequest; + TargetProgram* m_targetProgram; Dictionary<IRTargetIntrinsicDecoration*, RefPtr<SpvSnippet>> m_parsedSpvSnippets; Dictionary<IRInst*, HashSet<IRFunc*>> m_referencingEntryPoints; // The entry-points that directly or transitively reference this global inst. DiagnosticSink* m_sink; const SPIRVCoreGrammarInfo* m_grammarInfo; - SPIRVEmitSharedContext(IRModule* module, TargetRequest* target, DiagnosticSink* sink) + SPIRVEmitSharedContext(IRModule* module, TargetProgram* program, DiagnosticSink* sink) : m_irModule(module), - m_targetRequest(target), + m_targetProgram(program), + m_targetRequest(program->getTargetReq()), m_sink(sink), m_grammarInfo(&module->getSession()->getSPIRVCoreGrammarInfo()) {} diff --git a/source/slang/slang-ir-ssa-simplification.cpp b/source/slang/slang-ir-ssa-simplification.cpp index f20d1295c..77cad9f6c 100644 --- a/source/slang/slang-ir-ssa-simplification.cpp +++ b/source/slang/slang-ir-ssa-simplification.cpp @@ -17,7 +17,7 @@ namespace Slang { // Run a combination of SSA, SCCP, SimplifyCFG, and DeadCodeElimination pass // until no more changes are possible. - void simplifyIR(TargetRequest* target, IRModule* module, IRSimplificationOptions options, DiagnosticSink* sink) + void simplifyIR(TargetProgram* target, IRModule* module, IRSimplificationOptions options, DiagnosticSink* sink) { SLANG_PROFILE; bool changed = true; @@ -68,7 +68,7 @@ namespace Slang } } - void simplifyNonSSAIR(TargetRequest* target, IRModule* module, IRSimplificationOptions options) + void simplifyNonSSAIR(TargetProgram* target, IRModule* module, IRSimplificationOptions options) { bool changed = true; const int kMaxIterations = 8; @@ -90,7 +90,7 @@ namespace Slang } - void simplifyFunc(TargetRequest* target, IRGlobalValueWithCode* func, IRSimplificationOptions options, DiagnosticSink* sink) + void simplifyFunc(TargetProgram* target, IRGlobalValueWithCode* func, IRSimplificationOptions options, DiagnosticSink* sink) { bool changed = true; const int kMaxIterations = 8; diff --git a/source/slang/slang-ir-ssa-simplification.h b/source/slang/slang-ir-ssa-simplification.h index d338bf23d..c15ffc822 100644 --- a/source/slang/slang-ir-ssa-simplification.h +++ b/source/slang/slang-ir-ssa-simplification.h @@ -8,7 +8,7 @@ namespace Slang struct IRModule; struct IRGlobalValueWithCode; class DiagnosticSink; - class TargetRequest; + class TargetProgram; struct IRSimplificationOptions { @@ -29,10 +29,10 @@ namespace Slang // Run a combination of SSA, SCCP, SimplifyCFG, and DeadCodeElimination pass // until no more changes are possible. - void simplifyIR(TargetRequest* target, IRModule* module, IRSimplificationOptions options, DiagnosticSink* sink = nullptr); + void simplifyIR(TargetProgram* target, IRModule* module, IRSimplificationOptions options, DiagnosticSink* sink = nullptr); // Run simplifications on IR that is out of SSA form. - void simplifyNonSSAIR(TargetRequest* target, IRModule* module, IRSimplificationOptions options); + void simplifyNonSSAIR(TargetProgram* target, IRModule* module, IRSimplificationOptions options); - void simplifyFunc(TargetRequest* target, IRGlobalValueWithCode* func, IRSimplificationOptions options, DiagnosticSink* sink = nullptr); + void simplifyFunc(TargetProgram* target, IRGlobalValueWithCode* func, IRSimplificationOptions options, DiagnosticSink* sink = nullptr); } diff --git a/source/slang/slang-ir-string-hash.cpp b/source/slang/slang-ir-string-hash.cpp index b7e37d21e..8074bd149 100644 --- a/source/slang/slang-ir-string-hash.cpp +++ b/source/slang/slang-ir-string-hash.cpp @@ -56,26 +56,19 @@ void addGlobalHashedStringLiterals(const StringSlicePool& pool, IRModule* module const Index slicesCount = slices.getCount(); - // Note: This pass is using the extremely low-level `_allocateInst` operation on `IRModule` - // as an optimization. By allocating the instruction here in an "empty" state and then filling - // its operands in in place, we can avoid allocating space for a temporary `List<IRInst*>` to - // hold the IR string values created in the loop below. - // - // TODO: We should probably either eliminate this micro-optimization and just use a `List<IRInst*>` - // here, *or* we should devise a more first-class system for doing in-place instruction creation - // like that that can be compatible with desirable features like automatic deduplication. - // - IRInst* globalHashedInst = module->_allocateInst(kIROp_GlobalHashedStringLiterals, int(slicesCount)); - builder.addInst(globalHashedInst); - - auto operands = globalHashedInst->getOperands(); - + ShortList<IRInst*> operandInsts; for (Index i = 0; i < slicesCount; ++i) { IRStringLit* stringLit = builder.getStringValue(slices[i]); - operands[i].init(globalHashedInst, stringLit); + operandInsts.add(stringLit); } + IRInst* globalHashedInst = builder.emitIntrinsicInst( + nullptr, + kIROp_GlobalHashedStringLiterals, + UInt(slicesCount), + operandInsts.getArrayView().getBuffer()); + // Mark to keep alive builder.addKeepAliveDecoration(globalHashedInst); } diff --git a/source/slang/slang-ir-validate.cpp b/source/slang/slang-ir-validate.cpp index 5caa8a66e..2868c9929 100644 --- a/source/slang/slang-ir-validate.cpp +++ b/source/slang/slang-ir-validate.cpp @@ -378,7 +378,7 @@ namespace Slang CompileRequestBase* compileRequest, IRModule* module) { - if (!compileRequest->shouldValidateIR) + if (!compileRequest->getLinkage()->m_optionSet.getBoolOption(CompilerOptionName::ValidateIr)) return; auto sink = compileRequest->getSink(); diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index 8fef6f535..8531e4029 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -2342,8 +2342,6 @@ static void addNameHint( String name = getNameForNameHint(context, decl); if(name.getLength() == 0) return; - if (name == "MyBlockName2") - printf("break"); context->irBuilder->addNameHintDecoration(inst, name.getUnownedSlice()); } @@ -10238,7 +10236,7 @@ RefPtr<IRModule> generateIRForTranslationUnit( SharedIRGenContext sharedContextStorage( session, translationUnit->compileRequest->getSink(), - translationUnit->compileRequest->getLinkage()->m_obfuscateCode, + translationUnit->compileRequest->optionSet.shouldObfuscateCode(), translationUnit->getModuleDecl(), translationUnit->compileRequest->getLinkage()); SharedIRGenContext* sharedContext = &sharedContextStorage; @@ -10252,7 +10250,7 @@ RefPtr<IRModule> generateIRForTranslationUnit( IRBuilder* builder = &builderStorage; context->irBuilder = builder; - context->includeDebugInfo = compileRequest->getLinkage()->debugInfoLevel != DebugInfoLevel::None; + context->includeDebugInfo = compileRequest->getLinkage()->m_optionSet.getDebugInfoLevel() != DebugInfoLevel::None; // We need to emit IR for all public/exported symbols // in the translation unit. @@ -10450,7 +10448,7 @@ RefPtr<IRModule> generateIRForTranslationUnit( Linkage* linkage = compileRequest->getLinkage(); - stripOptions.shouldStripNameHints = linkage->m_obfuscateCode; + stripOptions.shouldStripNameHints = linkage->m_optionSet.shouldObfuscateCode(); // If we are generating an obfuscated source map, we don't want to strip locs, // we want to generate *new* locs that can be mapped (via source map) @@ -10474,7 +10472,7 @@ RefPtr<IRModule> generateIRForTranslationUnit( options.keepExportsAlive = true; eliminateDeadCode(module, options); - if (linkage->m_obfuscateCode) + if (linkage->m_optionSet.shouldObfuscateCode()) { // The obfuscated source map is stored on the module obfuscateModuleLocs(module, compileRequest->getSourceManager()); @@ -10494,7 +10492,7 @@ RefPtr<IRModule> generateIRForTranslationUnit( // If we are being asked to dump IR during compilation, // then we can dump the initial IR for the module here. - if(compileRequest->shouldDumpIR) + if(compileRequest->optionSet.shouldDumpIR()) { DiagnosticSinkWriter writer(compileRequest->getSink()); @@ -10525,7 +10523,7 @@ struct SpecializedComponentTypeIRGenContext : ComponentTypeVisitor SharedIRGenContext sharedContextStorage( session, sink, - linkage->m_obfuscateCode, + linkage->m_optionSet.shouldObfuscateCode(), nullptr, linkage ); @@ -10664,7 +10662,7 @@ struct TypeConformanceIRGenContext linkage = typeConformance->getLinkage(); session = linkage->getSessionImpl(); - SharedIRGenContext sharedContextStorage(session, sink, linkage->m_obfuscateCode, nullptr, linkage); + SharedIRGenContext sharedContextStorage(session, sink, linkage->m_optionSet.shouldObfuscateCode(), nullptr, linkage); SharedIRGenContext* sharedContext = &sharedContextStorage; IRGenContext contextStorage(sharedContext, linkage->getASTBuilder()); @@ -11016,7 +11014,7 @@ RefPtr<IRModule> TargetProgram::createIRModuleForLayout(DiagnosticSink* sink) SharedIRGenContext sharedContextStorage( session, sink, - linkage->m_obfuscateCode, + linkage->m_optionSet.shouldObfuscateCode(), nullptr, linkage); auto sharedContext = &sharedContextStorage; @@ -11111,12 +11109,12 @@ RefPtr<IRModule> TargetProgram::createIRModuleForLayout(DiagnosticSink* sink) } // Lets strip and run DCE here - if (linkage->m_obfuscateCode) + if (linkage->m_optionSet.shouldObfuscateCode()) { IRStripOptions stripOptions; - stripOptions.shouldStripNameHints = linkage->m_obfuscateCode; - stripOptions.stripSourceLocs = linkage->m_obfuscateCode; + stripOptions.shouldStripNameHints = true; + stripOptions.stripSourceLocs = true;; stripFrontEndOnlyInstructions(irModule, stripOptions); diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp index ca8b60d31..8e94b73cc 100644 --- a/source/slang/slang-options.cpp +++ b/source/slang/slang-options.cpp @@ -35,8 +35,8 @@ #include "../core/slang-char-util.h" #include "../core/slang-name-value.h" - #include "../core/slang-command-options-writer.h" +#include "slang-compiler-options.h" #include <assert.h> @@ -45,124 +45,7 @@ namespace Slang { namespace { // anonymous // All of the options are given an unique enum -enum class OptionKind -{ - // General - - MacroDefine, - DepFile, - EntryPointName, - Specialize, - Help, - HelpStyle, - Include, - Language, - MatrixLayoutColumn, - MatrixLayoutRow, - ModuleName, - Output, - Profile, - Stage, - Target, - Version, - WarningsAsErrors, - DisableWarnings, - EnableWarning, - DisableWarning, - DumpWarningDiagnostics, - InputFilesRemain, - EmitIr, - ReportDownstreamTime, - ReportPerfBenchmark, - SkipSPIRVValidation, - - SourceEmbedStyle, - SourceEmbedName, - SourceEmbedLanguage, - - // Target - - Capability, - DefaultImageFormatUnknown, - DisableDynamicDispatch, - DisableSpecialization, - FloatingPointMode, - DebugInformation, - LineDirectiveMode, - Optimization, - Obfuscate, - - VulkanBindShift, - VulkanBindGlobals, - VulkanInvertY, - VulkanUseEntryPointName, - VulkanUseGLLayout, - VulkanEmitReflection, - - GLSLForceScalarLayout, - EnableEffectAnnotations, - - EmitSpirvViaGLSL, - EmitSpirvDirectly, - SPIRVCoreGrammarJSON, - - // Downstream - - CompilerPath, - DefaultDownstreamCompiler, - DownstreamArgs, - PassThrough, - - // Repro - - DumpRepro, - DumpReproOnError, - ExtractRepro, - LoadRepro, - LoadReproDirectory, - ReproFallbackDirectory, - - // Debugging - - DumpAst, - DumpIntermediatePrefix, - DumpIntermediates, - DumpIr, - DumpIrIds, - PreprocessorOutput, - NoCodeGen, - OutputIncludes, - ReproFileSystem, - SerialIr, - SkipCodeGen, - ValidateIr, - VerbosePaths, - VerifyDebugSerialIr, - - // Experimental - - FileSystem, - Heterogeneous, - NoMangle, - AllowGLSL, - - // Internal - - ArchiveType, - CompileStdLib, - Doc, - IrCompression, - LoadStdLib, - ReferenceModule, - SaveStdLib, - SaveStdLibBinSource, - TrackLiveness, - - // Deprecated - ParameterBlocksUseRegisterSpaces, - - CountOf, -}; +typedef CompilerOptionName OptionKind; struct Option { @@ -670,7 +553,7 @@ void initCommandOptions(CommandOptions& options) // We can now check that the whole range is available. If this fails it means there // is an enum in the list that hasn't been setup as an option! - SLANG_ASSERT(options.hasContiguousUserValueRange(CommandOptions::LookupKind::Option, UserValue(0), UserValue(OptionKind::CountOf))); + SLANG_ASSERT(options.hasContiguousUserValueRange(CommandOptions::LookupKind::Option, UserValue(0), UserValue(OptionKind::CountOfParsableOptions))); SLANG_ASSERT(options.hasContiguousUserValueRange(CommandOptions::LookupKind::Category, UserValue(0), UserValue(ValueCategory::CountOf))); } @@ -767,12 +650,9 @@ struct OptionsParser struct RawTarget { CodeGenTarget format = CodeGenTarget::Unknown; - ProfileVersion profileVersion = ProfileVersion::Unknown; SlangTargetFlags targetFlags = kDefaultTargetFlags; int targetID = -1; - FloatingPointMode floatingPointMode = FloatingPointMode::Default; - bool forceGLSLScalarLayout = false; - List<CapabilityName> capabilityAtoms; + CompilerOptionSet optionSet; // State for tracking command-line errors bool conflictingProfilesSet = false; @@ -886,10 +766,6 @@ struct OptionsParser // before the first "proper" entry point is specified. RawEntryPoint m_defaultEntryPoint; - SlangCompileFlags m_flags = 0; - - RefPtr<HLSLToVulkanLayoutOptions> m_hlslToVulkanLayoutOptions; - List<RawTranslationUnit> m_rawTranslationUnits; // If we already have a translation unit for Slang code, then this will give its index. @@ -902,6 +778,12 @@ struct OptionsParser int m_translationUnitCount = 0; int m_currentTranslationUnitIndex = -1; + bool m_hasLoadedRepro = false; + bool m_compileStdLib = false; + slang::CompileStdLibFlags m_compileStdLibFlags; + + SlangArchiveType m_archiveType = SLANG_ARCHIVE_TYPE_RIFF_LZ4; + List<RawOutput> m_rawOutputs; DiagnosticSink m_parseSink; @@ -909,19 +791,6 @@ struct OptionsParser FrontEndCompileRequest* m_frontEndReq = nullptr; - SlangMatrixLayoutMode m_defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_MODE_UNKNOWN; - - // The default archive type is zip - SlangArchiveType m_archiveType = SLANG_ARCHIVE_TYPE_ZIP; - - bool m_compileStdLib = false; - slang::CompileStdLibFlags m_compileStdLibFlags = 0; - bool m_hasLoadedRepro = false; - - String m_spirvCoreGrammarJSONPath; - - bool m_allowGLSLInput = false; - CommandLineReader m_reader; CommandOptionsWriter::Style m_helpStyle = CommandOptionsWriter::Style::Text; @@ -1161,26 +1030,26 @@ OptionsParser::RawTarget* OptionsParser::getCurrentTarget() void OptionsParser::setProfileVersion(RawTarget* rawTarget, ProfileVersion profileVersion) { - if (rawTarget->profileVersion != ProfileVersion::Unknown) + if (rawTarget->optionSet.getProfileVersion() != ProfileVersion::Unknown) { rawTarget->redundantProfileSet = true; - if (profileVersion != rawTarget->profileVersion) + if (profileVersion != rawTarget->optionSet.getProfileVersion()) { rawTarget->conflictingProfilesSet = true; } } - rawTarget->profileVersion = profileVersion; + rawTarget->optionSet.setProfileVersion(profileVersion); } void OptionsParser::addCapabilityAtom(RawTarget* rawTarget, CapabilityName atom) { - rawTarget->capabilityAtoms.add(atom); + rawTarget->optionSet.addCapabilityAtom(atom); } void OptionsParser::setFloatingPointMode(RawTarget* rawTarget, FloatingPointMode mode) { - rawTarget->floatingPointMode = mode; + rawTarget->optionSet.set(CompilerOptionName::FloatingPointMode, mode); } /* static */bool OptionsParser::_passThroughRequiresStage(PassThroughMode passThrough) @@ -1294,67 +1163,6 @@ SlangResult OptionsParser::_compileReproDirectory(SlangSession* session, EndToEn return SLANG_OK; } -SlangResult OptionsParser::_overrideDiagnostics(const UnownedStringSlice& identifierList, Severity originalSeverity, Severity overrideSeverity) -{ - List<UnownedStringSlice> slices; - StringUtil::split(identifierList, ',', slices); - - for (const auto& slice : slices) - { - SLANG_RETURN_ON_FAIL(_overrideDiagnostic(slice, originalSeverity, overrideSeverity)); - } - return SLANG_OK; -} - -SlangResult OptionsParser::_overrideDiagnostic(const UnownedStringSlice& identifier, Severity originalSeverity, Severity overrideSeverity) -{ - auto diagnosticsLookup = getDiagnosticsLookup(); - - const DiagnosticInfo* diagnostic = nullptr; - Int diagnosticId = -1; - - // If it starts with a digit we assume it a number - if (identifier.getLength() > 0 && (CharUtil::isDigit(identifier[0]) || identifier[0] == '-')) - { - if (SLANG_FAILED(StringUtil::parseInt(identifier, diagnosticId))) - { - m_sink->diagnose(SourceLoc(), Diagnostics::unknownDiagnosticName, identifier); - return SLANG_FAIL; - } - - // If we use numbers, we don't worry if we can't find a diagnostic - // and silently ignore. This was the previous behavior, and perhaps - // provides a way to safely disable warnings, without worrying about - // the version of the compiler. - diagnostic = diagnosticsLookup->getDiagnosticById(diagnosticId); - } - else - { - diagnostic = diagnosticsLookup->findDiagnosticByName(identifier); - if (!diagnostic) - { - m_sink->diagnose(SourceLoc(), Diagnostics::unknownDiagnosticName, identifier); - return SLANG_FAIL; - } - diagnosticId = diagnostic->id; - } - - // If we are only allowing certain original severities check it's the right type - if (diagnostic && originalSeverity != Severity::Disable && diagnostic->severity != originalSeverity) - { - // Strictly speaking the diagnostic name is known, but it's not the right severity - // to be converted from, so it is an 'unknown name' in the context of severity... - // Or perhaps we want another diagnostic - m_sink->diagnose(SourceLoc(), Diagnostics::unknownDiagnosticName, identifier); - return SLANG_FAIL; - } - - // Override the diagnostic severity in the sink - m_requestImpl->getSink()->overrideDiagnosticSeverity(int(diagnosticId), overrideSeverity, diagnostic); - - return SLANG_OK; -} - SlangResult OptionsParser::_dumpDiagnostics(Severity originalSeverity) { // Get the diagnostics and dump them @@ -1784,20 +1592,28 @@ SlangResult OptionsParser::_parse( int argc, char const* const* argv) { - // Copy some state out of the current request, in case we've been called - // after some other initialization has been performed. - m_flags = m_requestImpl->getFrontEndReq()->compileFlags; - // Set up the args CommandLineArgs args(m_cmdLineContext); + // Converts input args into args in 'args'. // Doing so will allocate some SourceLoc space from the CommandLineContext. args.setArgs(argv, argc); + auto linkage = m_requestImpl->getLinkage(); + + // Before we do anything else lets strip out all of the downstream arguments. + DownstreamArgs downstreamArgs(m_cmdLineContext); + + + SLANG_RETURN_ON_FAIL(downstreamArgs.stripDownstreamArgs(args, 0, m_sink)); + for (auto& entry : downstreamArgs.m_entries) { - auto linkage = m_requestImpl->getLinkage(); - // Before we do anything else lets strip out all of the downstream arguments. - SLANG_RETURN_ON_FAIL(linkage->m_downstreamArgs.stripDownstreamArgs(args, 0, m_sink)); + String serializedArgs = entry.args.serialize(); + CompilerOptionValue v; + v.kind = CompilerOptionValueKind::String; + v.stringValue = entry.name; + v.stringValue2 = serializedArgs; + linkage->m_optionSet.add(CompilerOptionName::DownstreamArgs, v); } m_reader.init(&args, m_sink); @@ -1827,9 +1643,37 @@ SlangResult OptionsParser::_parse( switch (optionKind) { - case OptionKind::NoMangle: m_flags |= SLANG_COMPILE_FLAG_NO_MANGLING; break; - case OptionKind::AllowGLSL: m_allowGLSLInput = true; break; - case OptionKind::EmitIr: m_requestImpl->m_emitIr = true; break; + case OptionKind::NoMangle: + case OptionKind::AllowGLSL: + case OptionKind::EmitIr: + case OptionKind::DumpIntermediates: + case OptionKind::DumpReproOnError: + case OptionKind::ReportDownstreamTime: + case OptionKind::ReportPerfBenchmark: + case OptionKind::SkipSPIRVValidation: + case OptionKind::DisableSpecialization: + case OptionKind::DisableDynamicDispatch: + case OptionKind::TrackLiveness: + case OptionKind::SkipCodeGen: + case OptionKind::ParameterBlocksUseRegisterSpaces: + case OptionKind::ValidateIr: + case OptionKind::DumpIr: + case OptionKind::VulkanInvertY: + case OptionKind::VulkanUseEntryPointName: + case OptionKind::VulkanUseGLLayout: + case OptionKind::VulkanEmitReflection: + case OptionKind::MatrixLayoutRow: + case OptionKind::MatrixLayoutColumn: + case OptionKind::DefaultImageFormatUnknown: + case OptionKind::Obfuscate: + case OptionKind::OutputIncludes: + case OptionKind::PreprocessorOutput: + case OptionKind::DumpAst: + linkage->m_optionSet.set(optionKind, true); break; + break; + case OptionKind::NoCodeGen: + linkage->m_optionSet.set(OptionKind::SkipCodeGen, true); break; + break; case OptionKind::LoadStdLib: { CommandLineArg fileName; @@ -1842,7 +1686,11 @@ SlangResult OptionsParser::_parse( break; } case OptionKind::CompileStdLib: m_compileStdLib = true; break; - case OptionKind::ArchiveType: SLANG_RETURN_ON_FAIL(_expectValue(m_archiveType)); break; + case OptionKind::ArchiveType: + { + SLANG_RETURN_ON_FAIL(_expectValue(m_archiveType)); + break; + } case OptionKind::SaveStdLib: { CommandLineArg fileName; @@ -1871,8 +1719,6 @@ SlangResult OptionsParser::_parse( File::writeAllText(fileName.value, builder); break; } - case OptionKind::NoCodeGen: m_flags |= SLANG_COMPILE_FLAG_NO_CODEGEN; break; - case OptionKind::DumpIntermediates: m_compileRequest->setDumpIntermediates(true); break; case OptionKind::DumpIrIds: { m_frontEndReq->m_irDumpOptions.flags |= IRDumpOptions::Flag::DumpDebugIds; @@ -1882,31 +1728,26 @@ SlangResult OptionsParser::_parse( { CommandLineArg prefix; SLANG_RETURN_ON_FAIL(m_reader.expectArg(prefix)); - m_requestImpl->m_dumpIntermediatePrefix = prefix.value; + linkage->m_optionSet.set(CompilerOptionName::DumpIntermediatePrefix, prefix.value); break; } - case OptionKind::OutputIncludes: m_frontEndReq->outputIncludes = true; break; - case OptionKind::DumpIr: m_frontEndReq->shouldDumpIR = true; break; - case OptionKind::PreprocessorOutput: m_frontEndReq->outputPreprocessor = true; break; - case OptionKind::DumpAst: m_frontEndReq->shouldDumpAST = true; break; case OptionKind::Doc: { // If compiling stdlib is enabled, will write out documentation m_compileStdLibFlags |= slang::CompileStdLibFlag::WriteDocumentation; // Enable writing out documentation on the req - m_frontEndReq->shouldDocument = true; + linkage->m_optionSet.set(CompilerOptionName::Doc, true); break; } case OptionKind::DumpRepro: { CommandLineArg dumpRepro; SLANG_RETURN_ON_FAIL(m_reader.expectArg(dumpRepro)); - m_requestImpl->m_dumpRepro = dumpRepro.value; + linkage->m_optionSet.set(OptionKind::DumpRepro, dumpRepro.value); m_compileRequest->enableReproCapture(); break; } - case OptionKind::DumpReproOnError: m_requestImpl->m_dumpReproOnError = true; break; case OptionKind::ExtractRepro: { CommandLineArg reproName; @@ -1922,21 +1763,6 @@ SlangResult OptionsParser::_parse( } break; } - case OptionKind::ReportDownstreamTime: - { - m_compileRequest->setReportDownstreamTime(true); - break; - } - case OptionKind::ReportPerfBenchmark: - { - m_compileRequest->setReportPerfBenchmark(true); - break; - } - case OptionKind::SkipSPIRVValidation: - { - m_compileRequest->setSkipSPIRVValidation(true); - break; - } case OptionKind::ModuleName: { CommandLineArg moduleName; @@ -1986,64 +1812,50 @@ SlangResult OptionsParser::_parse( } case OptionKind::ReproFileSystem: SLANG_RETURN_ON_FAIL(_parseReproFileSystem(arg)); break; case OptionKind::SerialIr: m_frontEndReq->useSerialIRBottleneck = true; break; - case OptionKind::DisableSpecialization: m_requestImpl->disableSpecialization = true; break; - case OptionKind::DisableDynamicDispatch: m_requestImpl->disableDynamicDispatch = true; break; - case OptionKind::TrackLiveness: m_requestImpl->setTrackLiveness(true); break; - case OptionKind::VerbosePaths: m_requestImpl->getSink()->setFlag(DiagnosticSink::Flag::VerbosePath); break; + case OptionKind::VerbosePaths: + m_requestImpl->getSink()->setFlag(DiagnosticSink::Flag::VerbosePath); break; case OptionKind::DumpWarningDiagnostics: _dumpDiagnostics(Severity::Warning); break; case OptionKind::WarningsAsErrors: { CommandLineArg operand; SLANG_RETURN_ON_FAIL(m_reader.expectArg(operand)); - - if (operand.value == "all") - { - // TODO(JS): - // Perhaps there needs to be a way to disable this selectively. - m_requestImpl->getSink()->setFlag(DiagnosticSink::Flag::TreatWarningsAsErrors); - } - else - { - SLANG_RETURN_ON_FAIL(_overrideDiagnostics(operand.value.getUnownedSlice(), Severity::Warning, Severity::Error)); - } + linkage->m_optionSet.add(OptionKind::WarningsAsErrors, operand.value.getUnownedSlice()); break; } case OptionKind::DisableWarnings: { CommandLineArg operand; SLANG_RETURN_ON_FAIL(m_reader.expectArg(operand)); - SLANG_RETURN_ON_FAIL(_overrideDiagnostics(operand.value.getUnownedSlice(), Severity::Warning, Severity::Disable)); + //SLANG_RETURN_ON_FAIL(_overrideDiagnostics(operand.value.getUnownedSlice(), Severity::Warning, Severity::Disable)); + linkage->m_optionSet.add(OptionKind::DisableWarnings, operand.value.getUnownedSlice()); break; } case OptionKind::DisableWarning: { // 5 because -Wno- auto name = argValue.getUnownedSlice().tail(5); - SLANG_RETURN_ON_FAIL(_overrideDiagnostic(name, Severity::Warning, Severity::Disable)); + linkage->m_optionSet.add(OptionKind::DisableWarning, name); + + //SLANG_RETURN_ON_FAIL(_overrideDiagnostic(name, Severity::Warning, Severity::Disable)); break; } case OptionKind::EnableWarning: { // 2 because -W auto name = argValue.getUnownedSlice().tail(2); + linkage->m_optionSet.add(OptionKind::EnableWarning, name); // Enable the warning - SLANG_RETURN_ON_FAIL(_overrideDiagnostic(name, Severity::Warning, Severity::Warning)); + //SLANG_RETURN_ON_FAIL(_overrideDiagnostic(name, Severity::Warning, Severity::Warning)); break; } case OptionKind::VerifyDebugSerialIr: m_frontEndReq->verifyDebugSerialization = true; break; - case OptionKind::ValidateIr: m_frontEndReq->shouldValidateIR = true; break; - case OptionKind::SkipCodeGen: m_requestImpl->m_shouldSkipCodegen = true; break; - case OptionKind::ParameterBlocksUseRegisterSpaces: - { - getCurrentTarget()->targetFlags |= SLANG_TARGET_FLAG_PARAMETER_BLOCKS_USE_REGISTER_SPACES; - break; - } case OptionKind::IrCompression: { CommandLineArg name; SLANG_RETURN_ON_FAIL(m_reader.expectArg(name)); - - SLANG_RETURN_ON_FAIL(SerialParseUtil::parseCompressionType(name.value.getUnownedSlice(), m_requestImpl->getLinkage()->serialCompressionType)); + SerialCompressionType compressionType; + SLANG_RETURN_ON_FAIL(SerialParseUtil::parseCompressionType(name.value.getUnownedSlice(), compressionType)); + linkage->m_optionSet.set(optionKind, compressionType); break; } case OptionKind::Target: @@ -2078,13 +1890,13 @@ SlangResult OptionsParser::_parse( if (m_reader.hasArg() && m_reader.peekArg().value == toSlice("all")) { m_reader.advance(); - m_hlslToVulkanLayoutOptions->setAllShift(kind, shift); + linkage->m_optionSet.add(CompilerOptionName::VulkanBindShiftAll, (int)kind, (int)shift); } else { Int set; SLANG_RETURN_ON_FAIL(_expectInt(arg, set)); - m_hlslToVulkanLayoutOptions->setShift(kind, set, shift); + linkage->m_optionSet.add(CompilerOptionName::VulkanBindShift, (uint8_t)kind, (int)set, (int)shift); } break; } @@ -2094,32 +1906,7 @@ SlangResult OptionsParser::_parse( Int binding, bindingSet; SLANG_RETURN_ON_FAIL(_expectInt(arg, binding)); SLANG_RETURN_ON_FAIL(_expectInt(arg, bindingSet)); - - m_hlslToVulkanLayoutOptions->setGlobalsBinding(Index(bindingSet), Index(binding)); - break; - } - case OptionKind::VulkanInvertY: - { - // -fvk-invert-y - m_hlslToVulkanLayoutOptions->setInvertY(true); - break; - } - case OptionKind::VulkanUseEntryPointName: - { - // -fvk-use-entrypoint-name - m_hlslToVulkanLayoutOptions->setUseOriginalEntryPointName(true); - break; - } - case OptionKind::VulkanUseGLLayout: - { - // -fvk-use-gl-layout - m_hlslToVulkanLayoutOptions->setUseGLLayout(true); - break; - } - case OptionKind::VulkanEmitReflection: - { - // -fvk-invert-y - m_hlslToVulkanLayoutOptions->setEmitSPIRVReflectionInfo(true); + linkage->m_optionSet.set(OptionKind::VulkanBindGlobals, (int)binding, (int)bindingSet); break; } case OptionKind::Profile: SLANG_RETURN_ON_FAIL(_parseProfile(arg)); break; @@ -2172,7 +1959,7 @@ SlangResult OptionsParser::_parse( } case OptionKind::GLSLForceScalarLayout: { - getCurrentTarget()->forceGLSLScalarLayout = true; + getCurrentTarget()->optionSet.add(CompilerOptionName::GLSLForceScalarLayout, true); break; } case OptionKind::EnableEffectAnnotations: @@ -2327,8 +2114,6 @@ SlangResult OptionsParser::_parse( } break; } - case OptionKind::MatrixLayoutRow: m_defaultMatrixLayoutMode = SlangMatrixLayoutMode(kMatrixLayoutMode_RowMajor); break; - case OptionKind::MatrixLayoutColumn: m_defaultMatrixLayoutMode = SlangMatrixLayoutMode(kMatrixLayoutMode_ColumnMajor); break; case OptionKind::LineDirectiveMode: { SlangLineDirectiveMode value; @@ -2357,8 +2142,6 @@ SlangResult OptionsParser::_parse( break; } case OptionKind::DebugInformation: SLANG_RETURN_ON_FAIL(_parseDebugInformation(arg)); break; - case OptionKind::DefaultImageFormatUnknown: m_requestImpl->useUnknownImageFormatAsDefault = true; break; - case OptionKind::Obfuscate: m_requestImpl->getLinkage()->m_obfuscateCode = true; break; case OptionKind::FileSystem: { typedef TypeTextUtil::FileSystemType FileSystemType; @@ -2401,7 +2184,7 @@ SlangResult OptionsParser::_parse( { CommandLineArg path; SLANG_RETURN_ON_FAIL(m_reader.expectArg(path)); - m_spirvCoreGrammarJSONPath = path.value; + m_session->setSPIRVCoreGrammar(path.value.getBuffer()); } break; @@ -2502,16 +2285,6 @@ SlangResult OptionsParser::_parse( } } - // If there is state set on HLSL to Vulkan layout settings, set on the end to end request - // such can be added when target requests are setup - if (!m_hlslToVulkanLayoutOptions->isReset()) - { - m_requestImpl->setHLSLToVulkanLayoutOptions(m_hlslToVulkanLayoutOptions); - } - - // No longer need to track - m_hlslToVulkanLayoutOptions.setNull(); - if (m_compileStdLib) { SLANG_RETURN_ON_FAIL(m_session->compileStdLib(m_compileStdLibFlags)); @@ -2526,10 +2299,6 @@ SlangResult OptionsParser::_parse( return SLANG_OK; } - m_compileRequest->setCompileFlags(m_flags); - - m_compileRequest->setAllowGLSLInput(m_allowGLSLInput); - // As a compatability feature, if the user didn't list any explicit entry // point names, *and* they are compiling a single translation unit, *and* they // have either specified a stage, or we can assume one from the naming @@ -2785,14 +2554,14 @@ SlangResult OptionsParser::_parse( // then we can try to infer a target from the profile. // if (m_rawTargets.getCount() == 0 - && m_defaultTarget.profileVersion != ProfileVersion::Unknown + && m_defaultTarget.optionSet.getProfileVersion() != ProfileVersion::Unknown && !m_defaultTarget.conflictingProfilesSet) { // Let's see if the chosen profile allows us to infer // the code gen target format that the user probably meant. // CodeGenTarget inferredFormat = CodeGenTarget::Unknown; - auto profileVersion = m_defaultTarget.profileVersion; + auto profileVersion = m_defaultTarget.optionSet.getProfileVersion(); switch (Profile(profileVersion).getFamily()) { default: @@ -2837,22 +2606,24 @@ SlangResult OptionsParser::_parse( // Similar to the case for entry points, if there is a single target, // then we allow some of its options to come from the "default" // target state. + auto defaultTargetFloatingPointMode = m_defaultTarget.optionSet.getEnumOption<FloatingPointMode>(CompilerOptionName::FloatingPointMode); + if (m_rawTargets.getCount() == 1) { - if (m_defaultTarget.profileVersion != ProfileVersion::Unknown) + if (m_defaultTarget.optionSet.getProfileVersion() != ProfileVersion::Unknown) { - setProfileVersion(getCurrentTarget(), m_defaultTarget.profileVersion); + setProfileVersion(getCurrentTarget(), m_defaultTarget.optionSet.getProfileVersion()); } - for (auto atom : m_defaultTarget.capabilityAtoms) + for (auto atom : m_defaultTarget.optionSet.getArray(CompilerOptionName::Capability)) { - addCapabilityAtom(getCurrentTarget(), atom); + addCapabilityAtom(getCurrentTarget(), (CapabilityName)atom.intValue); } getCurrentTarget()->targetFlags |= m_defaultTarget.targetFlags; - if (m_defaultTarget.floatingPointMode != FloatingPointMode::Default) + if (defaultTargetFloatingPointMode != FloatingPointMode::Default) { - setFloatingPointMode(getCurrentTarget(), m_defaultTarget.floatingPointMode); + setFloatingPointMode(getCurrentTarget(), defaultTargetFloatingPointMode); } } else @@ -2861,7 +2632,7 @@ SlangResult OptionsParser::_parse( // specified, but there is != 1 taget, then that state doesn't // apply to anythign and we should give the user an error. // - if (m_defaultTarget.profileVersion != ProfileVersion::Unknown) + if (m_defaultTarget.optionSet.getProfileVersion() != ProfileVersion::Unknown) { if (m_rawTargets.getCount() == 0) { @@ -2889,7 +2660,7 @@ SlangResult OptionsParser::_parse( } } - if (m_defaultTarget.floatingPointMode != FloatingPointMode::Default) + if (defaultTargetFloatingPointMode != FloatingPointMode::Default) { if (m_rawTargets.getCount() == 0) { @@ -2910,7 +2681,7 @@ SlangResult OptionsParser::_parse( } else if (rawTarget.redundantProfileSet) { - m_sink->diagnose(SourceLoc(), Diagnostics::sameProfileSpecifiedMoreThanOnce, rawTarget.profileVersion, rawTarget.format); + m_sink->diagnose(SourceLoc(), Diagnostics::sameProfileSpecifiedMoreThanOnce, rawTarget.optionSet.getProfileVersion(), rawTarget.format); } } @@ -2925,13 +2696,13 @@ SlangResult OptionsParser::_parse( int targetID = m_compileRequest->addCodeGenTarget(SlangCompileTarget(rawTarget.format)); rawTarget.targetID = targetID; - if (rawTarget.profileVersion != ProfileVersion::Unknown) + if (rawTarget.optionSet.getProfileVersion() != ProfileVersion::Unknown) { - m_compileRequest->setTargetProfile(targetID, SlangProfileID(Profile(rawTarget.profileVersion).raw)); + m_compileRequest->setTargetProfile(targetID, SlangProfileID(Profile(rawTarget.optionSet.getProfileVersion()).raw)); } - for (auto atom : rawTarget.capabilityAtoms) + for (auto atom : rawTarget.optionSet.getArray(CompilerOptionName::Capability)) { - m_requestImpl->addTargetCapability(targetID, SlangCapabilityID(atom)); + m_requestImpl->addTargetCapability(targetID, SlangCapabilityID(atom.intValue)); } if (rawTarget.targetFlags) @@ -2939,27 +2710,18 @@ SlangResult OptionsParser::_parse( m_compileRequest->setTargetFlags(targetID, rawTarget.targetFlags); } - if (rawTarget.floatingPointMode != FloatingPointMode::Default) + auto floatingPointMode = rawTarget.optionSet.getEnumOption<FloatingPointMode>(CompilerOptionName::FloatingPointMode); + if (floatingPointMode != FloatingPointMode::Default) { - m_compileRequest->setTargetFloatingPointMode(targetID, SlangFloatingPointMode(rawTarget.floatingPointMode)); + m_compileRequest->setTargetFloatingPointMode(targetID, SlangFloatingPointMode(floatingPointMode)); } - if (rawTarget.forceGLSLScalarLayout) + if (rawTarget.optionSet.shouldUseScalarLayout()) { m_compileRequest->setTargetForceGLSLScalarBufferLayout(targetID, true); } } - if (m_defaultMatrixLayoutMode != SLANG_MATRIX_LAYOUT_MODE_UNKNOWN) - { - m_compileRequest->setMatrixLayoutMode(m_defaultMatrixLayoutMode); - } - - if(m_spirvCoreGrammarJSONPath.getLength()) - { - m_session->setSPIRVCoreGrammar(m_spirvCoreGrammarJSONPath.getBuffer()); - } - // Next we need to sort out the output files specified with `-o`, and // figure out which entry point and/or target they apply to. // @@ -3104,7 +2866,7 @@ SlangResult OptionsParser::_parse( } else { - target->addTargetFlags(SLANG_TARGET_FLAG_GENERATE_WHOLE_PROGRAM); + target->getOptionSet().addTargetFlags(SLANG_TARGET_FLAG_GENERATE_WHOLE_PROGRAM); targetInfo->wholeTargetOutputPath = rawOutput.path; } } @@ -3127,6 +2889,12 @@ SlangResult OptionsParser::_parse( } } + // Copy all settings from linkage to targets. + for (auto target : linkage->targets) + target->getOptionSet().inheritFrom(linkage->m_optionSet); + + applySettingsToDiagnosticSink(m_requestImpl->getSink(), m_sink, linkage->m_optionSet); + return (m_sink->getErrorCount() == 0) ? SLANG_OK : SLANG_FAIL; } @@ -3145,14 +2913,11 @@ SlangResult OptionsParser::parse( m_session = session; m_frontEndReq = m_requestImpl->getFrontEndReq(); - m_hlslToVulkanLayoutOptions = new HLSLToVulkanLayoutOptions; - m_cmdOptions = &session->m_commandOptions; + m_cmdLineContext = m_requestImpl->getLinkage()->m_cmdLineContext.get(); DiagnosticSink* requestSink = m_requestImpl->getSink(); - m_cmdLineContext = m_requestImpl->getLinkage()->m_downstreamArgs.getContext(); - // Why create a new DiagnosticSink? // We *don't* want the lexer that comes as default (it's for Slang source!) // We may want to set flags that are different diff --git a/source/slang/slang-parameter-binding.cpp b/source/slang/slang-parameter-binding.cpp index 4ddafa425..c2f8b2d4d 100644 --- a/source/slang/slang-parameter-binding.cpp +++ b/source/slang/slang-parameter-binding.cpp @@ -376,11 +376,12 @@ struct SharedParameterBindingContext SharedParameterBindingContext( LayoutRulesFamilyImpl* defaultLayoutRules, ProgramLayout* programLayout, - TargetRequest* targetReq, + TargetProgram* inTargetProgram, DiagnosticSink* sink) : defaultLayoutRules(defaultLayoutRules) , programLayout(programLayout) - , targetRequest(targetReq) + , targetRequest(inTargetProgram->getTargetReq()) + , targetProgram(inTargetProgram) , m_sink(sink) { } @@ -388,7 +389,7 @@ struct SharedParameterBindingContext DiagnosticSink* m_sink = nullptr; // The program that we are laying out -// Program* program = nullptr; + // Program* program = nullptr; // The target request that is triggering layout // @@ -397,6 +398,8 @@ struct SharedParameterBindingContext // can influence layout decisions. TargetRequest* targetRequest = nullptr; + TargetProgram* targetProgram = nullptr; + LayoutRulesFamilyImpl* defaultLayoutRules; // All shader parameters we've discovered so far, and started to lay out... @@ -422,6 +425,7 @@ struct SharedParameterBindingContext TargetRequest* getTargetRequest() { return targetRequest; } DiagnosticSink* getSink() { return m_sink; } Linkage* getLinkage() { return targetRequest->getLinkage(); } + TargetProgram* getTargetProgram() { return targetProgram; } }; static DiagnosticSink* getSink(SharedParameterBindingContext* shared) @@ -447,6 +451,7 @@ struct ParameterBindingContext EntryPointLayout* entryPointLayout = nullptr; TargetRequest* getTargetRequest() { return shared->getTargetRequest(); } + TargetProgram* getTargetProgram() { return shared->getTargetProgram(); } LayoutRulesFamilyImpl* getRulesFamily() { return layoutContext.getRulesFamily(); } ASTBuilder* getASTBuilder() { return shared->getLinkage()->getASTBuilder(); } @@ -714,7 +719,7 @@ RefPtr<TypeLayout> getTypeLayoutForGlobalShaderParameter( // shader parameter. return createTypeLayoutWith( layoutContext, - rules->getConstantBufferRules(context->getTargetRequest()), + rules->getConstantBufferRules(context->getTargetRequest()->getOptionSet()), type); } @@ -1107,7 +1112,7 @@ static void addExplicitParameterBindings_GLSL( // See if we can infer vulkan binding from HLSL if we have such options set, we know // we can't map - auto hlslToVulkanLayoutOptions = context->getTargetRequest()->getHLSLToVulkanLayoutOptions(); + auto hlslToVulkanLayoutOptions = context->getTargetProgram()->getHLSLToVulkanLayoutOptions(); // If we have the options, but cannot infer bindings, we don't need to go further if (hlslToVulkanLayoutOptions == nullptr || !hlslToVulkanLayoutOptions->canInferBindings()) @@ -1559,7 +1564,7 @@ static RefPtr<TypeLayout> processSimpleEntryPointParameter( // if( isD3DTarget(context->getTargetRequest()) ) { - auto version = context->getTargetRequest()->getTargetProfile().getVersion(); + auto version = context->getTargetProgram()->getOptionSet().getProfileVersion(); if( version <= ProfileVersion::DX_5_0 ) { // We will address the conflict here by claiming the corresponding @@ -2238,7 +2243,7 @@ static RefPtr<TypeLayout> computeEntryPointParameterTypeLayout( // return createTypeLayoutWith( context->layoutContext, - context->getRulesFamily()->getConstantBufferRules(context->getTargetRequest()), + context->getRulesFamily()->getConstantBufferRules(context->getTargetRequest()->getOptionSet()), paramType); } else @@ -2592,7 +2597,7 @@ static ParameterBindingAndKindInfo _allocateConstantBufferBinding( auto usedRangeSet = _getOrCreateUsedRangeSetForSpace(context, space); auto layoutInfo = context->getRulesFamily() - ->getConstantBufferRules(context->getTargetRequest()) + ->getConstantBufferRules(context->getTargetRequest()->getOptionSet()) ->GetObjectLayout(ShaderParameterKind::ConstantBuffer, context->layoutContext.objectLayoutOptions); ParameterBindingAndKindInfo info; @@ -2612,7 +2617,7 @@ static ParameterBindingAndKindInfo _assignConstantBufferBinding( auto usedRangeSet = _getOrCreateUsedRangeSetForSpace(context, space); auto layoutInfo = context->getRulesFamily() - ->getConstantBufferRules(context->getTargetRequest()) + ->getConstantBufferRules(context->getTargetRequest()->getOptionSet()) ->GetObjectLayout(ShaderParameterKind::ConstantBuffer, context->layoutContext.objectLayoutOptions); const Index count = Index(layoutInfo.size.getFiniteValue()); @@ -3555,7 +3560,7 @@ static bool _calcNeedsDefaultSpace(SharedParameterBindingContext& sharedContext) { // If it's uniform, but we have globals binding defined, we don't need a default space for it // as it will go in the global binding specified - if (auto hlslToVulkanOptions = sharedContext.getTargetRequest()->getHLSLToVulkanLayoutOptions()) + if (auto hlslToVulkanOptions = sharedContext.getTargetProgram()->getHLSLToVulkanLayoutOptions()) { if (hlslToVulkanOptions->hasGlobalsBinding()) { @@ -3628,7 +3633,7 @@ static void _appendRange(Index start, LayoutSize size, StringBuilder& ioBuf) static void _maybeApplyHLSLToVulkanShifts( ParameterBindingContext* paramContext, ParameterBindingAndKindInfo& globalConstantBinding, - TargetRequest* targetReq, + TargetProgram* targetProgram, DiagnosticSink* sink) { SLANG_UNUSED(sink); @@ -3636,7 +3641,7 @@ static void _maybeApplyHLSLToVulkanShifts( SharedParameterBindingContext& sharedContext = *paramContext->shared; // We may need to finally do any shifting if we have HLSLToVulkanLayoutOptions - auto vulkanOptions = targetReq->getHLSLToVulkanLayoutOptions(); + auto vulkanOptions = targetProgram->getHLSLToVulkanLayoutOptions(); if (!vulkanOptions) { return; @@ -3773,7 +3778,7 @@ RefPtr<ProgramLayout> generateParameterBindings( SharedParameterBindingContext sharedContext( layoutContext.getRulesFamily(), programLayout, - targetReq, + targetProgram, sink); // Create a sub-context to collect parameters that get @@ -3917,7 +3922,7 @@ RefPtr<ProgramLayout> generateParameterBindings( // If we have a space/binding assigned for use for globals in Vulkan, // we can't use *that* as the default space, so we allocate if - if (auto vulkanOptions = targetReq->getHLSLToVulkanLayoutOptions()) + if (auto vulkanOptions = targetProgram->getHLSLToVulkanLayoutOptions()) { const auto& globalBinding = vulkanOptions->getGlobalsBinding(); @@ -4041,7 +4046,7 @@ RefPtr<ProgramLayout> generateParameterBindings( _completeBindings(&context, program); // We may need to finally do any shifting if we have HLSLToVulkanLayoutOptions - _maybeApplyHLSLToVulkanShifts(&context, globalConstantBufferBinding, targetReq, sink); + _maybeApplyHLSLToVulkanShifts(&context, globalConstantBufferBinding, targetProgram, sink); // Next we need to create a type layout to reflect the information // we have collected, and we will use the `ScopeLayoutBuilder` diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index 477b43726..e0ffba53c 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -7413,9 +7413,9 @@ namespace Slang ContainerDecl* parentDecl) { ParserOptions options = {}; - options.enableEffectAnnotations = translationUnit->compileRequest->getLinkage()->getEnableEffectAnnotations(); + options.enableEffectAnnotations = translationUnit->compileRequest->optionSet.getBoolOption(CompilerOptionName::EnableEffectAnnotations); options.allowGLSLInput = - translationUnit->compileRequest->getLinkage()->getAllowGLSLInput() || + translationUnit->compileRequest->optionSet.getBoolOption(CompilerOptionName::AllowGLSL) || sourceLanguage == SourceLanguage::GLSL; options.isInLanguageServer = translationUnit->compileRequest->getLinkage()->isInLanguageServer(); diff --git a/source/slang/slang-reflection-api.cpp b/source/slang/slang-reflection-api.cpp index 28b22b833..b9eeccd30 100644 --- a/source/slang/slang-reflection-api.cpp +++ b/source/slang/slang-reflection-api.cpp @@ -2961,6 +2961,12 @@ SLANG_API unsigned int spReflection_GetTypeParameterCount(SlangReflection * refl return (unsigned int) program->specializationParams.getCount(); } +SLANG_API slang::ISession* spReflection_GetSession(SlangReflection* reflection) +{ + auto program = convert(reflection); + return program->getTargetProgram()->getTargetReq()->getLinkage(); +} + SLANG_API SlangReflectionTypeParameter* spReflection_GetTypeParameterByIndex(SlangReflection * reflection, unsigned int index) { auto program = convert(reflection); diff --git a/source/slang/slang-repro.cpp b/source/slang/slang-repro.cpp index a19470ebf..32f8d3289 100644 --- a/source/slang/slang-repro.cpp +++ b/source/slang/slang-repro.cpp @@ -363,19 +363,17 @@ static String _scrubName(const String& in) { RequestState* dst = base[requestState]; - dst->compileFlags = request->getFrontEndReq()->compileFlags; - dst->shouldDumpIntermediates = request->shouldDumpIntermediates; - - dst->debugInfoLevel = linkage->debugInfoLevel; - dst->optimizationLevel = linkage->optimizationLevel; + dst->compileFlags = 0; + dst->shouldDumpIntermediates = linkage->m_optionSet.getBoolOption(CompilerOptionName::DumpIntermediates); + dst->debugInfoLevel = linkage->m_optionSet.getEnumOption<DebugInfoLevel>(CompilerOptionName::DebugInformation); + dst->optimizationLevel = linkage->m_optionSet.getEnumOption<OptimizationLevel>(CompilerOptionName::Optimization); dst->containerFormat = request->m_containerFormat; dst->passThroughMode = request->m_passThrough; + dst->useUnknownImageFormatAsDefault = linkage->m_optionSet.getBoolOption(CompilerOptionName::DefaultImageFormatUnknown);; + dst->obfuscateCode = linkage->m_optionSet.getBoolOption(CompilerOptionName::Obfuscate); - dst->useUnknownImageFormatAsDefault = request->useUnknownImageFormatAsDefault; - dst->obfuscateCode = linkage->m_obfuscateCode; - - dst->defaultMatrixLayoutMode = SlangMatrixLayoutMode(linkage->defaultMatrixLayoutMode); + dst->defaultMatrixLayoutMode = (SlangMatrixLayoutMode)linkage->m_optionSet.getMatrixLayoutMode(); } // Entry points @@ -434,9 +432,9 @@ static String _scrubName(const String& in) { auto& dst = base[dstTargets[i]]; dst.target = srcTargetRequest->getTarget(); - dst.profile = srcTargetRequest->getTargetProfile(); - dst.targetFlags = srcTargetRequest->getTargetFlags(); - dst.floatingPointMode = srcTargetRequest->getFloatingPointMode(); + dst.profile = srcTargetRequest->getOptionSet().getProfile(); + dst.targetFlags = srcTargetRequest->getOptionSet().getTargetFlags(); + dst.floatingPointMode = srcTargetRequest->getOptionSet().getEnumOption<FloatingPointMode>(CompilerOptionName::FloatingPointMode); } // Copy the entry point/target output names @@ -475,21 +473,26 @@ static String _scrubName(const String& in) // Add the search paths { - const auto& srcPaths = linkage->searchDirectories.searchDirectories; - Offset32Array<Offset32Ptr<OffsetString> > dstPaths = inOutContainer.newArray<Offset32Ptr<OffsetString> >(srcPaths.getCount()); + auto srcPaths = linkage->getSearchDirectories(); + Offset32Array<Offset32Ptr<OffsetString> > dstPaths = inOutContainer.newArray<Offset32Ptr<OffsetString> >(srcPaths.searchDirectories.getCount()); // We don't handle parents here - SLANG_ASSERT(linkage->searchDirectories.parent == nullptr); - for (Index i = 0; i < srcPaths.getCount(); ++i) + SLANG_ASSERT(srcPaths.parent == nullptr); + for (Index i = 0; i < srcPaths.searchDirectories.getCount(); ++i) { - const auto srcPath = context.fromString(srcPaths[i].path); + const auto srcPath = context.fromString(srcPaths.searchDirectories[i].path); base[dstPaths[i]] = srcPath; } base[requestState]->searchPaths = dstPaths; } // Add preprocessor definitions - base[requestState]->preprocessorDefinitions = context.calcDefines(linkage->preprocessorDefinitions); + Dictionary<String, String> preprocessorDefines; + for (auto def : linkage->m_optionSet.getArray(CompilerOptionName::MacroDefine)) + { + preprocessorDefines[def.stringValue] = def.stringValue2; + } + base[requestState]->preprocessorDefinitions = context.calcDefines(preprocessorDefines); { const auto& srcTranslationUnits = request->getFrontEndReq()->translationUnits; @@ -915,12 +918,26 @@ struct LoadContext externalRequest->setOutputContainerFormat(SlangContainerFormat(requestState->containerFormat)); externalRequest->setPassThrough(SlangPassThrough(request->m_passThrough)); - request->useUnknownImageFormatAsDefault = requestState->useUnknownImageFormatAsDefault; - linkage->m_obfuscateCode = requestState->obfuscateCode; + linkage->m_optionSet.set(CompilerOptionName::DefaultImageFormatUnknown, requestState->useUnknownImageFormatAsDefault); + linkage->m_optionSet.set(CompilerOptionName::Obfuscate, requestState->obfuscateCode); linkage->setMatrixLayoutMode(requestState->defaultMatrixLayoutMode); } + { + const auto& srcPaths = requestState->searchPaths; + for (Index i = 0; i < srcPaths.getCount(); ++i) + { + linkage->m_optionSet.add(CompilerOptionName::Include, base.asRaw(base.asRaw(srcPaths[i]))->getSlice()); + } + } + Dictionary<String, String> preprocessorDefines; + context.loadDefines(requestState->preprocessorDefinitions, preprocessorDefines); + for (auto def : preprocessorDefines) + { + linkage->m_optionSet.addPreprocessorDefine(def.first, def.second); + } + // Add the target requests { for (Index i = 0; i < requestState->targetRequests.getCount(); ++i) @@ -932,9 +949,9 @@ struct LoadContext auto dstTarget = linkage->targets[index]; SLANG_ASSERT(dstTarget->getTarget() == src.target); - dstTarget->setTargetProfile(src.profile); - dstTarget->addTargetFlags(src.targetFlags); - dstTarget->setFloatingPointMode(src.floatingPointMode); + dstTarget->getOptionSet().setProfile(src.profile); + dstTarget->getOptionSet().addTargetFlags(src.targetFlags); + dstTarget->getOptionSet().set(CompilerOptionName::FloatingPointMode, src.floatingPointMode); // If there is output state (like output filenames) add here if (src.outputStates.getCount()) @@ -960,17 +977,6 @@ struct LoadContext } } - { - const auto& srcPaths = requestState->searchPaths; - auto& dstPaths = linkage->searchDirectories.searchDirectories; - dstPaths.setCount(srcPaths.getCount()); - for (Index i = 0; i < srcPaths.getCount(); ++i) - { - dstPaths[i].path = base.asRaw(base.asRaw(srcPaths[i]))->getSlice(); - } - } - - context.loadDefines(requestState->preprocessorDefinitions, linkage->preprocessorDefinitions); { auto frontEndReq = request->getFrontEndReq(); diff --git a/source/slang/slang-serialize-container.cpp b/source/slang/slang-serialize-container.cpp index 6a75064ab..39b67614d 100644 --- a/source/slang/slang-serialize-container.cpp +++ b/source/slang/slang-serialize-container.cpp @@ -123,9 +123,9 @@ namespace Slang { auto& dstTarget = targetComponent.target; - dstTarget.floatingPointMode = target->getFloatingPointMode(); - dstTarget.profile = target->getTargetProfile(); - dstTarget.flags = target->getTargetFlags(); + dstTarget.floatingPointMode = target->getOptionSet().getFloatingPointMode(); + dstTarget.profile = target->getOptionSet().getProfile(); + dstTarget.flags = target->getOptionSet().getTargetFlags(); dstTarget.codeGenTarget = target->getTarget(); out.targetComponents.add(targetComponent); diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp index ccd34a966..6b1e2e115 100644 --- a/source/slang/slang-type-layout.cpp +++ b/source/slang/slang-type-layout.cpp @@ -889,14 +889,14 @@ CUDARayTracingLayoutRulesImpl kCUDAHitAttributesParameterLayoutRulesImpl(LayoutR struct GLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl { virtual LayoutRulesImpl* getAnyValueRules() override; - virtual LayoutRulesImpl* getConstantBufferRules(TargetRequest* request) override; + virtual LayoutRulesImpl* getConstantBufferRules(CompilerOptionSet& compilerOptions) override; virtual LayoutRulesImpl* getPushConstantBufferRules() override; virtual LayoutRulesImpl* getTextureBufferRules() override; virtual LayoutRulesImpl* getVaryingInputRules() override; virtual LayoutRulesImpl* getVaryingOutputRules() override; virtual LayoutRulesImpl* getSpecializationConstantRules() override; - virtual LayoutRulesImpl* getShaderStorageBufferRules(TargetRequest* request) override; - virtual LayoutRulesImpl* getParameterBlockRules(TargetRequest* request) override; + virtual LayoutRulesImpl* getShaderStorageBufferRules(CompilerOptionSet& compilerOptions) override; + virtual LayoutRulesImpl* getParameterBlockRules(CompilerOptionSet& compilerOptions) override; LayoutRulesImpl* getRayPayloadParameterRules() override; LayoutRulesImpl* getCallablePayloadParameterRules() override; @@ -904,20 +904,20 @@ struct GLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl LayoutRulesImpl* getShaderRecordConstantBufferRules() override; - LayoutRulesImpl* getStructuredBufferRules(TargetRequest* request) override; + LayoutRulesImpl* getStructuredBufferRules(CompilerOptionSet& compilerOptions) override; }; struct HLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl { virtual LayoutRulesImpl* getAnyValueRules() override; - virtual LayoutRulesImpl* getConstantBufferRules(TargetRequest* request) override; + virtual LayoutRulesImpl* getConstantBufferRules(CompilerOptionSet& compilerOptions) override; virtual LayoutRulesImpl* getPushConstantBufferRules() override; virtual LayoutRulesImpl* getTextureBufferRules() override; virtual LayoutRulesImpl* getVaryingInputRules() override; virtual LayoutRulesImpl* getVaryingOutputRules() override; virtual LayoutRulesImpl* getSpecializationConstantRules() override; - virtual LayoutRulesImpl* getShaderStorageBufferRules(TargetRequest* request) override; - virtual LayoutRulesImpl* getParameterBlockRules(TargetRequest* request) override; + virtual LayoutRulesImpl* getShaderStorageBufferRules(CompilerOptionSet& compilerOptions) override; + virtual LayoutRulesImpl* getParameterBlockRules(CompilerOptionSet& compilerOptions) override; LayoutRulesImpl* getRayPayloadParameterRules() override; LayoutRulesImpl* getCallablePayloadParameterRules() override; @@ -925,47 +925,47 @@ struct HLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl LayoutRulesImpl* getShaderRecordConstantBufferRules() override; - LayoutRulesImpl* getStructuredBufferRules(TargetRequest* request) override; + LayoutRulesImpl* getStructuredBufferRules(CompilerOptionSet& compilerOptions) override; }; struct CPULayoutRulesFamilyImpl : LayoutRulesFamilyImpl { virtual LayoutRulesImpl* getAnyValueRules() override; - virtual LayoutRulesImpl* getConstantBufferRules(TargetRequest* request) override; + virtual LayoutRulesImpl* getConstantBufferRules(CompilerOptionSet& compilerOptions) override; virtual LayoutRulesImpl* getPushConstantBufferRules() override; virtual LayoutRulesImpl* getTextureBufferRules() override; virtual LayoutRulesImpl* getVaryingInputRules() override; virtual LayoutRulesImpl* getVaryingOutputRules() override; virtual LayoutRulesImpl* getSpecializationConstantRules() override; - virtual LayoutRulesImpl* getShaderStorageBufferRules(TargetRequest* request) override; - virtual LayoutRulesImpl* getParameterBlockRules(TargetRequest* request) override; + virtual LayoutRulesImpl* getShaderStorageBufferRules(CompilerOptionSet& compilerOptions) override; + virtual LayoutRulesImpl* getParameterBlockRules(CompilerOptionSet& compilerOptions) override; LayoutRulesImpl* getRayPayloadParameterRules() override; LayoutRulesImpl* getCallablePayloadParameterRules() override; LayoutRulesImpl* getHitAttributesParameterRules() override; LayoutRulesImpl* getShaderRecordConstantBufferRules() override; - LayoutRulesImpl* getStructuredBufferRules(TargetRequest* request) override; + LayoutRulesImpl* getStructuredBufferRules(CompilerOptionSet& compilerOptions) override; }; struct CUDALayoutRulesFamilyImpl : LayoutRulesFamilyImpl { virtual LayoutRulesImpl* getAnyValueRules() override; - virtual LayoutRulesImpl* getConstantBufferRules(TargetRequest* request) override; + virtual LayoutRulesImpl* getConstantBufferRules(CompilerOptionSet& compilerOptions) override; virtual LayoutRulesImpl* getPushConstantBufferRules() override; virtual LayoutRulesImpl* getTextureBufferRules() override; virtual LayoutRulesImpl* getVaryingInputRules() override; virtual LayoutRulesImpl* getVaryingOutputRules() override; virtual LayoutRulesImpl* getSpecializationConstantRules() override; - virtual LayoutRulesImpl* getShaderStorageBufferRules(TargetRequest* request) override; - virtual LayoutRulesImpl* getParameterBlockRules(TargetRequest* request) override; + virtual LayoutRulesImpl* getShaderStorageBufferRules(CompilerOptionSet& compilerOptions) override; + virtual LayoutRulesImpl* getParameterBlockRules(CompilerOptionSet& compilerOptions) override; LayoutRulesImpl* getRayPayloadParameterRules() override; LayoutRulesImpl* getCallablePayloadParameterRules() override; LayoutRulesImpl* getHitAttributesParameterRules() override; LayoutRulesImpl* getShaderRecordConstantBufferRules() override; - LayoutRulesImpl* getStructuredBufferRules(TargetRequest* request) override; + LayoutRulesImpl* getStructuredBufferRules(CompilerOptionSet& compilerOptions) override; }; GLSLLayoutRulesFamilyImpl kGLSLLayoutRulesFamilyImpl; @@ -1229,16 +1229,16 @@ LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getAnyValueRules() return &kGLSLAnyValueLayoutRulesImpl_; } -LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getConstantBufferRules(TargetRequest* targetReq) +LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getConstantBufferRules(CompilerOptionSet& compilerOptions) { - if (targetReq->getForceGLSLScalarBufferLayout()) + if (compilerOptions.shouldUseScalarLayout()) return &kScalarLayoutRulesImpl_; return &kStd140LayoutRulesImpl_; } -LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getParameterBlockRules(TargetRequest* targetReq) +LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getParameterBlockRules(CompilerOptionSet& compilerOptions) { - if (targetReq->getForceGLSLScalarBufferLayout()) + if (compilerOptions.shouldUseScalarLayout()) return &kScalarLayoutRulesImpl_; return &kStd140LayoutRulesImpl_; } @@ -1273,9 +1273,9 @@ LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getSpecializationConstantRules() return &kGLSLSpecializationConstantLayoutRulesImpl_; } -LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getShaderStorageBufferRules(TargetRequest* request) +LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getShaderStorageBufferRules(CompilerOptionSet& compilerOptions) { - if (request->getForceGLSLScalarBufferLayout()) + if (compilerOptions.shouldUseScalarLayout()) return &kScalarLayoutRulesImpl_; return &kStd430LayoutRulesImpl_; } @@ -1295,9 +1295,9 @@ LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getHitAttributesParameterRules() return &kGLSLHitAttributesParameterLayoutRulesImpl_; } -LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getStructuredBufferRules(TargetRequest* targetReq) +LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getStructuredBufferRules(CompilerOptionSet& options) { - if (targetReq->getForceGLSLScalarBufferLayout()) + if (options.shouldUseScalarLayout()) return &kScalarLayoutRulesImpl_; return &kGLSLStructuredBufferLayoutRulesImpl_; } @@ -1309,12 +1309,12 @@ LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getAnyValueRules() return &kHLSLAnyValueLayoutRulesImpl_; } -LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getConstantBufferRules(TargetRequest*) +LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getConstantBufferRules(CompilerOptionSet&) { return &kHLSLConstantBufferLayoutRulesImpl_; } -LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getParameterBlockRules(TargetRequest*) +LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getParameterBlockRules(CompilerOptionSet&) { // TODO: actually pick something appropriate... return &kHLSLConstantBufferLayoutRulesImpl_; @@ -1331,7 +1331,7 @@ LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getShaderRecordConstantBufferRules() return &kHLSLConstantBufferLayoutRulesImpl_; } -LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getStructuredBufferRules(TargetRequest*) +LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getStructuredBufferRules(CompilerOptionSet&) { return &kHLSLStructuredBufferLayoutRulesImpl_; } @@ -1356,7 +1356,7 @@ LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getSpecializationConstantRules() return nullptr; } -LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getShaderStorageBufferRules(TargetRequest*) +LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getShaderStorageBufferRules(CompilerOptionSet&) { return nullptr; } @@ -1383,7 +1383,7 @@ LayoutRulesImpl* CPULayoutRulesFamilyImpl::getAnyValueRules() return &kCPUAnyValueLayoutRulesImpl_; } -LayoutRulesImpl* CPULayoutRulesFamilyImpl::getConstantBufferRules(TargetRequest*) +LayoutRulesImpl* CPULayoutRulesFamilyImpl::getConstantBufferRules(CompilerOptionSet&) { return &kCPULayoutRulesImpl_; } @@ -1410,11 +1410,11 @@ LayoutRulesImpl* CPULayoutRulesFamilyImpl::getSpecializationConstantRules() { return nullptr; } -LayoutRulesImpl* CPULayoutRulesFamilyImpl::getShaderStorageBufferRules(TargetRequest*) +LayoutRulesImpl* CPULayoutRulesFamilyImpl::getShaderStorageBufferRules(CompilerOptionSet&) { return nullptr; } -LayoutRulesImpl* CPULayoutRulesFamilyImpl::getParameterBlockRules(TargetRequest*) +LayoutRulesImpl* CPULayoutRulesFamilyImpl::getParameterBlockRules(CompilerOptionSet&) { // Not clear - just use similar to CPU return &kCPULayoutRulesImpl_; @@ -1437,7 +1437,7 @@ LayoutRulesImpl* CPULayoutRulesFamilyImpl::getShaderRecordConstantBufferRules() return &kCPULayoutRulesImpl_; } -LayoutRulesImpl* CPULayoutRulesFamilyImpl::getStructuredBufferRules(TargetRequest*) +LayoutRulesImpl* CPULayoutRulesFamilyImpl::getStructuredBufferRules(CompilerOptionSet&) { return &kCPULayoutRulesImpl_; } @@ -1449,7 +1449,7 @@ LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getAnyValueRules() return &kCUDAAnyValueLayoutRulesImpl_; } -LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getConstantBufferRules(TargetRequest*) +LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getConstantBufferRules(CompilerOptionSet&) { return &kCUDALayoutRulesImpl_; } @@ -1476,11 +1476,11 @@ LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getSpecializationConstantRules() { return nullptr; } -LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getShaderStorageBufferRules(TargetRequest*) +LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getShaderStorageBufferRules(CompilerOptionSet&) { return nullptr; } -LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getParameterBlockRules(TargetRequest*) +LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getParameterBlockRules(CompilerOptionSet&) { // Not clear - just use similar to CPU return &kCUDALayoutRulesImpl_; @@ -1504,7 +1504,7 @@ LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getShaderRecordConstantBufferRules() return &kCUDALayoutRulesImpl_; } -LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getStructuredBufferRules(TargetRequest*) +LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getStructuredBufferRules(CompilerOptionSet&) { return &kCUDALayoutRulesImpl_; } @@ -1566,9 +1566,9 @@ TypeLayoutContext getInitialLayoutContextForTarget(TargetRequest* targetReq, Pro TypeLayoutContext context; context.astBuilder = astBuilder; context.targetReq = targetReq; - context.programLayout = programLayout; + context.programLayout = programLayout; context.rules = nullptr; - context.matrixLayoutMode = targetReq->getDefaultMatrixLayoutMode(); + context.matrixLayoutMode = targetReq->getOptionSet().getMatrixLayoutMode(); if (auto hlslToVulkanLayoutOptions = targetReq->getHLSLToVulkanLayoutOptions()) { @@ -1577,7 +1577,7 @@ TypeLayoutContext getInitialLayoutContextForTarget(TargetRequest* targetReq, Pro if( rulesFamily ) { - context.rules = rulesFamily->getConstantBufferRules(targetReq); + context.rules = rulesFamily->getConstantBufferRules(targetReq->getOptionSet()); } return context; @@ -1764,15 +1764,15 @@ bool isCUDATarget(TargetRequest* targetReq) } } -SourceLanguage getIntermediateSourceLanguageForTarget(TargetRequest* req) +SourceLanguage getIntermediateSourceLanguageForTarget(TargetProgram* targetProgram) { // If we are emitting directly, there is no intermediate source language - if (req->shouldEmitSPIRVDirectly()) + if (targetProgram->getOptionSet().shouldEmitSPIRVDirectly()) { return SourceLanguage::Unknown; } - switch (req->getTarget()) + switch (targetProgram->getTargetReq()->getTarget()) { case CodeGenTarget::GLSL: case CodeGenTarget::GLSL_Vulkan: @@ -1843,7 +1843,7 @@ static bool isSM5OrEarlier(TargetRequest* targetReq) if(!isD3DTarget(targetReq)) return false; - auto profile = targetReq->getTargetProfile(); + auto profile = targetReq->getOptionSet().getProfile(); if(profile.getFamily() == ProfileFamily::DX) { @@ -1859,7 +1859,7 @@ static bool isSM5_1OrLater(TargetRequest* targetReq) if(!isD3DTarget(targetReq)) return false; - auto profile = targetReq->getTargetProfile(); + auto profile = targetReq->getOptionSet().getProfile(); if(profile.getFamily() == ProfileFamily::DX) { @@ -2735,7 +2735,7 @@ RefPtr<TypeLayout> createConstantBufferTypeLayoutIfNeeded( return _createParameterGroupTypeLayout( context - .with(context.targetReq->getDefaultMatrixLayoutMode()), + .with(context.targetReq->getOptionSet().getMatrixLayoutMode()), nullptr, elementTypeLayout); } @@ -2767,11 +2767,11 @@ static RefPtr<TypeLayout> _createParameterGroupTypeLayout( LayoutRulesImpl* getParameterBufferElementTypeLayoutRules( ParameterGroupType* parameterGroupType, LayoutRulesImpl* rules, - TargetRequest* targetRequest) + CompilerOptionSet& compilerOptions) { if( as<ConstantBufferType>(parameterGroupType) ) { - return rules->getLayoutRulesFamily()->getConstantBufferRules(targetRequest); + return rules->getLayoutRulesFamily()->getConstantBufferRules(compilerOptions); } else if( as<TextureBufferType>(parameterGroupType) ) { @@ -2787,11 +2787,11 @@ LayoutRulesImpl* getParameterBufferElementTypeLayoutRules( } else if( as<GLSLShaderStorageBufferType>(parameterGroupType) ) { - return rules->getLayoutRulesFamily()->getShaderStorageBufferRules(targetRequest); + return rules->getLayoutRulesFamily()->getShaderStorageBufferRules(compilerOptions); } else if (as<ParameterBlockType>(parameterGroupType)) { - return rules->getLayoutRulesFamily()->getParameterBlockRules(targetRequest); + return rules->getLayoutRulesFamily()->getParameterBlockRules(compilerOptions); } else { @@ -2810,7 +2810,7 @@ RefPtr<TypeLayout> createParameterGroupTypeLayout( auto elementTypeRules = getParameterBufferElementTypeLayoutRules( parameterGroupType, parameterGroupRules, - context.targetReq); + context.targetReq->getOptionSet()); auto elementType = parameterGroupType->getElementType(); @@ -2831,7 +2831,7 @@ createStructuredBufferWithCounterTypeLayout( { auto typeLayout = createStructuredBufferTypeLayout(context, kind, structuredBufferType, elementTypeLayout); - const auto structuredBufferLayoutRules = context.getRulesFamily()->getStructuredBufferRules(context.targetReq); + const auto structuredBufferLayoutRules = context.getRulesFamily()->getStructuredBufferRules(context.targetReq->getOptionSet()); const auto counterType = context.astBuilder->getIntType(); const auto counterBufferType = context.astBuilder->getRWStructuredBufferType(counterType); @@ -2916,7 +2916,7 @@ createStructuredBufferTypeLayout( Type* elementType) { // look up the appropriate rules via the `LayoutRulesFamily` - auto structuredBufferLayoutRules = context.getRulesFamily()->getStructuredBufferRules(context.targetReq); + auto structuredBufferLayoutRules = context.getRulesFamily()->getStructuredBufferRules(context.targetReq->getOptionSet()); // Create and save type layout for the buffer contents. auto elementTypeLayout = createTypeLayoutWith( diff --git a/source/slang/slang-type-layout.h b/source/slang/slang-type-layout.h index 23b70d59d..f11ee342e 100644 --- a/source/slang/slang-type-layout.h +++ b/source/slang/slang-type-layout.h @@ -1052,14 +1052,14 @@ struct LayoutRulesImpl struct LayoutRulesFamilyImpl { virtual LayoutRulesImpl* getAnyValueRules() = 0; - virtual LayoutRulesImpl* getConstantBufferRules(TargetRequest* request) = 0; + virtual LayoutRulesImpl* getConstantBufferRules(CompilerOptionSet& compilerOptions) = 0; virtual LayoutRulesImpl* getPushConstantBufferRules() = 0; virtual LayoutRulesImpl* getTextureBufferRules() = 0; virtual LayoutRulesImpl* getVaryingInputRules() = 0; virtual LayoutRulesImpl* getVaryingOutputRules() = 0; virtual LayoutRulesImpl* getSpecializationConstantRules()= 0; - virtual LayoutRulesImpl* getShaderStorageBufferRules(TargetRequest* request) = 0; - virtual LayoutRulesImpl* getParameterBlockRules(TargetRequest* request) = 0; + virtual LayoutRulesImpl* getShaderStorageBufferRules(CompilerOptionSet& compilerOptions) = 0; + virtual LayoutRulesImpl* getParameterBlockRules(CompilerOptionSet& compilerOptions) = 0; virtual LayoutRulesImpl* getRayPayloadParameterRules() = 0; virtual LayoutRulesImpl* getCallablePayloadParameterRules() = 0; @@ -1067,7 +1067,7 @@ struct LayoutRulesFamilyImpl virtual LayoutRulesImpl* getShaderRecordConstantBufferRules() = 0; - virtual LayoutRulesImpl* getStructuredBufferRules(TargetRequest* request) = 0; + virtual LayoutRulesImpl* getStructuredBufferRules(CompilerOptionSet& compilerOptions) = 0; }; /// A custom tuple to capture the outputs of type layout @@ -1258,7 +1258,7 @@ private: // the ordering of all global generic type paramters. // TypeLayoutContext getInitialLayoutContextForTarget( - TargetRequest* targetReq, + TargetRequest* targetRequest, ProgramLayout* programLayout); /// Direction(s) of a varying shader parameter diff --git a/source/slang/slang-workspace-version.cpp b/source/slang/slang-workspace-version.cpp index 0826ca557..a07ef75cc 100644 --- a/source/slang/slang-workspace-version.cpp +++ b/source/slang/slang-workspace-version.cpp @@ -519,7 +519,7 @@ void WorkspaceVersion::ensureWorkspaceFlavor(UnownedStringSlice path) // Setup linkage for vfx files. // TODO: consider supporting this as an external config file. flavor = WorkspaceFlavor::VFX; - linkage->setEnableEffectAnnotations(true); + linkage->m_optionSet.set(CompilerOptionName::EnableEffectAnnotations, true); linkage->addPreprocessorDefine("VS", "__file_decl"); linkage->addPreprocessorDefine("CS", "__file_decl"); linkage->addPreprocessorDefine("GS", "__file_decl"); diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 395285b41..498dc67f5 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -169,7 +169,7 @@ void Session::init() // Built in linkage uses the built in builder m_builtinLinkage = new Linkage(this, builtinAstBuilder, nullptr); - m_builtinLinkage->debugInfoLevel = DebugInfoLevel::None; + m_builtinLinkage->m_optionSet.set(CompilerOptionName::DebugInformation, DebugInfoLevel::None); // Because the `Session` retains the builtin `Linkage`, // we need to make sure that the parent pointer inside @@ -578,7 +578,7 @@ static T makeFromSizeVersioned(const uint8_t* src) // The size to copy is the minimum on the two sizes const auto copySize = std::min(srcSize, dstSize); - ::memcpy(&dst, &src, copySize); + ::memcpy(&dst, src, copySize); // The final struct size is the destination size dst.structureSize = dstSize; @@ -587,11 +587,14 @@ static T makeFromSizeVersioned(const uint8_t* src) } SLANG_NO_THROW SlangResult SLANG_MCALL Session::createSession( - slang::SessionDesc const& desc, + slang::SessionDesc const& inDesc, slang::ISession** outSession) { RefPtr<ASTBuilder> astBuilder(new ASTBuilder(m_sharedASTBuilder, "Session::astBuilder")); + slang::SessionDesc desc = makeFromSizeVersioned<slang::SessionDesc>((uint8_t*)&inDesc); + RefPtr<Linkage> linkage = new Linkage(this, astBuilder, getBuiltinLinkage()); + linkage->m_optionSet.load(desc.compilerOptionEntryCount, desc.compilerOptionEntries); { const Int targetCount = desc.targetCount; @@ -603,13 +606,6 @@ SLANG_NO_THROW SlangResult SLANG_MCALL Session::createSession( } } - linkage->setFlags(desc.flags); - - if(desc.flags & slang::kSessionFlag_FalcorCustomSharedKeywordSemantics) - { - linkage->m_useFalcorCustomSharedKeywordSemantics = true; - } - linkage->setMatrixLayoutMode(desc.defaultMatrixLayoutMode); Int searchPathCount = desc.searchPathCount; @@ -632,9 +628,8 @@ SLANG_NO_THROW SlangResult SLANG_MCALL Session::createSession( if (desc.structureSize >= offsetof(slang::SessionDesc, enableEffectAnnotations)) { - linkage->setEnableEffectAnnotations(desc.enableEffectAnnotations); + linkage->m_optionSet.set(CompilerOptionName::EnableEffectAnnotations, desc.enableEffectAnnotations); } - *outSession = asExternal(linkage.detach()); return SLANG_OK; } @@ -836,10 +831,57 @@ SLANG_NO_THROW SlangResult SLANG_MCALL Session::setSPIRVCoreGrammar(char const* return spirvCoreGrammarInfo ? SLANG_OK : SLANG_FAIL; } +struct ParsedCommandLineData : public ISlangUnknown, public ComObject +{ + SLANG_COM_OBJECT_IUNKNOWN_ALL + + ISlangUnknown* getInterface(const Slang::Guid& guid) + { + if (guid == ISlangUnknown::getTypeGuid()) + return this; + return nullptr; + } + List<SerializedOptionsData> options; + List<slang::TargetDesc> targets; +}; + +SLANG_NO_THROW SlangResult SLANG_MCALL Session::parseCommandLineArguments( + int argc, + const char* const* argv, + slang::SessionDesc* outDesc, + ISlangUnknown** outAllocation) +{ + if (outDesc->structureSize < sizeof(slang::SessionDesc)) + return SLANG_E_BUFFER_TOO_SMALL; + RefPtr<ParsedCommandLineData> outData = new ParsedCommandLineData(); + SerializedOptionsData optionData; + RefPtr<EndToEndCompileRequest> tempReq = new EndToEndCompileRequest(this); + tempReq->processCommandLineArguments(argv, argc); + tempReq->getOptionSet().serialize(&optionData); + outData->options.add(optionData); + for (auto target : tempReq->getLinkage()->targets) + { + slang::TargetDesc tdesc; + SerializedOptionsData targetOptionData; + tempReq->getTargetOptionSet(target).serialize(&targetOptionData); + outData->options.add(targetOptionData); + tdesc.compilerOptionEntryCount = (uint32_t)targetOptionData.entries.getCount(); + tdesc.compilerOptionEntries = targetOptionData.entries.getBuffer(); + outData->targets.add(tdesc); + } + outDesc->compilerOptionEntryCount = (uint32_t)optionData.entries.getCount(); + outDesc->compilerOptionEntries = optionData.entries.getBuffer(); + outDesc->targetCount = outData->targets.getCount(); + outDesc->targets = outData->targets.getBuffer(); + *outAllocation = outData.get(); + outData->addRef(); + return SLANG_OK; +} + Profile getEffectiveProfile(EntryPoint* entryPoint, TargetRequest* target) { auto entryPointProfile = entryPoint->getProfile(); - auto targetProfile = target->getTargetProfile(); + auto targetProfile = target->getOptionSet().getProfile(); // Depending on the target *format* we might have to restrict the // profile family to one that makes sense. @@ -959,6 +1001,7 @@ Linkage::Linkage(Session* session, ASTBuilder* astBuilder, Linkage* builtinLinka , m_retainedSession(session) , m_sourceManager(&m_defaultSourceManager) , m_astBuilder(astBuilder) + , m_cmdLineContext(new CommandLineContext()) { if (builtinLinkage) m_astBuilder->m_cachedNodes = builtinLinkage->getASTBuilder()->m_cachedNodes; @@ -975,24 +1018,6 @@ Linkage::Linkage(Session* session, ASTBuilder* astBuilder, Linkage* builtinLinka for (const auto& nameToMod : builtinLinkage->mapNameToLoadedModules) mapNameToLoadedModules.add(nameToMod); } - - { - RefPtr<CommandLineContext> context = new CommandLineContext; - m_downstreamArgs = DownstreamArgs(context); - - // Add all of the possible names we allow for downstream tools - { - for (Index i = SLANG_PASS_THROUGH_NONE + 1; i < SLANG_PASS_THROUGH_COUNT_OF; ++i) - { - m_downstreamArgs.addName(TypeTextUtil::getPassThroughName(SlangPassThrough(i))); - } - - // Generic downstream tool - m_downstreamArgs.addName("downstream"); - // Generic downstream linker - m_downstreamArgs.addName("linker"); - } - } } ISlangUnknown* Linkage::getInterface(const Guid& guid) @@ -1008,6 +1033,18 @@ Linkage::~Linkage() destroyTypeCheckingCache(); } +SearchDirectoryList& Linkage::getSearchDirectories() +{ + auto list = m_optionSet.getArray(CompilerOptionName::Include); + if (list.getCount() != searchDirectoryCache.searchDirectories.getCount()) + { + searchDirectoryCache.searchDirectories.clear(); + for (auto dir : list) + searchDirectoryCache.searchDirectories.add(SearchDirectory(dir.stringValue)); + } + return searchDirectoryCache; +} + TypeCheckingCache* Linkage::getTypeCheckingCache() { if (!m_typeCheckingCache) @@ -1036,11 +1073,15 @@ void Linkage::addTarget( auto targetIndex = addTarget(CodeGenTarget(desc.format)); auto target = targets[targetIndex]; - target->setFloatingPointMode(FloatingPointMode(desc.floatingPointMode)); - target->addTargetFlags(desc.flags); - target->setTargetProfile(Profile(desc.profile)); - target->setLineDirectiveMode(LineDirectiveMode(desc.lineDirectiveMode)); - target->setForceGLSLScalarBufferLayout(desc.forceGLSLScalarBufferLayout); + auto& optionSet = target->getOptionSet(); + optionSet.inheritFrom(m_optionSet); + + optionSet.set(CompilerOptionName::FloatingPointMode, FloatingPointMode(desc.floatingPointMode)); + optionSet.addTargetFlags(desc.flags); + optionSet.setProfile(Profile(desc.profile)); + optionSet.set(CompilerOptionName::LineDirectiveMode, LineDirectiveMode(desc.lineDirectiveMode)); + optionSet.set(CompilerOptionName::GLSLForceScalarLayout, desc.forceGLSLScalarBufferLayout); + } #if 0 @@ -1064,6 +1105,7 @@ SLANG_NO_THROW slang::IModule* SLANG_MCALL Linkage::loadModule( SLANG_AST_BUILDER_RAII(getASTBuilder()); DiagnosticSink sink(getSourceManager(), Lexer::sourceLocationLexer); + applySettingsToDiagnosticSink(&sink, &sink, m_optionSet); if (isInLanguageServer()) { @@ -1097,10 +1139,13 @@ slang::IModule* Linkage::loadModuleFromBlob( SLANG_AST_BUILDER_RAII(getASTBuilder()); DiagnosticSink sink(getSourceManager(), Lexer::sourceLocationLexer); + applySettingsToDiagnosticSink(&sink, &sink, m_optionSet); + if (isInLanguageServer()) { sink.setFlags(DiagnosticSink::Flag::HumaneLoc | DiagnosticSink::Flag::LanguageServer); } + try { @@ -1177,6 +1222,7 @@ SLANG_NO_THROW SlangResult SLANG_MCALL Linkage::createCompositeComponentType( } DiagnosticSink sink(getSourceManager(), Lexer::sourceLocationLexer); + applySettingsToDiagnosticSink(&sink, &sink, m_optionSet); List<RefPtr<ComponentType>> childComponents; for( Int cc = 0; cc < componentTypeCount; ++cc ) @@ -1391,6 +1437,8 @@ SLANG_NO_THROW SlangResult SLANG_MCALL Linkage::createTypeConformanceComponentTy RefPtr<TypeConformance> result; DiagnosticSink sink; + applySettingsToDiagnosticSink(&sink, &sink, m_optionSet); + try { SharedSemanticsContext sharedSemanticsContext(this, nullptr, &sink); @@ -1437,47 +1485,12 @@ void Linkage::buildHash(DigestBuilder<SHA1>& builder, SlangInt targetIndex) auto version = String(getBuildTagString()); builder.append(version); - // Add the search directory paths to the hash - auto searchDirectoryList = getSearchDirectories().searchDirectories; - for (auto& searchDir : searchDirectoryList) - { - auto searchPath = searchDir.path; - builder.append(searchPath); - } - - // Add the preprocessor definitions to the hash - for (const auto& [defName, defVal] : preprocessorDefinitions) - { - builder.append(defName); - builder.append(defVal); - } - - // Add compiler settings to hash - builder.append(defaultMatrixLayoutMode); - builder.append(debugInfoLevel); - builder.append(debugInfoFormat); - builder.append(optimizationLevel); + // Add compiler options, including search path, preprocessor includes, etc. + m_optionSet.buildHash(builder); // Add the target specified by targetIndex auto targetReq = targets[targetIndex]; - builder.append(targetReq->getTarget()); - builder.append(targetReq->getTargetProfile().raw); - builder.append(targetReq->getTargetFlags()); - builder.append(targetReq->getFloatingPointMode()); - builder.append(targetReq->getLineDirectiveMode()); - builder.append(targetReq->getForceGLSLScalarBufferLayout()); - builder.append(targetReq->getDefaultMatrixLayoutMode()); - builder.append(targetReq->shouldDumpIntermediates()); - builder.append(targetReq->shouldTrackLiveness()); - - auto cookedCapabilities = targetReq->getTargetCaps().getExpandedAtoms(); - builder.append(cookedCapabilities.getCount()); - for (auto& capabilityConjunction : cookedCapabilities) - { - builder.append(capabilityConjunction.getExpandedAtoms().getCount()); - for (auto atom : capabilityConjunction.getExpandedAtoms()) - builder.append(atom); - } + targetReq->getOptionSet().buildHash(builder); const PassThroughMode passThroughMode = getDownstreamCompilerRequiredForTarget(targetReq->getTarget()); const SourceLanguage sourceLanguage = getDefaultSourceLanguageForDownstreamCompiler(passThroughMode); @@ -1511,7 +1524,7 @@ void Linkage::buildHash(DigestBuilder<SHA1>& builder, SlangInt targetIndex) SlangResult Linkage::addSearchPath( char const* path) { - searchDirectories.searchDirectories.add(Slang::SearchDirectory(path)); + m_optionSet.add(CompilerOptionName::Include, String(path)); return SLANG_OK; } @@ -1519,14 +1532,18 @@ SlangResult Linkage::addPreprocessorDefine( char const* name, char const* value) { - preprocessorDefinitions[name] = value; + CompilerOptionValue val; + val.kind = CompilerOptionValueKind::String; + val.stringValue = name; + val.stringValue2 = value; + m_optionSet.add(CompilerOptionName::MacroDefine, val); return SLANG_OK; } SlangResult Linkage::setMatrixLayoutMode( SlangMatrixLayoutMode mode) { - defaultMatrixLayoutMode = MatrixLayoutMode(mode); + m_optionSet.setMatrixLayoutMode((MatrixLayoutMode)mode); return SLANG_OK; } @@ -1536,32 +1553,30 @@ SlangResult Linkage::setMatrixLayoutMode( TargetRequest::TargetRequest(Linkage* linkage, CodeGenTarget format) : linkage(linkage) - , format(format) -{} - - -Session* TargetRequest::getSession() { - return linkage->getSessionImpl(); + optionSet = linkage->m_optionSet; + optionSet.add(CompilerOptionName::Target, format); } -MatrixLayoutMode TargetRequest::getDefaultMatrixLayoutMode() +TargetRequest::TargetRequest(const TargetRequest& other) + : linkage(other.linkage), optionSet(other.optionSet) { - return linkage->getDefaultMatrixLayoutMode(); } -void TargetRequest::setHLSLToVulkanLayoutOptions(HLSLToVulkanLayoutOptions* opts) + +Session* TargetRequest::getSession() { - if (isKhronosTarget(this)) - { - hlslToVulkanLayoutOptions = opts; - } + return linkage->getSessionImpl(); } -void TargetRequest::addCapability(CapabilityName capability) +HLSLToVulkanLayoutOptions* TargetRequest::getHLSLToVulkanLayoutOptions() { - rawCapabilities.add(capability); - cookedCapabilities = CapabilitySet::makeEmpty(); + if (!hlslToVulkanOptions) + { + hlslToVulkanOptions = new HLSLToVulkanLayoutOptions(); + hlslToVulkanOptions->loadFromOptionSet(optionSet); + } + return hlslToVulkanOptions.get(); } CapabilitySet TargetRequest::getTargetCaps() @@ -1590,7 +1605,7 @@ CapabilitySet TargetRequest::getTargetCaps() List<CapabilityName> atoms; bool isGLSLTarget = false; - switch(format) + switch(getTarget()) { case CodeGenTarget::GLSL: case CodeGenTarget::GLSL_Vulkan: @@ -1600,7 +1615,7 @@ CapabilitySet TargetRequest::getTargetCaps() break; case CodeGenTarget::SPIRV: case CodeGenTarget::SPIRVAssembly: - if (targetFlags & SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY) + if (getOptionSet().shouldEmitSPIRVDirectly()) { atoms.add(CapabilityName::spirv_1_5); } @@ -1645,8 +1660,9 @@ CapabilitySet TargetRequest::getTargetCaps() CapabilitySet latestSpirvCapSet = CapabilitySet(CapabilityName::spirv_latest); CapabilityName latestSpirvAtom = (CapabilityName)latestSpirvCapSet.getExpandedAtoms()[0].getExpandedAtoms().getLast(); - for (auto atom : rawCapabilities) + for (auto atomVal : optionSet.getArray(CompilerOptionName::Capability)) { + auto atom = (CapabilityName)atomVal.intValue; if (isGLSLTarget) { // If we are emitting GLSL code, we need to @@ -1740,16 +1756,11 @@ Scope* TranslationUnitRequest::getLanguageScope() Dictionary<String, String> TranslationUnitRequest::getCombinedPreprocessorDefinitions() { - // TODO(JS): - // Note! that a adding a define twice will cause an exception in debug builds - // that may be desirable or not... Dictionary<String, String> combinedPreprocessorDefinitions; - for (const auto& def : compileRequest->getLinkage()->preprocessorDefinitions) - combinedPreprocessorDefinitions.add(def); - for (const auto& def : compileRequest->preprocessorDefinitions) - combinedPreprocessorDefinitions.add(def); for (const auto& def : preprocessorDefinitions) - combinedPreprocessorDefinitions.add(def); + combinedPreprocessorDefinitions.addIfNotExists(def); + for (const auto& def : compileRequest->optionSet.getArray(CompilerOptionName::MacroDefine)) + combinedPreprocessorDefinitions.addIfNotExists(def.stringValue, def.stringValue2); // Define standard macros, if not already defined. This style assumes using `#if __SOME_VAR` style, as in // @@ -2098,6 +2109,7 @@ FrontEndCompileRequest::FrontEndCompileRequest( : CompileRequestBase(linkage, sink) , m_writers(writers) { + optionSet.inheritFrom(linkage->m_optionSet); } /// Handlers for preprocessor callbacks to use when doing ordinary front-end compilation @@ -2386,7 +2398,7 @@ void FrontEndCompileRequest::parseTranslationUnit( // Here we should probably be using the searchDirectories on the FrontEndCompileRequest. // If searchDirectories.parent pointed to the one in the Linkage would mean linkage paths // would be checked too (after those on the FrontEndCompileRequest). - IncludeSystem includeSystem(&linkage->searchDirectories, linkage->getFileSystemExt(), linkage->getSourceManager()); + IncludeSystem includeSystem(&linkage->getSearchDirectories(), linkage->getFileSystemExt(), linkage->getSourceManager()); auto combinedPreprocessorDefinitions = translationUnit->getCombinedPreprocessorDefinitions(); @@ -2458,12 +2470,12 @@ void FrontEndCompileRequest::parseTranslationUnit( break; } - if (outputIncludes) + if (optionSet.getBoolOption(CompilerOptionName::OutputIncludes)) { _outputIncludes(translationUnit->getSourceFiles(), getSink()->getSourceManager(), getSink()); } - if (outputPreprocessor) + if (optionSet.getBoolOption(CompilerOptionName::PreprocessorOutput)) { if (m_writers) { @@ -2484,7 +2496,7 @@ void FrontEndCompileRequest::parseTranslationUnit( // Let's try dumping - if (shouldDumpAST) + if (optionSet.getBoolOption(CompilerOptionName::DumpAst)) { StringBuilder buf; SourceWriter writer(linkage->getSourceManager(), LineDirectiveMode::None, nullptr); @@ -2660,7 +2672,7 @@ SlangResult FrontEndCompileRequest::executeActionsInner() parseTranslationUnit(translationUnit); } - if (outputPreprocessor) + if (optionSet.getBoolOption(CompilerOptionName::PreprocessorOutput)) { // If doing pre-processor output, then we are done return SLANG_OK; @@ -2675,7 +2687,7 @@ SlangResult FrontEndCompileRequest::executeActionsInner() return SLANG_FAIL; // After semantic checking is performed we can try and output doc information for this - if (shouldDocument) + if (optionSet.getBoolOption(CompilerOptionName::Doc)) { // Not 100% clear where best to get the ASTBuilder from, but from the linkage shouldn't // cause any problems with scoping @@ -2820,6 +2832,11 @@ SlangResult EndToEndCompileRequest::executeActionsInner() } } + // Update compiler settings in target requests. + for (auto target : getLinkage()->targets) + target->getOptionSet().inheritFrom(getOptionSet()); + m_frontEndReq->optionSet = getOptionSet(); + // We only do parsing and semantic checking if we *aren't* doing // a pass-through compilation. // @@ -2828,7 +2845,7 @@ SlangResult EndToEndCompileRequest::executeActionsInner() SLANG_RETURN_ON_FAIL(getFrontEndReq()->executeActionsInner()); } - if (getFrontEndReq()->outputPreprocessor) + if (getOptionSet().getBoolOption(CompilerOptionName::PreprocessorOutput)) { return SLANG_OK; } @@ -2836,8 +2853,7 @@ SlangResult EndToEndCompileRequest::executeActionsInner() // If command line specifies to skip codegen, we exit here. // Note: this is a debugging option. // - if (m_shouldSkipCodegen || - ((getFrontEndReq()->compileFlags & SLANG_COMPILE_FLAG_NO_CODEGEN) != 0)) + if (getOptionSet().getBoolOption(CompilerOptionName::SkipCodeGen)) { // We will use the program (and matching layout information) // that was computed in the front-end for all subsequent @@ -2848,7 +2864,7 @@ SlangResult EndToEndCompileRequest::executeActionsInner() m_specializedEntryPoints = getFrontEndReq()->getUnspecializedEntryPoints(); SLANG_RETURN_ON_FAIL(maybeCreateContainer()); - + SLANG_RETURN_ON_FAIL(maybeWriteContainer(m_containerOutputPath)); return SLANG_OK; @@ -2875,6 +2891,7 @@ SlangResult EndToEndCompileRequest::executeActionsInner() // for (auto targetReq : getLinkage()->targets) { + targetReq->getOptionSet().inheritFrom(getLinkage()->m_optionSet); auto targetProgram = m_specializedGlobalAndEntryPointsComponentType->getTargetProgram(targetReq); targetProgram->getOrCreateLayout(getSink()); } @@ -3388,7 +3405,7 @@ RefPtr<Module> Linkage::findOrImportModule( // Next, try to find the file of the given name, // using our ordinary include-handling logic. - IncludeSystem includeSystem(&searchDirectories, getFileSystemExt(), getSourceManager()); + IncludeSystem includeSystem(&getSearchDirectories(), getFileSystemExt(), getSourceManager()); // Get the original path info PathInfo pathIncludedFromInfo = getSourceManager()->getPathInfo(loc, SourceLocType::Actual); @@ -3458,7 +3475,8 @@ SourceFile* Linkage::findFile(Name* name, SourceLoc loc, IncludeSystem& outInclu // Next, try to find the file of the given name, // using our ordinary include-handling logic. - outIncludeSystem = IncludeSystem(&searchDirectories, getFileSystemExt(), getSourceManager()); + auto searchDirs = getSearchDirectories(); + outIncludeSystem = IncludeSystem(&searchDirs, getFileSystemExt(), getSourceManager()); // Get the original path info PathInfo pathIncludedFromInfo = getSourceManager()->getPathInfo(loc, SourceLocType::Actual); @@ -3808,7 +3826,6 @@ ISlangUnknown* ComponentType::getInterface(Guid const& guid) { return static_cast<slang::IComponentType*>(this); } - return nullptr; } @@ -3947,6 +3964,7 @@ SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getEntryPointCode( auto targetProgram = getTargetProgram(target); DiagnosticSink sink(linkage->getSourceManager(), Lexer::sourceLocationLexer); + applySettingsToDiagnosticSink(&sink, &sink, m_optionSet); IArtifact* artifact = targetProgram->getOrCreateEntryPointResult(entryPointIndex, &sink); sink.getBlobIfNeeded(outDiagnostics); @@ -4008,6 +4026,8 @@ SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getEntryPointHostCallable( auto targetProgram = getTargetProgram(target); DiagnosticSink sink(linkage->getSourceManager(), Lexer::sourceLocationLexer); + applySettingsToDiagnosticSink(&sink, &sink, m_optionSet); + IArtifact* artifact = targetProgram->getOrCreateEntryPointResult(entryPointIndex, &sink); sink.getBlobIfNeeded(outDiagnostics); @@ -4131,6 +4151,23 @@ SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::link( return SLANG_OK; } +SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::linkWithOptions( + slang::IComponentType** outLinkedComponentType, + uint32_t count, + slang::CompilerOptionEntry* entries, + ISlangBlob** outDiagnostics) +{ + SLANG_RETURN_ON_FAIL(link(outLinkedComponentType, outDiagnostics)); + + auto linked = *outLinkedComponentType; + + if (linked) + { + static_cast<ComponentType*>(linked)->getOptionSet().load(count, entries); + } + + return SLANG_OK; +} /// Visitor used by `ComponentType::enumerateModules` struct EnumerateModulesVisitor : ComponentTypeVisitor @@ -4875,13 +4912,12 @@ TargetProgram::TargetProgram( , m_targetReq(targetReq) { m_entryPointResults.setCount(componentType->getEntryPointCount()); + m_optionSet.overrideWith(m_program->getOptionSet()); + m_optionSet.inheritFrom(targetReq->getOptionSet()); } // - - - Session* CompileRequestBase::getSession() { return getLinkage()->getSessionImpl(); @@ -4981,6 +5017,7 @@ void Session::addBuiltinSource( SourceManager* sourceManager = getBuiltinSourceManager(); DiagnosticSink sink(sourceManager, Lexer::sourceLocationLexer); + RefPtr<FrontEndCompileRequest> compileRequest = new FrontEndCompileRequest( m_builtinLinkage, nullptr, @@ -5075,60 +5112,53 @@ void EndToEndCompileRequest::setFileSystem(ISlangFileSystem* fileSystem) void EndToEndCompileRequest::setCompileFlags(SlangCompileFlags flags) { - getFrontEndReq()->compileFlags = flags; + if (flags & SLANG_COMPILE_FLAG_NO_MANGLING) + getOptionSet().set(CompilerOptionName::NoMangle, true); + if (flags & SLANG_COMPILE_FLAG_NO_CODEGEN) + getOptionSet().set(CompilerOptionName::SkipCodeGen, true); + if (flags & SLANG_COMPILE_FLAG_OBFUSCATE) + getOptionSet().set(CompilerOptionName::Obfuscate, true); } SlangCompileFlags EndToEndCompileRequest::getCompileFlags() { - return getFrontEndReq()->compileFlags; + SlangCompileFlags result = 0; + if (getOptionSet().getBoolOption(CompilerOptionName::NoMangle)) + result |= SLANG_COMPILE_FLAG_NO_MANGLING; + if (getOptionSet().getBoolOption(CompilerOptionName::SkipCodeGen)) + result |= SLANG_COMPILE_FLAG_NO_CODEGEN; + if (getOptionSet().getBoolOption(CompilerOptionName::Obfuscate)) + result |= SLANG_COMPILE_FLAG_OBFUSCATE; + return result; } void EndToEndCompileRequest::setDumpIntermediates(int enable) { - shouldDumpIntermediates = (enable != 0); - - // Change all existing targets to use the new setting. - auto linkage = getLinkage(); - for (auto& target : linkage->targets) - { - target->setDumpIntermediates(enable != 0); - } + getOptionSet().set(CompilerOptionName::DumpIntermediates, enable); } void EndToEndCompileRequest::setTrackLiveness(bool v) { - enableLivenessTracking = v; - - // Change all existing targets to use the new setting. - auto linkage = getLinkage(); - for (auto& target : linkage->targets) - { - target->setTrackLiveness(v); - } + getOptionSet().set(CompilerOptionName::TrackLiveness, v); } void EndToEndCompileRequest::setDumpIntermediatePrefix(const char* prefix) { - m_dumpIntermediatePrefix = prefix; + getOptionSet().set(CompilerOptionName::DumpIntermediatePrefix, String(prefix)); } void EndToEndCompileRequest::setLineDirectiveMode(SlangLineDirectiveMode mode) { - // This method is deprecated and user should call `setTargetLineDirectiveMode` instead. - // We provide the implementation here for backward compatibility. - // Targets added later will use `m_lineDirectiveMode`, so we update it to the new `mode` - // set by the user. - m_lineDirectiveMode = LineDirectiveMode(mode); - - // Change all existing targets to use the new mode. - auto linkage = getLinkage(); - for (auto& target : linkage->targets) - target->setLineDirectiveMode(m_lineDirectiveMode); + getOptionSet().set(CompilerOptionName::LineDirectiveMode, mode); } void EndToEndCompileRequest::setCommandLineCompilerMode() { m_isCommandLineCompile = true; + + // legacy slangc tool defaults to column major layout. + if (!getOptionSet().hasOption(CompilerOptionName::MatrixLayoutRow)) + getOptionSet().setMatrixLayoutMode(kMatrixLayoutMode_ColumnMajor); } void EndToEndCompileRequest::_completeTargetRequest(UInt targetIndex) @@ -5137,14 +5167,7 @@ void EndToEndCompileRequest::_completeTargetRequest(UInt targetIndex) TargetRequest* targetRequest = linkage->targets[Index(targetIndex)]; - // If we have vulkan layout options, and the target is khronos add the options - if (m_hlslToVulkanLayoutOptions && isKhronosTarget(targetRequest)) - { - targetRequest->setHLSLToVulkanLayoutOptions(m_hlslToVulkanLayoutOptions); - } - - // Set the current line directive - targetRequest->setLineDirectiveMode(m_lineDirectiveMode); + targetRequest->getOptionSet().inheritFrom(getLinkage()->m_optionSet); } void EndToEndCompileRequest::setCodeGenTarget(SlangCompileTarget target) @@ -5165,45 +5188,39 @@ int EndToEndCompileRequest::addCodeGenTarget(SlangCompileTarget target) void EndToEndCompileRequest::setTargetProfile(int targetIndex, SlangProfileID profile) { - getLinkage()->targets[targetIndex]->setTargetProfile(Profile(profile)); -} - -void EndToEndCompileRequest::setHLSLToVulkanLayoutOptions(int targetIndex, HLSLToVulkanLayoutOptions* vulkanShiftOptions) -{ - getLinkage()->targets[targetIndex]->setHLSLToVulkanLayoutOptions(vulkanShiftOptions); + getTargetOptionSet(targetIndex).setProfile(Profile(profile)); } void EndToEndCompileRequest::setTargetFlags(int targetIndex, SlangTargetFlags flags) { - getLinkage()->targets[targetIndex]->addTargetFlags(flags); + getTargetOptionSet(targetIndex).setTargetFlags(flags); } void EndToEndCompileRequest::setTargetForceGLSLScalarBufferLayout(int targetIndex, bool value) { - getLinkage()->targets[targetIndex]->setForceGLSLScalarBufferLayout(value); + getTargetOptionSet(targetIndex).set(CompilerOptionName::GLSLForceScalarLayout, value); } void EndToEndCompileRequest::setTargetFloatingPointMode(int targetIndex, SlangFloatingPointMode mode) { - getLinkage()->targets[targetIndex]->setFloatingPointMode(FloatingPointMode(mode)); + getTargetOptionSet(targetIndex).set(CompilerOptionName::FloatingPointMode, FloatingPointMode(mode)); } void EndToEndCompileRequest::setMatrixLayoutMode(SlangMatrixLayoutMode mode) { - getLinkage()->setMatrixLayoutMode(mode); + getOptionSet().setMatrixLayoutMode((MatrixLayoutMode)mode); } void EndToEndCompileRequest::setTargetMatrixLayoutMode(int targetIndex, SlangMatrixLayoutMode mode) { - SLANG_UNUSED(targetIndex); - setMatrixLayoutMode(mode); + getTargetOptionSet(targetIndex).setMatrixLayoutMode(MatrixLayoutMode(mode)); } void EndToEndCompileRequest::setTargetLineDirectiveMode( SlangInt targetIndex, SlangLineDirectiveMode mode) { - getLinkage()->targets[targetIndex]->setLineDirectiveMode(LineDirectiveMode(mode)); + getTargetOptionSet(targetIndex).set(CompilerOptionName::LineDirectiveMode, LineDirectiveMode(mode)); } void EndToEndCompileRequest::overrideDiagnosticSeverity( @@ -5250,23 +5267,23 @@ SlangResult EndToEndCompileRequest::addTargetCapability(SlangInt targetIndex, Sl auto& targets = getLinkage()->targets; if(targetIndex < 0 || targetIndex >= targets.getCount()) return SLANG_E_INVALID_ARG; - targets[targetIndex]->addCapability(CapabilityName(capability)); + getTargetOptionSet(targetIndex).addCapabilityAtom(CapabilityName(capability)); return SLANG_OK; } void EndToEndCompileRequest::setDebugInfoLevel(SlangDebugInfoLevel level) { - getLinkage()->debugInfoLevel = DebugInfoLevel(level); + getOptionSet().set(CompilerOptionName::DebugInformation, DebugInfoLevel(level)); } void EndToEndCompileRequest::setDebugInfoFormat(SlangDebugInfoFormat format) { - getLinkage()->debugInfoFormat = DebugInfoFormat(format); + getOptionSet().set(CompilerOptionName::DebugInformationFormat, DebugInfoFormat(format)); } void EndToEndCompileRequest::setOptimizationLevel(SlangOptimizationLevel level) { - getLinkage()->optimizationLevel = OptimizationLevel(level); + getOptionSet().set(CompilerOptionName::Optimization, OptimizationLevel(level)); } void EndToEndCompileRequest::setOutputContainerFormat(SlangContainerFormat format) @@ -5281,17 +5298,17 @@ void EndToEndCompileRequest::setPassThrough(SlangPassThrough inPassThrough) void EndToEndCompileRequest::setReportDownstreamTime(bool value) { - m_reportDownstreamCompileTime = value; + getOptionSet().set(CompilerOptionName::ReportDownstreamTime, value); } void EndToEndCompileRequest::setReportPerfBenchmark(bool value) { - m_reportPerfBenchmark = value; + getOptionSet().set(CompilerOptionName::ReportPerfBenchmark, value); } void EndToEndCompileRequest::setSkipSPIRVValidation(bool value) { - m_skipSPIRVValidation = value; + getOptionSet().set(CompilerOptionName::SkipSPIRVValidation, value); } void EndToEndCompileRequest::setDiagnosticCallback(SlangDiagnosticCallback callback, void const* userData) @@ -5312,17 +5329,17 @@ ISlangWriter* EndToEndCompileRequest::getWriter(SlangWriterChannel chan) void EndToEndCompileRequest::addSearchPath(const char* path) { - getLinkage()->addSearchPath(path); + getOptionSet().addSearchPath(path); } void EndToEndCompileRequest::addPreprocessorDefine(const char* key, const char* value) { - getLinkage()->addPreprocessorDefine(key, value); + getOptionSet().addPreprocessorDefine(key, value); } void EndToEndCompileRequest::setEnableEffectAnnotations(bool value) { - getLinkage()->setEnableEffectAnnotations(value); + getOptionSet().set(CompilerOptionName::EnableEffectAnnotations, value); } char const* EndToEndCompileRequest::getDiagnosticOutput() @@ -5599,16 +5616,16 @@ SlangResult EndToEndCompileRequest::setTypeNameForEntryPointExistentialTypeParam void EndToEndCompileRequest::setAllowGLSLInput(bool value) { - getLinkage()->setAllowGLSLInput(value); + getOptionSet().set(CompilerOptionName::AllowGLSL, value); } -SlangResult EndToEndCompileRequest::EndToEndCompileRequest::compile() +SlangResult EndToEndCompileRequest::compile() { SlangResult res = SLANG_FAIL; double downstreamStartTime = 0.0; double totalStartTime = 0.0; - if (m_reportDownstreamCompileTime) + if (getOptionSet().getBoolOption(CompilerOptionName::ReportDownstreamTime)) { getSession()->getCompilerElapsedTime(&totalStartTime, &downstreamStartTime); } @@ -5665,7 +5682,7 @@ SlangResult EndToEndCompileRequest::EndToEndCompileRequest::compile() } #endif - if (m_reportDownstreamCompileTime) + if (getOptionSet().getBoolOption(CompilerOptionName::ReportDownstreamTime)) { double downstreamEndTime = 0; double totalEndTime = 0; @@ -5674,7 +5691,7 @@ SlangResult EndToEndCompileRequest::EndToEndCompileRequest::compile() String downstreamTimeStr = String(downstreamTime, "%.2f"); getSink()->diagnose(SourceLoc(), Diagnostics::downstreamCompileTime, downstreamTimeStr); } - if (m_reportPerfBenchmark) + if (getOptionSet().getBoolOption(CompilerOptionName::ReportPerfBenchmark)) { StringBuilder perfResult; PerformanceProfiler::getProfiler()->getResult(perfResult); @@ -5684,16 +5701,19 @@ SlangResult EndToEndCompileRequest::EndToEndCompileRequest::compile() // Repro dump handling { - if (m_dumpRepro.getLength()) + auto dumpRepro = getOptionSet().getStringOption(CompilerOptionName::DumpRepro); + auto dumpReproOnError = getOptionSet().getBoolOption(CompilerOptionName::DumpReproOnError); + + if (dumpRepro.getLength()) { - SlangResult saveRes = ReproUtil::saveState(this, m_dumpRepro); + SlangResult saveRes = ReproUtil::saveState(this, dumpRepro); if (SLANG_FAILED(saveRes)) { - getSink()->diagnose(SourceLoc(), Diagnostics::unableToWriteReproFile, m_dumpRepro); + getSink()->diagnose(SourceLoc(), Diagnostics::unableToWriteReproFile, dumpRepro); return saveRes; } } - else if (m_dumpReproOnError && SLANG_FAILED(res)) + else if (dumpReproOnError && SLANG_FAILED(res)) { String reproFileName; SlangResult saveRes = SLANG_FAIL; |
