Web: Change a bunch of HLSL methods from dynamic to compile-time known.

This saves about 7K.
By changing just a few methods to be compile-time known, a bunch of
scattered code becomes DCE.
This commit is contained in:
John Kessenich 2019-07-27 08:18:03 -06:00
parent d4ed5158d1
commit bfc21ff1a9
9 changed files with 55 additions and 26 deletions

View File

@ -1 +1 @@
1210368 ../build/install/bin/glslangValidator.exe 1202688 ../build/install/bin/glslangValidator.exe

View File

@ -359,7 +359,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo
switch (op) { switch (op) {
case EOpLogicalNot: case EOpLogicalNot:
if (source == EShSourceHlsl) { if (getSource() == EShSourceHlsl) {
break; // HLSL can promote logical not break; // HLSL can promote logical not
} }
@ -544,7 +544,7 @@ bool TIntermediate::isConversionAllowed(TOperator op, TIntermTyped* node) const
break; break;
// HLSL can assign samplers directly (no constructor) // HLSL can assign samplers directly (no constructor)
if (source == EShSourceHlsl && node->getBasicType() == EbtSampler) if (getSource() == EShSourceHlsl && node->getBasicType() == EbtSampler)
break; break;
// samplers can get assigned via a sampler constructor // samplers can get assigned via a sampler constructor
@ -921,7 +921,7 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no
case EOpLogicalAnd: case EOpLogicalAnd:
case EOpLogicalOr: case EOpLogicalOr:
case EOpLogicalXor: case EOpLogicalXor:
if (source == EShSourceHlsl) if (getSource() == EShSourceHlsl)
promoteTo = std::make_tuple(EbtBool, EbtBool); promoteTo = std::make_tuple(EbtBool, EbtBool);
else else
return std::make_tuple(node0, node1); return std::make_tuple(node0, node1);
@ -932,7 +932,7 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no
// HLSL can promote bools to ints to make this work. // HLSL can promote bools to ints to make this work.
case EOpLeftShift: case EOpLeftShift:
case EOpRightShift: case EOpRightShift:
if (source == EShSourceHlsl) { if (getSource() == EShSourceHlsl) {
TBasicType node0BasicType = node0->getBasicType(); TBasicType node0BasicType = node0->getBasicType();
if (node0BasicType == EbtBool) if (node0BasicType == EbtBool)
node0BasicType = EbtInt; node0BasicType = EbtInt;
@ -1133,7 +1133,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EOpLeftShiftAssign: case EOpLeftShiftAssign:
case EOpRightShiftAssign: case EOpRightShiftAssign:
{ {
if (source == EShSourceHlsl && node->getType().getBasicType() == EbtBool) if (getSource() == EShSourceHlsl && node->getType().getBasicType() == EbtBool)
promoteTo = type.getBasicType(); promoteTo = type.getBasicType();
else { else {
if (isTypeInt(type.getBasicType()) && isTypeInt(node->getBasicType())) if (isTypeInt(type.getBasicType()) && isTypeInt(node->getBasicType()))
@ -1179,7 +1179,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
TIntermTyped* TIntermediate::addUniShapeConversion(TOperator op, const TType& type, TIntermTyped* node) TIntermTyped* TIntermediate::addUniShapeConversion(TOperator op, const TType& type, TIntermTyped* node)
{ {
// some source languages don't do this // some source languages don't do this
switch (source) { switch (getSource()) {
case EShSourceHlsl: case EShSourceHlsl:
break; break;
case EShSourceGlsl: case EShSourceGlsl:
@ -1232,7 +1232,7 @@ TIntermTyped* TIntermediate::addUniShapeConversion(TOperator op, const TType& ty
void TIntermediate::addBiShapeConversion(TOperator op, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode) void TIntermediate::addBiShapeConversion(TOperator op, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode)
{ {
// some source languages don't do this // some source languages don't do this
switch (source) { switch (getSource()) {
case EShSourceHlsl: case EShSourceHlsl:
break; break;
case EShSourceGlsl: case EShSourceGlsl:
@ -1335,7 +1335,7 @@ TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped*
// The new node that handles the conversion // The new node that handles the conversion
TOperator constructorOp = mapTypeToConstructorOp(type); TOperator constructorOp = mapTypeToConstructorOp(type);
if (source == EShSourceHlsl) { if (getSource() == EShSourceHlsl) {
// HLSL rules for scalar, vector and matrix conversions: // HLSL rules for scalar, vector and matrix conversions:
// 1) scalar can become anything, initializing every component with its value // 1) scalar can become anything, initializing every component with its value
// 2) vector and matrix can become scalar, first element is used (warning: truncation) // 2) vector and matrix can become scalar, first element is used (warning: truncation)
@ -1498,7 +1498,7 @@ bool TIntermediate::isIntegralConversion(TBasicType from, TBasicType to) const
case EbtInt: case EbtInt:
switch(to) { switch(to) {
case EbtUint: case EbtUint:
return version >= 400 || (source == EShSourceHlsl); return version >= 400 || getSource() == EShSourceHlsl;
case EbtInt64: case EbtInt64:
case EbtUint64: case EbtUint64:
return true; return true;
@ -1588,7 +1588,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
// TODO: Move more policies into language-specific handlers. // TODO: Move more policies into language-specific handlers.
// Some languages allow more general (or potentially, more specific) conversions under some conditions. // Some languages allow more general (or potentially, more specific) conversions under some conditions.
if (source == EShSourceHlsl) { if (getSource() == EShSourceHlsl) {
const bool fromConvertable = (from == EbtFloat || from == EbtDouble || from == EbtInt || from == EbtUint || from == EbtBool); const bool fromConvertable = (from == EbtFloat || from == EbtDouble || from == EbtInt || from == EbtUint || from == EbtBool);
const bool toConvertable = (to == EbtFloat || to == EbtDouble || to == EbtInt || to == EbtUint || to == EbtBool); const bool toConvertable = (to == EbtFloat || to == EbtDouble || to == EbtInt || to == EbtUint || to == EbtBool);
@ -1655,7 +1655,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
} }
// hlsl supported conversions // hlsl supported conversions
if (source == EShSourceHlsl) { if (getSource() == EShSourceHlsl) {
if (from == EbtBool && (to == EbtInt || to == EbtUint || to == EbtFloat)) if (from == EbtBool && (to == EbtInt || to == EbtUint || to == EbtFloat))
return true; return true;
} }
@ -1687,7 +1687,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
case EbtFloat: case EbtFloat:
return true; return true;
case EbtBool: case EbtBool:
return (source == EShSourceHlsl); return (getSource() == EShSourceHlsl);
#ifdef AMD_EXTENSIONS #ifdef AMD_EXTENSIONS
case EbtInt16: case EbtInt16:
case EbtUint16: case EbtUint16:
@ -1698,18 +1698,18 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
#ifdef AMD_EXTENSIONS #ifdef AMD_EXTENSIONS
extensionRequested(E_GL_AMD_gpu_shader_half_float) || extensionRequested(E_GL_AMD_gpu_shader_half_float) ||
#endif #endif
(source == EShSourceHlsl); getSource() == EShSourceHlsl;
default: default:
return false; return false;
} }
case EbtUint: case EbtUint:
switch (from) { switch (from) {
case EbtInt: case EbtInt:
return version >= 400 || (source == EShSourceHlsl); return version >= 400 || getSource() == EShSourceHlsl;
case EbtUint: case EbtUint:
return true; return true;
case EbtBool: case EbtBool:
return (source == EShSourceHlsl); return getSource() == EShSourceHlsl;
#ifdef AMD_EXTENSIONS #ifdef AMD_EXTENSIONS
case EbtInt16: case EbtInt16:
case EbtUint16: case EbtUint16:
@ -1723,7 +1723,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
case EbtInt: case EbtInt:
return true; return true;
case EbtBool: case EbtBool:
return (source == EShSourceHlsl); return getSource() == EShSourceHlsl;
#ifdef AMD_EXTENSIONS #ifdef AMD_EXTENSIONS
case EbtInt16: case EbtInt16:
return extensionRequested(E_GL_AMD_gpu_shader_int16); return extensionRequested(E_GL_AMD_gpu_shader_int16);
@ -1901,7 +1901,7 @@ std::tuple<TBasicType, TBasicType> TIntermediate::getConversionDestinatonType(TB
if (profile == EEsProfile || version == 110) if (profile == EEsProfile || version == 110)
return std::make_tuple(res0, res1);; return std::make_tuple(res0, res1);;
if (source == EShSourceHlsl) { if (getSource() == EShSourceHlsl) {
if (canImplicitlyPromote(type1, type0, op)) { if (canImplicitlyPromote(type1, type0, op)) {
res0 = type0; res0 = type0;
res1 = type0; res1 = type0;

View File

@ -574,6 +574,7 @@ void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TStrin
selector.push_back(0); selector.push_back(0);
} }
#ifdef ENABLE_HLSL
// //
// Make the passed-in variable information become a member of the // Make the passed-in variable information become a member of the
// global uniform block. If this doesn't exist yet, make it. // global uniform block. If this doesn't exist yet, make it.
@ -618,6 +619,7 @@ void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& mem
++firstNewMember; ++firstNewMember;
} }
#endif
void TParseContextBase::finish() void TParseContextBase::finish()
{ {

View File

@ -150,8 +150,10 @@ public:
extensionCallback(line, extension, behavior); extensionCallback(line, extension, behavior);
} }
#ifdef ENABLE_HLSL
// Manage the global uniform block (default uniforms in GLSL, $Global in HLSL) // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr); virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
#endif
// Potentially rename shader entry point function // Potentially rename shader entry point function
void renameShaderFunction(TString*& name) const void renameShaderFunction(TString*& name) const

View File

@ -833,13 +833,16 @@ bool ProcessDeferred(
// Get all the stages, languages, clients, and other environment // Get all the stages, languages, clients, and other environment
// stuff sorted out. // stuff sorted out.
EShSource source = (messages & EShMsgReadHlsl) != 0 ? EShSourceHlsl : EShSourceGlsl; EShSource sourceGuess = (messages & EShMsgReadHlsl) != 0 ? EShSourceHlsl : EShSourceGlsl;
SpvVersion spvVersion; SpvVersion spvVersion;
EShLanguage stage = compiler->getLanguage(); EShLanguage stage = compiler->getLanguage();
TranslateEnvironment(environment, messages, source, stage, spvVersion); TranslateEnvironment(environment, messages, sourceGuess, stage, spvVersion);
#ifdef ENABLE_HLSL #ifdef ENABLE_HLSL
EShSource source = sourceGuess;
if (environment != nullptr && environment->target.hlslFunctionality1) if (environment != nullptr && environment->target.hlslFunctionality1)
intermediate.setHlslFunctionality1(); intermediate.setHlslFunctionality1();
#else
const EShSource source = EShSourceGlsl;
#endif #endif
// First, without using the preprocessor or parser, find the #version, so we know what // First, without using the preprocessor or parser, find the #version, so we know what
// symbol tables, processing rules, etc. to set up. This does not need the extra strings // symbol tables, processing rules, etc. to set up. This does not need the extra strings

View File

@ -943,6 +943,7 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase {
} }
}; };
#ifdef ENABLE_HLSL
/******************************************************************************** /********************************************************************************
The following IO resolver maps types in HLSL register space, as follows: The following IO resolver maps types in HLSL register space, as follows:
@ -1023,6 +1024,7 @@ struct TDefaultHlslIoResolver : public TDefaultIoResolverBase {
return ent.newBinding = -1; return ent.newBinding = -1;
} }
}; };
#endif
// Map I/O variables to provided offsets, and make bindings for // Map I/O variables to provided offsets, and make bindings for
// unbound but live variables. // unbound but live variables.
@ -1044,6 +1046,7 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSi
return false; return false;
// if no resolver is provided, use the default resolver with the given shifts and auto map settings // if no resolver is provided, use the default resolver with the given shifts and auto map settings
TDefaultIoResolver defaultResolver(intermediate); TDefaultIoResolver defaultResolver(intermediate);
#ifdef ENABLE_HLSL
TDefaultHlslIoResolver defaultHlslResolver(intermediate); TDefaultHlslIoResolver defaultHlslResolver(intermediate);
if (resolver == nullptr) { if (resolver == nullptr) {
// TODO: use a passed in IO mapper for this // TODO: use a passed in IO mapper for this
@ -1053,6 +1056,10 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSi
resolver = &defaultResolver; resolver = &defaultResolver;
} }
resolver->addStage(stage); resolver->addStage(stage);
#else
resolver = &defaultResolver;
#endif
TVarLiveMap inVarMap, outVarMap, uniformVarMap; TVarLiveMap inVarMap, outVarMap, uniformVarMap;
TVarLiveVector inVector, outVector, uniformVector; TVarLiveVector inVector, outVector, uniformVector;
TVarGatherTraverser iter_binding_all(intermediate, true, inVarMap, outVarMap, uniformVarMap); TVarGatherTraverser iter_binding_all(intermediate, true, inVarMap, outVarMap, uniformVarMap);

View File

@ -106,9 +106,9 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
if (language != unit.language) if (language != unit.language)
error(infoSink, "stages must match when linking into a single stage"); error(infoSink, "stages must match when linking into a single stage");
if (source == EShSourceNone) if (getSource() == EShSourceNone)
source = unit.source; setSource(unit.getSource());
if (source != unit.source) if (getSource() != unit.getSource())
error(infoSink, "can't link compilation units from different source languages"); error(infoSink, "can't link compilation units from different source languages");
if (treeRoot == nullptr) { if (treeRoot == nullptr) {
@ -609,7 +609,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
return; return;
if (numEntryPoints < 1) { if (numEntryPoints < 1) {
if (source == EShSourceGlsl) if (getSource() == EShSourceGlsl)
error(infoSink, "Missing entry point: Each stage requires one entry point"); error(infoSink, "Missing entry point: Each stage requires one entry point");
else else
warn(infoSink, "Entry point not found"); warn(infoSink, "Entry point not found");
@ -704,7 +704,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
error(infoSink, "At least one shader must specify an output layout(vertices=...)"); error(infoSink, "At least one shader must specify an output layout(vertices=...)");
break; break;
case EShLangTessEvaluation: case EShLangTessEvaluation:
if (source == EShSourceGlsl) { if (getSource() == EShSourceGlsl) {
if (inputPrimitive == ElgNone) if (inputPrimitive == ElgNone)
error(infoSink, "At least one shader must specify an input layout primitive"); error(infoSink, "At least one shader must specify an input layout primitive");
if (vertexSpacing == EvsNone) if (vertexSpacing == EvsNone)

View File

@ -235,7 +235,11 @@ class TIntermediate {
public: public:
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) :
implicitThisName("@this"), implicitCounterName("@count"), implicitThisName("@this"), implicitCounterName("@count"),
language(l), source(EShSourceNone), profile(p), version(v), treeRoot(0), language(l),
#ifdef ENABLE_HLSL
source(EShSourceNone),
#endif
profile(p), version(v), treeRoot(0),
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false), numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet), invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
inputPrimitive(ElgNone), outputPrimitive(ElgNone), inputPrimitive(ElgNone), outputPrimitive(ElgNone),
@ -285,8 +289,13 @@ public:
void output(TInfoSink&, bool tree); void output(TInfoSink&, bool tree);
void removeTree(); void removeTree();
#ifdef ENABLE_HLSL
void setSource(EShSource s) { source = s; } void setSource(EShSource s) { source = s; }
EShSource getSource() const { return source; } EShSource getSource() const { return source; }
#else
void setSource(EShSource s) { assert(s == EShSourceGlsl); }
EShSource getSource() const { return EShSourceGlsl; }
#endif
void setEntryPointName(const char* ep) void setEntryPointName(const char* ep)
{ {
entryPointName = ep; entryPointName = ep;
@ -842,7 +851,9 @@ protected:
static const char* getResourceName(TResourceType); static const char* getResourceName(TResourceType);
const EShLanguage language; // stage, known at construction time const EShLanguage language; // stage, known at construction time
#ifdef ENABLE_HLSL
EShSource source; // source language, known a bit later EShSource source; // source language, known a bit later
#endif
std::string entryPointName; std::string entryPointName;
std::string entryPointMangledName; std::string entryPointMangledName;
typedef std::list<TCall> TGraph; typedef std::list<TCall> TGraph;

View File

@ -129,9 +129,13 @@ public:
void getPreamble(std::string&); void getPreamble(std::string&);
bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; } bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; }
bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; } bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; }
#ifdef ENABLE_HLSL
bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; } bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; }
bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; } bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; }
bool hlslDX9Compatible() const { return (messages & EShMsgHlslDX9Compatible) != 0; } bool hlslDX9Compatible() const { return (messages & EShMsgHlslDX9Compatible) != 0; }
#else
bool isReadingHLSL() const { return false; }
#endif
TInfoSink& infoSink; TInfoSink& infoSink;