summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-emit-cpp.h
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-12-20 14:01:33 -0500
committerGitHub <noreply@github.com>2019-12-20 14:01:33 -0500
commit79b52bb8ac2a6059f5bbdc17be22725400b74aad (patch)
tree41569fe825ecae951ff0881c11f356fb1b71dfb8 /source/slang/slang-emit-cpp.h
parent9f0e9d6ba431d8deb000b4fe6ff03c879d662f45 (diff)
HLSLIntrinsicSet (#1159)
* CPPCompiler -> DownstreamCompiler * Added DownstreamCompileResult to start abstraction such that we don't need files. * * Split out slang-blob.cpp * Made CompileResult hold a DownstreamCompileResult - for access to binary or ISlangSharedLibrary * Keep temporary files in scope. * Add a hash to the hex dump stream. * Move all file tracking into DownstreamCompiler. * WIP support for nvrtc. * WIP: Adding support for nvrtc compiler. Adding enum types, wiring up the nvrtc into slang. * Fix remaining CPPCompiler references. * Fix order issue on target string matching. * Use ISlangSharedLibrary for nvrtc. * Use DownstreamCompiler for nvrtc. * WIP first pass at compilation win nvrtc. * Added testing if file is on file system into CommandLineDownstreamCompiler. Added sourceContentsPath. * Make test cuda-compile.cu work by just compiling not comparing output. * Genearlize DownstreamCompiler usage. * Fix warning on clang. * Remove CompilerType from DownstreamCompiler. * Use DownstreamCompiler interface for all compilers. NOTE for FXC, DXC and GLSLANG this doesn't mean using 'compile' - it's still extracting functions from shared library. * Replace DownstreamCompiler::SourceType -> SlangSourceLanguage * Replace _canCompile with something data driven. * Fix compiling on gcc/clang for DownstreamCompiler. * Moved some text conversions into DownstreamCompiler. * Fix problem on non-vc builds with not having return on locateCompilers for VS. * Change so no warning for code not reachable on locateCompilers for vs. * WIP: CUDA code generation - currently just using CPU layout and HLSL. * emitXXXForEntryPoint -> emitEntryPointSource emitSourceForEntryPoint -> emitEntryPointSourceFromIR Fix up generating cuda to get PTX. * WIP emitting cuda for IR. * Small improvements to CUDA ouput. * Disable the CUDA emit test, as output not currently compilable. * Split out IRTypeSet to simplify CPPSourceEmitter and other Emitters that rely on determining unique use of type and/or need to generate types in order to output code. * First pass at HLSLIntrinsicSet. * Small improvements to HLSLIntrinsicSet. * Use HLSLIntrinsicSet in CPPSourceEmitter. * Small improvements to checking of HLSLIntrinsic construction. * Deallocate intrinsic copy if a match was found.
Diffstat (limited to 'source/slang/slang-emit-cpp.h')
-rw-r--r--source/slang/slang-emit-cpp.h213
1 files changed, 26 insertions, 187 deletions
diff --git a/source/slang/slang-emit-cpp.h b/source/slang/slang-emit-cpp.h
index ffe4a1544..45a9ee35a 100644
--- a/source/slang/slang-emit-cpp.h
+++ b/source/slang/slang-emit-cpp.h
@@ -6,135 +6,18 @@
#include "slang-ir-clone.h"
#include "slang-ir-type-set.h"
+#include "slang-hlsl-intrinsic-set.h"
#include "../core/slang-string-slice-pool.h"
namespace Slang
{
-/* TODO(JS): Note that there are multiple methods to handle 'construction' operations. That is because 'construct' is used as a kind of
-generic 'construction' for built in types including vectors and matrices.
-
-For the moment the cpp emit code, determines what kind of construct is needed, and has special handling for ConstructConvert and
-ConstructFromScalar.
-
-That currently we do not see constructVectorFromScalar - for example when we do...
-
-int2 fromScalar = 1;
-
-This appears as a construction from an int.
-
-That the better thing to do would be that there were IR instructions for the specific types of construction. I suppose there is a question
-about whether there should be separate instructions for vector/matrix, or emit code should just use the destination type. In practice I think
-it's fine that there isn't an instruction separating vector/matrix. That being the case I guess we arguably don't need constructVectorFromScalar,
-just constructXXXFromScalar. Would be good if there was a suitable name to encompass vector/matrix.
-*/
-
-#define SLANG_CPP_INTRINSIC_OP(x) \
- x(Invalid, "", -1) \
- x(Init, "", -1) \
- \
- x(Mul, "*", 2) \
- x(Div, "/", 2) \
- x(Add, "+", 2) \
- x(Sub, "-", 2) \
- x(Lsh, "<<", 2) \
- x(Rsh, ">>", 2) \
- x(IRem, "%", 2) \
- x(FRem, "remainder", 2) \
- \
- x(Eql, "==", 2) \
- x(Neq, "!=", 2) \
- x(Greater, ">", 2) \
- x(Less, "<", 2) \
- x(Geq, ">=", 2) \
- x(Leq, "<=", 2) \
- \
- x(BitAnd, "&", 2) \
- x(BitXor, "^", 2) \
- x(BitOr, "|" , 2) \
- \
- x(And, "&&", 2) \
- x(Or, "||", 2) \
- \
- x(Neg, "-", 1) \
- x(Not, "!", 1) \
- x(BitNot, "~", 1) \
- \
- x(Any, "any", 1) \
- x(All, "all", 1) \
- \
- x(Swizzle, "", -1) \
- \
- x(Dot, "dot", 2) \
- x(VecMatMul, "mul", 2) \
- \
- x(Normalize, "normalize", 1) \
- x(Length, "length", 1) \
- \
- x(Sin, "sin", 1) \
- x(Cos, "cos", 1) \
- x(Tan, "tan", 1) \
- \
- x(ArcSin, "asin", 1) \
- x(ArcCos, "acos", 1) \
- x(ArcTan, "atan", 1) \
- \
- x(ArcTan2, "atan2", 2) \
- x(SinCos, "sincos", 3) \
- \
- x(Rcp, "rcp", 1) \
- x(Sign, "sign", 1) \
- x(Saturate, "saturate", 1) \
- x(Frac, "frac", 1) \
- \
- x(Ceil, "ceil", 1) \
- x(Floor, "floor", 1) \
- x(Trunc, "trunc", 1) \
- \
- x(Sqrt, "sqrt", 1) \
- x(RecipSqrt, "rsqrt", 1) \
- \
- x(Exp2, "exp2", 1) \
- x(Exp, "exp", 1) \
- \
- x(Abs, "abs", 1) \
- \
- x(Min, "min", 2) \
- x(Max, "max", 2) \
- x(Pow, "pow", 2) \
- x(FMod, "fmod", 2) \
- x(Cross, "cross", 2) \
- x(Reflect, "reflect", 2) \
- \
- x(SmoothStep, "smoothstep", 3) \
- x(Lerp, "lerp", 3) \
- x(Clamp, "clamp", 3) \
- x(Step, "step", 2) \
- \
- x(AsFloat, "asfloat", 1) \
- x(AsInt, "asint", -1) \
- x(AsUInt, "asuint", -1) \
- x(AsDouble, "asdouble", 2) \
- \
- x(ConstructConvert, "", 1) \
- x(ConstructFromScalar, "", 1) \
- \
- x(GetAt, "", 2) \
- x(SetAt, "", 3)
-
-
class CPPSourceEmitter: public CLikeSourceEmitter
{
public:
typedef CLikeSourceEmitter Super;
-#define SLANG_CPP_INTRINSIC_OP_ENUM(x, op, numOperands) x,
- enum class IntrinsicOp
- {
- SLANG_CPP_INTRINSIC_OP(SLANG_CPP_INTRINSIC_OP_ENUM)
- };
-
typedef uint32_t SemanticUsedFlags;
struct SemanticUsedFlag
{
@@ -146,42 +29,6 @@ public:
};
};
- struct OperationInfo
- {
- UnownedStringSlice name;
- UnownedStringSlice funcName;
- int8_t numOperands; ///< -1 if can't be handled automatically via amount of params
- };
-
- struct SpecializedIntrinsic
- {
- typedef SpecializedIntrinsic ThisType;
-
- UInt GetHashCode() const { return combineHash(int(op), Slang::GetHashCode(signatureType)); }
-
- bool operator==(const ThisType& rhs) const { return op == rhs.op && returnType == rhs.returnType && signatureType == rhs.signatureType; }
- bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
-
- bool isScalar() const
- {
- int paramCount = int(signatureType->getParamCount());
- for (int i = 0; i < paramCount; ++i)
- {
- IRType* paramType = signatureType->getParamType(i);
- // If any are vec or matrix, then we
- if (paramType->op == kIROp_MatrixType || paramType->op == kIROp_VectorType)
- {
- return false;
- }
- }
- return true;
- }
-
- IntrinsicOp op;
- IRType* returnType;
- IRFuncType* signatureType; // Same as funcType, but has return type of void
- };
-
struct TypeDimension
{
bool isScalar() const { return rowCount <= 1 && colCount <= 1; }
@@ -190,22 +37,13 @@ public:
int colCount;
};
- virtual SpecializedIntrinsic getSpecializedOperation(IntrinsicOp op, IRType*const* argTypes, int argTypesCount, IRType* retType);
virtual void useType(IRType* type);
- virtual void emitCall(const SpecializedIntrinsic& specOp, IRInst* inst, const IRUse* operands, int numOperands, const EmitOpInfo& inOuterPrec);
+ virtual void emitCall(const HLSLIntrinsic* specOp, IRInst* inst, const IRUse* operands, int numOperands, const EmitOpInfo& inOuterPrec);
virtual void emitTypeDefinition(IRType* type);
- virtual void emitSpecializedOperationDefinition(const SpecializedIntrinsic& specOp);
+ virtual void emitSpecializedOperationDefinition(const HLSLIntrinsic* specOp);
- void emitOperationCall(IntrinsicOp op, IRInst* inst, IRUse* operands, int operandCount, IRType* retType, const EmitOpInfo& inOuterPrec);
-
static UnownedStringSlice getBuiltinTypeName(IROp op);
-
- static const OperationInfo& getOperationInfo(IntrinsicOp op);
-
- static IntrinsicOp getOperation(IROp op);
-
- IntrinsicOp getOperationByName(const UnownedStringSlice& slice);
-
+
SourceWriter* getSourceWriter() const { return m_writer; }
CPPSourceEmitter(const Desc& desc);
@@ -233,34 +71,34 @@ protected:
IRTargetIntrinsicDecoration* targetIntrinsic,
EmitOpInfo const& inOuterPrec);
- void _emitVecMatMulDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp);
+ void _emitVecMatMulDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp);
- void _emitAryDefinition(const SpecializedIntrinsic& specOp);
+ void _emitAryDefinition(const HLSLIntrinsic* specOp);
// Really we don't want any of these defined like they are here, they should be defined in slang stdlib
- void _emitAnyAllDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp);
- void _emitCrossDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp);
- void _emitLengthDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp);
- void _emitNormalizeDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp);
- void _emitReflectDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp);
- void _emitConstructConvertDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp);
- void _emitConstructFromScalarDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp);
- void _emitGetAtDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp);
+ void _emitAnyAllDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp);
+ void _emitCrossDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp);
+ void _emitLengthDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp);
+ void _emitNormalizeDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp);
+ void _emitReflectDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp);
+ void _emitConstructConvertDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp);
+ void _emitConstructFromScalarDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp);
+ void _emitGetAtDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp);
- void _emitSignature(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp);
+ void _emitSignature(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp);
void _emitInOutParamType(IRType* type, String const& name, IRType* valueType);
- UnownedStringSlice _getAndEmitSpecializedOperationDefinition(IntrinsicOp op, IRType*const* argTypes, Int argCount, IRType* retType);
+ UnownedStringSlice _getAndEmitSpecializedOperationDefinition(HLSLIntrinsic::Op op, IRType*const* argTypes, Int argCount, IRType* retType);
static TypeDimension _getTypeDimension(IRType* type, bool vecSwap);
static void _emitAccess(const UnownedStringSlice& name, const TypeDimension& dimension, int row, int col, SourceWriter* writer);
- StringSlicePool::Handle _calcScalarFuncName(IntrinsicOp op, IRBasicType* type);
- UnownedStringSlice _getScalarFuncName(IntrinsicOp operation, IRBasicType* scalarType);
+ StringSlicePool::Handle _calcScalarFuncName(HLSLIntrinsic::Op, IRBasicType* type);
+ UnownedStringSlice _getScalarFuncName(HLSLIntrinsic::Op operation, IRBasicType* scalarType);
- UnownedStringSlice _getFuncName(const SpecializedIntrinsic& specOp);
- StringSlicePool::Handle _calcFuncName(const SpecializedIntrinsic& specOp);
+ UnownedStringSlice _getFuncName(const HLSLIntrinsic* specOp);
+ StringSlicePool::Handle _calcFuncName(const HLSLIntrinsic* specOp);
UnownedStringSlice _getTypeName(IRType* type);
StringSlicePool::Handle _calcTypeName(IRType* type);
@@ -276,16 +114,17 @@ protected:
void _emitInitAxisValues(const Int sizeAlongAxis[kThreadGroupAxisCount], const UnownedStringSlice& mulName, const UnownedStringSlice& addName);
- Dictionary<SpecializedIntrinsic, StringSlicePool::Handle> m_intrinsicNameMap;
+ bool _tryEmitInstExprAsIntrinsic(IRInst* inst, const EmitOpInfo& inOuterPrec);
+
Dictionary<IRType*, StringSlicePool::Handle> m_typeNameMap;
+ Dictionary<const HLSLIntrinsic*, StringSlicePool::Handle> m_intrinsicNameMap;
IRTypeSet m_typeSet;
+ RefPtr<HLSLIntrinsicOpLookup> m_opLookup;
+ HLSLIntrinsicSet m_intrinsicSet;
Dictionary<IRType*, bool> m_typeEmittedMap;
- Dictionary<SpecializedIntrinsic, bool> m_intrinsicEmittedMap;
-
- // Maps from a name (in the form of a handle/index from m_slicePool) to an operation
- List<IntrinsicOp> m_intrinsicOpMap;
+ Dictionary<const HLSLIntrinsic*, bool> m_intrinsicEmittedMap;
StringSlicePool m_slicePool;