Add option to override semantic defines (#3766)

This commit is contained in:
Vishal Sharma 2021-05-11 21:43:15 -07:00 коммит произвёл GitHub
Родитель 61bd18526d
Коммит 742657ade4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
10 изменённых файлов: 130 добавлений и 6 удалений

Просмотреть файл

@ -28,6 +28,7 @@ class DxcLangExtensionsCommonHelper {
private:
llvm::SmallVector<std::string, 2> m_semanticDefines;
llvm::SmallVector<std::string, 2> m_semanticDefineExclusions;
llvm::SetVector<std::string> m_nonOptSemanticDefines;
llvm::SmallVector<std::string, 2> m_defines;
llvm::SmallVector<CComPtr<IDxcIntrinsicTable>, 2> m_intrinsicTables;
CComPtr<IDxcSemanticDefineValidator> m_semanticDefineValidator;
@ -47,9 +48,24 @@ private:
CATCH_CPP_RETURN_HRESULT();
}
HRESULT STDMETHODCALLTYPE RegisterIntoSet(LPCWSTR name, llvm::SetVector<std::string>& here)
{
try {
IFTPTR(name);
std::string s;
if (!Unicode::UTF16ToUTF8String(name, &s)) {
throw ::hlsl::Exception(E_INVALIDARG);
}
here.insert(s);
return S_OK;
}
CATCH_CPP_RETURN_HRESULT();
}
public:
const llvm::SmallVector<std::string, 2>& GetSemanticDefines() const { return m_semanticDefines; }
const llvm::SmallVector<std::string, 2>& GetSemanticDefineExclusions() const { return m_semanticDefineExclusions; }
const llvm::SetVector<std::string>& GetNonOptSemanticDefines() const { return m_nonOptSemanticDefines; }
const llvm::SmallVector<std::string, 2>& GetDefines() const { return m_defines; }
llvm::SmallVector<CComPtr<IDxcIntrinsicTable>, 2>& GetIntrinsicTables(){ return m_intrinsicTables; }
const std::string &GetSemanticDefineMetadataName() { return m_semanticDefineMetaDataName; }
@ -65,6 +81,11 @@ public:
return RegisterIntoVector(name, m_semanticDefineExclusions);
}
HRESULT STDMETHODCALLTYPE RegisterNonOptSemanticDefine(LPCWSTR name)
{
return RegisterIntoSet(name, m_nonOptSemanticDefines);
}
HRESULT STDMETHODCALLTYPE RegisterDefine(LPCWSTR name)
{
return RegisterIntoVector(name, m_defines);
@ -218,6 +239,10 @@ public:
DxcThreadMalloc TM(m_pMalloc); \
return (_helper_field_).RegisterSemanticDefineExclusion(name); \
} \
HRESULT STDMETHODCALLTYPE RegisterNonOptSemanticDefine(LPCWSTR name) override { \
DxcThreadMalloc TM(m_pMalloc); \
return (_helper_field_).RegisterNonOptSemanticDefine(name); \
} \
HRESULT STDMETHODCALLTYPE RegisterDefine(LPCWSTR name) override { \
DxcThreadMalloc TM(m_pMalloc); \
return (_helper_field_).RegisterDefine(name); \

Просмотреть файл

@ -20,6 +20,7 @@
#include "dxc/dxcapi.h"
#include "dxc/Support/SPIRVOptions.h"
#include <map>
#include <set>
namespace llvm {
namespace opt {
@ -133,6 +134,7 @@ public:
unsigned DefaultTextCodePage = DXC_CP_UTF8; // OPT_encoding
bool AllResourcesBound = false; // OPT_all_resources_bound
bool IgnoreOptSemDefs = false; // OPT_ignore_opt_semdefs
bool AstDump = false; // OPT_ast_dump
bool ColorCodeAssembly = false; // OPT_Cc
bool CodeGenHighLevel = false; // OPT_fcgl
@ -200,6 +202,9 @@ public:
std::map<std::string, bool> DxcOptimizationToggles; // OPT_opt_enable & OPT_opt_disable
std::map<std::string, std::string> DxcOptimizationSelects; // OPT_opt_select
std::set<std::string> IgnoreSemDefs; // OPT_ignore_semdef
std::map<std::string, std::string> OverrideSemDefs; // OPT_override_semdef
bool PrintAfterAll; // OPT_print_after_all
bool EnablePayloadQualifiers = false; // OPT_enable_payload_qualifiers
bool HandleExceptions = false; // OPT_disable_exception_handling

Просмотреть файл

@ -271,6 +271,12 @@ def validator_version : Separate<["-", "/"], "validator-version">, Group<hlslcom
HelpText<"Override validator version for module. Format: <major.minor> ; Default: DXIL.dll version or current internal version.">;
def print_after_all : Flag<["-", "/"], "print-after-all">, Group<hlslcomp_Group>, Flags<[CoreOption, HelpHidden]>,
HelpText<"Print LLVM IR after each pass.">;
def ignore_opt_semdefs : Flag<["-", "/"], "ignore-opt-semdefs">, Group<hlslcomp_Group>, Flags<[CoreOption, HelpHidden]>,
HelpText<"Ignore optional semantic defines which are not required to ensure program correctness.">;
def ignore_semdef : Separate<["-", "/"], "ignore-semdef">, Group<hlslcomp_Group>, Flags<[CoreOption, HelpHidden]>,
HelpText<"Ignore the semantic define passed as a value to this flag.">;
def override_semdef : Separate<["-", "/"], "override-semdef">, Group<hlslcomp_Group>, Flags<[CoreOption, HelpHidden]>,
HelpText<"Override the value of semantic define with the one passed with this flag.">;
def force_zero_store_lifetimes : Flag<["-", "/"], "force-zero-store-lifetimes">, Group<hlslcomp_Group>, Flags<[CoreOption, HelpHidden]>,
HelpText<"Instead of generating lifetime intrinsics (SM >= 6.6) or storing undef (SM < 6.6), force fall back to storing zeroinitializer.">;
def enable_lifetime_markers : Flag<["-", "/"], "enable-lifetime-markers">, Group<hlslcomp_Group>, Flags<[CoreOption]>,

Просмотреть файл

@ -196,6 +196,13 @@ public:
virtual HRESULT STDMETHODCALLTYPE SetTargetTriple(LPCSTR name) = 0;
};
CROSS_PLATFORM_UUIDOF(IDxcLangExtensions3, "A1B19880-FB1F-4920-9BC5-50356483BAC1")
struct IDxcLangExtensions3 : public IDxcLangExtensions2 {
public:
/// Registers a semantic define which cannot be overriden using the flag -override-opt-semdefs
virtual HRESULT STDMETHODCALLTYPE RegisterNonOptSemanticDefine(LPCWSTR name) = 0;
};
CROSS_PLATFORM_UUIDOF(IDxcSystemAccess, "454b764f-3549-475b-958c-a7a6fcd05fbc")
struct IDxcSystemAccess : public IUnknown
{

Просмотреть файл

@ -258,6 +258,18 @@ static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group,
}
}
static std::pair<std::string, std::string> ParseDefine(std::string &argVal) {
std::pair<std::string, std::string> result = std::make_pair("", "");
if (argVal.empty())
return result;
auto defEndPos = argVal.find('=') == std::string::npos ? argVal.size() : argVal.find('=');
result.first = argVal.substr(0, defEndPos);
if (!result.first.empty() && defEndPos < argVal.size() - 1) {
result.second = argVal.substr(defEndPos + 1, argVal.size() - defEndPos - 1);
}
return result;
}
// SPIRV Change Starts
#ifdef ENABLE_SPIRV_CODEGEN
/// Checks and collects the arguments for -fvk-{b|s|t|u}-shift into *shifts.
@ -507,6 +519,23 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
}
}
std::vector<std::string> ignoreSemDefs = Args.getAllArgValues(OPT_ignore_semdef);
for (std::string &ignoreSemDef : ignoreSemDefs) {
opts.IgnoreSemDefs.insert(ignoreSemDef);
}
std::vector<std::string> overrideSemDefs = Args.getAllArgValues(OPT_override_semdef);
for (std::string &overrideSemDef : overrideSemDefs) {
auto kv = ParseDefine(overrideSemDef);
if (kv.first.empty())
continue;
if (opts.OverrideSemDefs.find(kv.first) == opts.OverrideSemDefs.end()) {
opts.OverrideSemDefs.insert(std::make_pair(kv.first, kv.second));
} else {
opts.OverrideSemDefs[kv.first] = kv.second;
}
}
std::vector<std::string> optSelects = Args.getAllArgValues(OPT_opt_select);
for (unsigned i = 0; i + 1 < optSelects.size(); i+=2) {
std::string optimization = llvm::StringRef(optSelects[i]).lower();
@ -612,6 +641,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
opts.AllResourcesBound = Args.hasFlag(OPT_all_resources_bound, OPT_INVALID, false);
opts.AllResourcesBound = Args.hasFlag(OPT_all_resources_bound_, OPT_INVALID, opts.AllResourcesBound);
opts.IgnoreOptSemDefs = Args.hasFlag(OPT_ignore_opt_semdefs, OPT_INVALID, false);
opts.ColorCodeAssembly = Args.hasFlag(OPT_Cc, OPT_INVALID, false);
opts.DefaultRowMajor = Args.hasFlag(OPT_Zpr, OPT_INVALID, false);
opts.DefaultColMajor = Args.hasFlag(OPT_Zpc, OPT_INVALID, false);

Просмотреть файл

@ -20,6 +20,7 @@
#include <string>
#include <vector>
#include <map>
#include <set>
#include "dxc/HLSL/HLSLExtensionsCodegenHelper.h" // HLSL change
#include "dxc/Support/SPIRVOptions.h" // SPIR-V Change
@ -194,6 +195,12 @@ public:
bool HLSLAvoidControlFlow = false;
/// Force [flatten] on every if.
bool HLSLAllResourcesBound = false;
/// Skip adding optional semantics defines except ones which are required for correctness.
bool HLSLIgnoreOptSemDefs = false;
/// List of semantic defines that must be ignored.
std::set<std::string> HLSLIgnoreSemDefs;
/// List of semantic defines that must be overridden with user-provided values.
std::map<std::string, std::string> HLSLOverrideSemDefs;
/// Major version of validator to run.
unsigned HLSLValidatorMajorVer = 0;
/// Minor version of validator to run.

Просмотреть файл

@ -547,7 +547,7 @@ static void CreateDefineStrings(
}
class DxcCompiler : public IDxcCompiler3,
public IDxcLangExtensions2,
public IDxcLangExtensions3,
public IDxcContainerEvent,
public IDxcVersionInfo3,
#ifdef SUPPORT_QUERY_GIT_COMMIT_INFO
@ -583,6 +583,7 @@ public:
IDxcCompiler3,
IDxcLangExtensions,
IDxcLangExtensions2,
IDxcLangExtensions3,
IDxcContainerEvent,
IDxcVersionInfo
#ifdef SUPPORT_QUERY_GIT_COMMIT_INFO
@ -1347,6 +1348,9 @@ public:
compiler.getCodeGenOpts().HLSLOptimizationToggles = Opts.DxcOptimizationToggles;
compiler.getCodeGenOpts().HLSLOptimizationSelects = Opts.DxcOptimizationSelects;
compiler.getCodeGenOpts().HLSLAllResourcesBound = Opts.AllResourcesBound;
compiler.getCodeGenOpts().HLSLIgnoreOptSemDefs = Opts.IgnoreOptSemDefs;
compiler.getCodeGenOpts().HLSLIgnoreSemDefs = Opts.IgnoreSemDefs;
compiler.getCodeGenOpts().HLSLOverrideSemDefs = Opts.OverrideSemDefs;
compiler.getCodeGenOpts().HLSLDefaultRowMajor = Opts.DefaultRowMajor;
compiler.getCodeGenOpts().HLSLPreferControlFlow = Opts.PreferFlowControl;
compiler.getCodeGenOpts().HLSLAvoidControlFlow = Opts.AvoidFlowControl;

Просмотреть файл

@ -189,7 +189,7 @@ public:
_Outptr_result_nullonfailure_ IDxcTranslationUnit** pTranslationUnit) override;
};
class DxcIntelliSense : public IDxcIntelliSense, public IDxcLangExtensions2 {
class DxcIntelliSense : public IDxcIntelliSense, public IDxcLangExtensions3 {
private:
DXC_MICROCOM_TM_REF_FIELDS()
hlsl::DxcLangExtensionsHelper m_langHelper;
@ -201,7 +201,7 @@ public:
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject) override {
return DoBasicQueryInterface<IDxcIntelliSense, IDxcLangExtensions,
IDxcLangExtensions2>(
IDxcLangExtensions2, IDxcLangExtensions3>(
this, iid, ppvObject);
}

Просмотреть файл

@ -340,6 +340,11 @@ ParsedSemanticDefineList hlsl::CollectSemanticDefinesParsedByCompiler(
const llvm::SmallVector<std::string, 2> &defineExclusions =
helper->GetSemanticDefineExclusions();
const llvm::SetVector<std::string> &nonOptDefines =
helper->GetNonOptSemanticDefines();
std::set<std::string> overridenMacroSemDef;
// This is very inefficient in general, but in practice we either have
// no semantic defines, or we have a star define for a some reserved prefix.
// These will be sorted so rewrites are stable.
@ -374,10 +379,45 @@ ParsedSemanticDefineList hlsl::CollectSemanticDefinesParsedByCompiler(
continue;
}
// overriding a semantic define takes the first precedence
if (compiler.getCodeGenOpts().HLSLOverrideSemDefs.size() > 0 &&
compiler.getCodeGenOpts().HLSLOverrideSemDefs.find(ii->getName().str()) !=
compiler.getCodeGenOpts().HLSLOverrideSemDefs.end()) {
std::string defName = ii->getName().str();
std::string defValue = compiler.getCodeGenOpts().HLSLOverrideSemDefs[defName];
overridenMacroSemDef.insert(defName);
parsedDefines.emplace_back(ParsedSemanticDefine{ defName, defValue, 0 });
continue;
}
// ignoring a specific semantic define takes second precedence
if (compiler.getCodeGenOpts().HLSLIgnoreSemDefs.size() > 0 &&
compiler.getCodeGenOpts().HLSLIgnoreSemDefs.find(ii->getName().str()) !=
compiler.getCodeGenOpts().HLSLIgnoreSemDefs.end()) {
continue;
}
// ignoring all non-correctness semantic defines takes third precendence
if (compiler.getCodeGenOpts().HLSLIgnoreOptSemDefs &&
!nonOptDefines.count(ii->getName().str())) {
continue;
}
macros.push_back(std::pair<const IdentifierInfo *, MacroInfo *>(ii, mi));
}
}
// If there are semantic defines which are passed using -override-semdef flag,
// but we don't have that semantic define present in source or arglist, then
// we just add the semantic define.
for (auto &kv : compiler.getCodeGenOpts().HLSLOverrideSemDefs) {
std::string overrideDefName = kv.first;
std::string overrideDefVal = kv.second;
if (overridenMacroSemDef.find(overrideDefName) == overridenMacroSemDef.end()) {
parsedDefines.emplace_back(ParsedSemanticDefine{ overrideDefName, overrideDefVal, 0 });
}
}
if (!macros.empty()) {
std::sort(macros.begin(), macros.end(), MacroPairCompareIsLessThan);
MacroExpander expander(pp);
@ -1226,7 +1266,7 @@ HRESULT DoReWriteWithLineDirective(
}
} // namespace
class DxcRewriter : public IDxcRewriter2, public IDxcLangExtensions2 {
class DxcRewriter : public IDxcRewriter2, public IDxcLangExtensions3 {
private:
DXC_MICROCOM_TM_REF_FIELDS()
DxcLangExtensionsHelper m_langExtensionsHelper;
@ -1238,7 +1278,7 @@ public:
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid,
void **ppvObject) override {
return DoBasicQueryInterface<IDxcRewriter2, IDxcRewriter,
IDxcLangExtensions, IDxcLangExtensions2>(
IDxcLangExtensions, IDxcLangExtensions2, IDxcLangExtensions3>(
this, iid, ppvObject);
}

Просмотреть файл

@ -494,7 +494,7 @@ public:
dxc::DxcDllSupport &m_dllSupport;
CComPtr<IDxcCompiler> pCompiler;
CComPtr<IDxcLangExtensions2> pLangExtensions;
CComPtr<IDxcLangExtensions3> pLangExtensions;
CComPtr<IDxcBlobEncoding> pCodeBlob;
CComPtr<IDxcOperationResult> pCompileResult;
CComPtr<IDxcSemanticDefineValidator> pTestSemanticDefineValidator;