diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2019-12-19 16:40:33 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-12-19 16:40:33 -0500 |
| commit | 9f0e9d6ba431d8deb000b4fe6ff03c879d662f45 (patch) | |
| tree | a5097a8367a767fcf8caf6476de1bebe57066b0c /source | |
| parent | e3fe0319467546bae070137c58dcf8f9fbe93c79 (diff) | |
Split out IRTypeSet (#1158)
* 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.
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-emit-cpp.cpp | 157 | ||||
| -rw-r--r-- | source/slang/slang-emit-cpp.h | 33 | ||||
| -rw-r--r-- | source/slang/slang-ir-type-set.cpp | 229 | ||||
| -rw-r--r-- | source/slang/slang-ir-type-set.h | 84 | ||||
| -rw-r--r-- | source/slang/slang.vcxproj | 2 | ||||
| -rw-r--r-- | source/slang/slang.vcxproj.filters | 6 |
6 files changed, 344 insertions, 167 deletions
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp index e7f11fc92..46eeee5bd 100644 --- a/source/slang/slang-emit-cpp.cpp +++ b/source/slang/slang-emit-cpp.cpp @@ -265,13 +265,13 @@ void CPPSourceEmitter::emitTypeDefinition(IRType* inType) return; } - IRType* type = _cloneType(inType); + IRType* type = m_typeSet.getType(inType); if (m_typeEmittedMap.TryGetValue(type)) { return; } - if (type->getModule() != m_uniqueModule) + if (!m_typeSet.isOwned(type)) { // If defined in a different module, we assume they are emitted already. (Assumed to // be a nominal type) @@ -322,7 +322,7 @@ void CPPSourceEmitter::emitTypeDefinition(IRType* inType) const auto rowCount = int(GetIntVal(matType->getRowCount())); const auto colCount = int(GetIntVal(matType->getColumnCount())); - IRType* vecType = _getVecType(matType->getElementType(), colCount); + IRType* vecType = m_typeSet.addVectorType(matType->getElementType(), colCount); emitTypeDefinition(vecType); UnownedStringSlice typeName = _getTypeName(type); @@ -373,7 +373,7 @@ void CPPSourceEmitter::emitTypeDefinition(IRType* inType) UnownedStringSlice CPPSourceEmitter::_getTypeName(IRType* inType) { - IRType* type = _cloneType(inType); + IRType* type = m_typeSet.getType(inType); StringSlicePool::Handle handle = StringSlicePool::kNullHandle; if (m_typeNameMap.TryGetValue(type, handle)) @@ -390,7 +390,7 @@ UnownedStringSlice CPPSourceEmitter::_getTypeName(IRType* inType) const auto colCount = int(GetIntVal(matType->getColumnCount())); // Make sure the vector type the matrix is built on is added - useType(_getVecType(elementType, colCount)); + useType(m_typeSet.addVectorType(elementType, colCount)); } StringBuilder builder; @@ -631,115 +631,6 @@ void CPPSourceEmitter::useType(IRType* type) _getTypeName(type); } -IRInst* CPPSourceEmitter::_clone(IRInst* inst) -{ - if (inst == nullptr) - { - return nullptr; - } - - IRModule* module = inst->getModule(); - // All inst's must belong to a module - SLANG_ASSERT(module); - - // If it's in this module then we don't need to clone - if (module == m_uniqueModule) - { - return inst; - } - - if (IRInst*const* newInstPtr = m_cloneMap.TryGetValue(inst)) - { - return *newInstPtr; - } - - if (isNominalOp(inst->op)) - { - // TODO(JS) - // This is arguably problematic - I'm adding an instruction from another module to the map, to be it's self. - // I did have code which created a copy of the nominal instruction and name hint, but because nominality means - // 'same address' other code would generate a different name for that instruction (say as compared to being a member in - // the original instruction) - // - // Because I use findOrAddInst which doesn't hoist instructions, the hoisting doesn't rely on parenting, that would - // break. - - // If nominal, we just use the original inst - m_cloneMap.Add(inst, inst); - return inst; - } - - // It would be nice if I could use ir-clone.cpp to do this -> but it doesn't clone - // operands. We wouldn't want to clone decorations, and it can't clone IRConstant(!) so - // it's no use - - IRInst* clone = nullptr; - switch (inst->op) - { - case kIROp_IntLit: - { - auto intLit = static_cast<IRConstant*>(inst); - IRType* cloneType = _cloneType(intLit->getDataType()); - clone = m_irBuilder.getIntValue(cloneType, intLit->value.intVal); - break; - } - case kIROp_StringLit: - { - auto stringLit = static_cast<IRStringLit*>(inst); - clone = m_irBuilder.getStringValue(stringLit->getStringSlice()); - break; - } - default: - { - if (IRBasicType::isaImpl(inst->op)) - { - clone = m_irBuilder.getType(inst->op); - } - else - { - IRType* irType = dynamicCast<IRType>(inst); - if (irType) - { - auto cloneType = _cloneType(inst->getFullType()); - Index operandCount = Index(inst->getOperandCount()); - - List<IRInst*> cloneOperands; - cloneOperands.setCount(operandCount); - - for (Index i = 0; i < operandCount; ++i) - { - cloneOperands[i] = _clone(inst->getOperand(i)); - } - - //clone = m_irBuilder.findOrEmitHoistableInst(cloneType, inst->op, operandCount, cloneOperands.getBuffer()); - - UInt operandCounts[1] = { UInt(operandCount) }; - IRInst*const* listOperands[1] = { cloneOperands.getBuffer() }; - - clone = m_irBuilder.findOrAddInst(cloneType, inst->op, 1, operandCounts, listOperands); - } - else - { - // This cloning style only works on insts that are not unique - auto cloneType = _cloneType(inst->getFullType()); - - Index operandCount = Index(inst->getOperandCount()); - clone = m_irBuilder.emitIntrinsicInst(cloneType, inst->op, operandCount, nullptr); - for (Index i = 0; i < operandCount; ++i) - { - auto cloneOperand = _clone(inst->getOperand(i)); - clone->getOperands()[i].init(clone, cloneOperand); - } - } - } - break; - } - } - - m_cloneMap.Add(inst, clone); - return clone; -} - static IRBasicType* _getElementType(IRType* type) { switch (type->op) @@ -1102,10 +993,13 @@ void CPPSourceEmitter::_emitCrossDefinition(const UnownedStringSlice& funcName, UnownedStringSlice CPPSourceEmitter::_getAndEmitSpecializedOperationDefinition(IntrinsicOp op, IRType*const* argTypes, Int argCount, IRType* retType) { + // Use the type sets builder... + IRBuilder& builder = m_typeSet.getBuilder(); + SpecializedIntrinsic specOp; specOp.op = op; specOp.returnType = retType; - specOp.signatureType = m_irBuilder.getFuncType(argCount, argTypes, m_irBuilder.getVoidType()); + specOp.signatureType = builder.getFuncType(argCount, argTypes, builder.getVoidType()); emitSpecializedOperationDefinition(specOp); return _getFuncName(specOp); @@ -1443,12 +1337,6 @@ void CPPSourceEmitter::emitSpecializedOperationDefinition(const SpecializedIntri SLANG_ASSERT(!"Unhandled"); } -IRType* CPPSourceEmitter::_getVecType(IRType* elementType, int elementCount) -{ - elementType = _cloneType(elementType); - return m_irBuilder.getVectorType(elementType, m_irBuilder.getIntValue(m_irBuilder.getIntType(), elementCount)); -} - CPPSourceEmitter::SpecializedIntrinsic CPPSourceEmitter::getSpecializedOperation(IntrinsicOp op, IRType*const* inArgTypes, int argTypesCount, IRType* retType) { SpecializedIntrinsic specOp; @@ -1459,11 +1347,14 @@ CPPSourceEmitter::SpecializedIntrinsic CPPSourceEmitter::getSpecializedOperation for (int i = 0; i < argTypesCount; ++i) { - argTypes[i] = _cloneType(inArgTypes[i]->getCanonicalType()); + argTypes[i] = m_typeSet.getType(inArgTypes[i]->getCanonicalType()); } - specOp.returnType = _cloneType(retType); - specOp.signatureType = m_irBuilder.getFuncType(argTypes, m_irBuilder.getBasicType(BaseType::Void)); + specOp.returnType = m_typeSet.getType(retType); + + // Use the typesets builder + IRBuilder& builder = m_typeSet.getBuilder(); + specOp.signatureType = builder.getFuncType(argTypes, builder.getBasicType(BaseType::Void)); return specOp; } @@ -1786,21 +1677,12 @@ void CPPSourceEmitter::emitOperationCall(IntrinsicOp op, IRInst* inst, IRUse* op CPPSourceEmitter::CPPSourceEmitter(const Desc& desc): Super(desc), - m_slicePool(StringSlicePool::Style::Default) + m_slicePool(StringSlicePool::Style::Default), + m_typeSet(desc.compileRequest->getSession()) { m_semanticUsedFlags = 0; //m_semanticUsedFlags = SemanticUsedFlag::GroupID | SemanticUsedFlag::GroupThreadID | SemanticUsedFlag::DispatchThreadID; - m_sharedIRBuilder.module = nullptr; - m_sharedIRBuilder.session = desc.compileRequest->getSession(); - - m_irBuilder.sharedBuilder = &m_sharedIRBuilder; - - m_uniqueModule = m_irBuilder.createModule(); - m_sharedIRBuilder.module = m_uniqueModule; - - m_irBuilder.setInsertInto(m_irBuilder.getModule()->getModuleInst()); - // Add all the operations with names (not ops like -, / etc) to the lookup map for (int i = 0; i < SLANG_COUNT_OF(s_operationInfos); ++i) { @@ -2028,13 +1910,12 @@ void CPPSourceEmitter::emitSimpleValueImpl(IRInst* inst) void CPPSourceEmitter::emitVectorTypeNameImpl(IRType* elementType, IRIntegerValue elementCount) { - emitSimpleType(_getVecType(elementType, int(elementCount))); + emitSimpleType(m_typeSet.addVectorType(elementType, int(elementCount))); } void CPPSourceEmitter::emitSimpleTypeImpl(IRType* inType) { - - UnownedStringSlice slice = _getTypeName(_cloneType(inType)); + UnownedStringSlice slice = _getTypeName(m_typeSet.getType(inType)); m_writer->emit(slice); } diff --git a/source/slang/slang-emit-cpp.h b/source/slang/slang-emit-cpp.h index fdc283574..ffe4a1544 100644 --- a/source/slang/slang-emit-cpp.h +++ b/source/slang/slang-emit-cpp.h @@ -5,6 +5,8 @@ #include "slang-emit-c-like.h" #include "slang-ir-clone.h" +#include "slang-ir-type-set.h" + #include "../core/slang-string-slice-pool.h" namespace Slang @@ -254,11 +256,6 @@ protected: static TypeDimension _getTypeDimension(IRType* type, bool vecSwap); static void _emitAccess(const UnownedStringSlice& name, const TypeDimension& dimension, int row, int col, SourceWriter* writer); - IRType* _getVecType(IRType* elementType, int elementCount); - - IRInst* _clone(IRInst* inst); - IRType* _cloneType(IRType* type) { return (IRType*)_clone((IRInst*)type); } - StringSlicePool::Handle _calcScalarFuncName(IntrinsicOp op, IRBasicType* type); UnownedStringSlice _getScalarFuncName(IntrinsicOp operation, IRBasicType* scalarType); @@ -282,30 +279,8 @@ protected: Dictionary<SpecializedIntrinsic, StringSlicePool::Handle> m_intrinsicNameMap; Dictionary<IRType*, StringSlicePool::Handle> m_typeNameMap; - /* This is used so as to try and use slangs type system to uniquely identify types and specializations on intrinsic. - That we want to have a pointer to a type be unique, and slang supports this through the m_sharedIRBuilder. BUT for this to - work all work on the module must use the same sharedIRBuilder, and that appears to not be the case in terms - of other passes. - Even if it was the case when we may want to add types as part of emitting, we can't use the previously used - shared builder, so again we end up with pointers to the same things not being the same thing. - - To work around this we clone types we want to use as keys into the 'unique module'. - This is not necessary for all types though - as we assume nominal types *must* have unique pointers (that is the - definition of nominal). - - This could be handled in other ways (for example not testing equality on pointer equality). Anyway for now this - works, but probably needs to be handled in a better way. The better way may involve having guarantees about equality - enabled in other code generation and making de-duping possible in emit code. - - Note that one pro for this approach is that it does not alter the source module. That as it stands it's not necessary - for the source module to be immutable, because it is created for emitting and then discarded. - */ - RefPtr<IRModule> m_uniqueModule; - SharedIRBuilder m_sharedIRBuilder; - IRBuilder m_irBuilder; - - Dictionary<IRInst*, IRInst*> m_cloneMap; - + IRTypeSet m_typeSet; + Dictionary<IRType*, bool> m_typeEmittedMap; Dictionary<SpecializedIntrinsic, bool> m_intrinsicEmittedMap; diff --git a/source/slang/slang-ir-type-set.cpp b/source/slang/slang-ir-type-set.cpp new file mode 100644 index 000000000..7beeaced4 --- /dev/null +++ b/source/slang/slang-ir-type-set.cpp @@ -0,0 +1,229 @@ +// slang-ir-type-set.cpp +#include "slang-ir-type-set.h" + +#include "slang-ir.h" +#include "slang-ir-insts.h" + +namespace Slang +{ + +IRTypeSet::IRTypeSet(Session* session) +{ + m_sharedBuilder.module = nullptr; + m_sharedBuilder.session = session; + + m_builder.sharedBuilder = &m_sharedBuilder; + + m_module = m_builder.createModule(); + + m_sharedBuilder.module = m_module; + + m_builder.setInsertInto(m_module->getModuleInst()); +} + +IRTypeSet::~IRTypeSet() +{ + List<IRType*> types; + getTypes(types); + + for (auto type : types) + { + // We need to destroy references to instructions in other modules + if (type->getModule() == m_module) + { + // We want to remove arguments because an argument *could* be an instruction in another module, + // and we don't want to those modules insts to have uses, in this module which is being destroyed + type->removeArguments(); + } + } +} + +IRInst* IRTypeSet::cloneInst(IRInst* inst) +{ + if (inst == nullptr) + { + return nullptr; + } + + // See if it's already cloned + if (IRInst*const* newInstPtr = m_cloneMap.TryGetValue(inst)) + { + return *newInstPtr; + } + + IRModule* module = inst->getModule(); + // All inst's must belong to a module + SLANG_ASSERT(module); + + // If it's in this module then we don't need to clone + if (module == m_module) + { + return inst; + } + + if (isNominalOp(inst->op)) + { + // We can clone without any definition, and add the linkage + + // TODO(JS) + // This is arguably problematic - I'm adding an instruction from another module to the map, to be it's self. + // I did have code which created a copy of the nominal instruction and name hint, but because nominality means + // 'same address' other code would generate a different name for that instruction (say as compared to being a member in + // the original instruction) + // + // Because I use findOrAddInst which doesn't hoist instructions, the hoisting doesn't rely on parenting, that would + // break. + + // If nominal, we just use the original inst + m_cloneMap.Add(inst, inst); + return inst; + } + + // It would be nice if I could use ir-clone.cpp to do this -> but it doesn't clone + // operands. We wouldn't want to clone decorations, and it can't clone IRConstant(!) so + // it's no use + + IRInst* clone = nullptr; + switch (inst->op) + { + case kIROp_IntLit: + { + auto intLit = static_cast<IRConstant*>(inst); + IRType* clonedType = cloneType(intLit->getDataType()); + clone = m_builder.getIntValue(clonedType, intLit->value.intVal); + break; + } + case kIROp_StringLit: + { + auto stringLit = static_cast<IRStringLit*>(inst); + clone = m_builder.getStringValue(stringLit->getStringSlice()); + break; + } + default: + { + if (IRBasicType::isaImpl(inst->op)) + { + clone = m_builder.getType(inst->op); + } + else + { + IRType* irType = dynamicCast<IRType>(inst); + if (irType) + { + auto clonedType = cloneType(inst->getFullType()); + Index operandCount = Index(inst->getOperandCount()); + + List<IRInst*> cloneOperands; + cloneOperands.setCount(operandCount); + + for (Index i = 0; i < operandCount; ++i) + { + cloneOperands[i] = cloneInst(inst->getOperand(i)); + } + + //clone = m_irBuilder.findOrEmitHoistableInst(cloneType, inst->op, operandCount, cloneOperands.getBuffer()); + + UInt operandCounts[1] = { UInt(operandCount) }; + IRInst*const* listOperands[1] = { cloneOperands.getBuffer() }; + + clone = m_builder.findOrAddInst(clonedType, inst->op, 1, operandCounts, listOperands); + } + else + { + // This cloning style only works on insts that are not unique + auto clonedType = cloneType(inst->getFullType()); + + Index operandCount = Index(inst->getOperandCount()); + clone = m_builder.emitIntrinsicInst(clonedType, inst->op, operandCount, nullptr); + for (Index i = 0; i < operandCount; ++i) + { + auto cloneOperand = cloneInst(inst->getOperand(i)); + clone->getOperands()[i].init(clone, cloneOperand); + } + } + } + break; + } + } + + m_cloneMap.Add(inst, clone); + return clone; +} + +IRType* IRTypeSet::add(IRType* irType) +{ + if (irType->getModule() == m_module) + { + return irType; + } + // We need to clone the type + return cloneType(irType); +} + +void IRTypeSet::getTypes(List<IRType*>& outTypes) const +{ + outTypes.clear(); + for (auto inst : m_module->getModuleInst()->getChildren()) + { + if (IRType* type = as<IRType>(inst)) + { + outTypes.add(type); + } + } +} + +void IRTypeSet::getTypes(Kind kind, List<IRType*>& outTypes) const +{ + outTypes.clear(); + + for (auto inst : m_module->getModuleInst()->getChildren()) + { + IRType* type = nullptr; + + switch (kind) + { + case Kind::Scalar: + { + type = as<IRBasicType>(inst); + break; + } + case Kind::Vector: + { + type = as<IRVectorType>(inst); + break; + } + case Kind::Matrix: + { + type = as<IRMatrixType>(inst); + break; + } + default: break; + } + + if (type) + { + outTypes.add(type); + } + } +} + +IRType* IRTypeSet::addVectorType(IRType* inElementType, int colsCount) +{ + IRType* elementType = cloneType(inElementType); + return m_builder.getVectorType(elementType, m_builder.getIntValue(m_builder.getIntType(), colsCount)); +} + +void IRTypeSet::addVectorForMatrixTypes() +{ + // Make a copy so we can alter m_types dictionary + List<IRType*> types; + getTypes(Kind::Matrix, types); + for (IRType* type : types) + { + SLANG_ASSERT(as<IRMatrixType>(type)); + IRMatrixType* matType = static_cast<IRMatrixType*>(type); + m_builder.getVectorType(matType->getElementType(), matType->getColumnCount()); + } +} + +} diff --git a/source/slang/slang-ir-type-set.h b/source/slang/slang-ir-type-set.h new file mode 100644 index 000000000..016513258 --- /dev/null +++ b/source/slang/slang-ir-type-set.h @@ -0,0 +1,84 @@ +// slang-ir-type-set.h +#pragma once + +#include "slang-ir.h" +#include "slang-ir-insts.h" + +#include "../core/slang-string-slice-pool.h" + +namespace Slang +{ + +/* +NOTE! This type set is only designed to work for emitting code to determine unique types. It is envisaged in the +future that it will not be needed because types will be made unique within a module, and thus the pointer to a type +will uniquely identify the type. + +The other reason this type exists, is to allow an IRModule for emit to be immutable. That is not currently possible +within emit code because it may be necessary in order to emit to be able to create other types that needed (for example +vector types required for a matrix type implementation). + +This is used so as to try and use slangs type system to uniquely identify types and specializations on intrinsic. +That we want to have a pointer to a type be unique, and slang supports this through the m_sharedIRBuilder. BUT for this to +work all work on the module must use the same sharedIRBuilder, and that appears to not be the case in terms +of other passes. +Even if it was the case when we may want to add types as part of emitting, we can't use the previously used +shared builder, so again we end up with pointers to the same things not being the same thing. + +To work around this we clone types we want to use as keys into the 'unique module'. +This is not necessary for all types though - as we assume nominal types *must* have unique pointers (that is the +definition of nominal). + +This could be handled in other ways (for example not testing equality on pointer equality). Anyway for now this +works, but probably needs to be handled in a better way. The better way may involve having guarantees about equality +enabled in other code generation and making de-duping possible in emit code. + +Note that one pro for this approach is that it does not alter the source module. That as it stands it's not necessary +for the source module to be immutable, because it is created for emitting and then discarded. + */ +class IRTypeSet +{ +public: + enum class Kind + { + Scalar, + Vector, + Matrix, + CountOf, + }; + + IRType* add(IRType* type); + IRType* addVectorType(IRType* elementType, int colsCount); + + void addVectorForMatrixTypes(); + + void getTypes(List<IRType*>& outTypes) const; + void getTypes(Kind kind, List<IRType*>& outTypes) const; + + IRType* getType(IRType* type) { return cloneType(type); } + + IRType* cloneType(IRType* type) { return (IRType*)cloneInst((IRInst*)type); } + IRInst* cloneInst(IRInst* inst); + + /// Returns true if the type belongs and is created on the module owned by the set + bool isOwned(IRType* type) { return type->getModule() == m_module; } + + IRBuilder& getBuilder() { return m_builder; } + IRModule* getModule() const { return m_module; } + + IRTypeSet(Session* session); + ~IRTypeSet(); + +protected: + + // Maps insts from source modules into m_module. + // NOTE! That nominal types are not cloned, as they are identified by pointer. They are just + Dictionary<IRInst*, IRInst*> m_cloneMap; + + // Can find all types by traversing the types in the m_module + SharedIRBuilder m_sharedBuilder; + IRBuilder m_builder; + RefPtr<IRModule> m_module; +}; + +} // namespace Slang diff --git a/source/slang/slang.vcxproj b/source/slang/slang.vcxproj index e120e006f..df34de00c 100644 --- a/source/slang/slang.vcxproj +++ b/source/slang/slang.vcxproj @@ -230,6 +230,7 @@ <ClInclude Include="slang-ir-ssa.h" /> <ClInclude Include="slang-ir-string-hash.h" /> <ClInclude Include="slang-ir-strip.h" /> + <ClInclude Include="slang-ir-type-set.h" /> <ClInclude Include="slang-ir-union.h" /> <ClInclude Include="slang-ir-validate.h" /> <ClInclude Include="slang-ir.h" /> @@ -310,6 +311,7 @@ <ClCompile Include="slang-ir-ssa.cpp" /> <ClCompile Include="slang-ir-string-hash.cpp" /> <ClCompile Include="slang-ir-strip.cpp" /> + <ClCompile Include="slang-ir-type-set.cpp" /> <ClCompile Include="slang-ir-union.cpp" /> <ClCompile Include="slang-ir-validate.cpp" /> <ClCompile Include="slang-ir.cpp" /> diff --git a/source/slang/slang.vcxproj.filters b/source/slang/slang.vcxproj.filters index 1c619a3d5..6c3626a3b 100644 --- a/source/slang/slang.vcxproj.filters +++ b/source/slang/slang.vcxproj.filters @@ -141,6 +141,9 @@ <ClInclude Include="slang-ir-strip.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="slang-ir-type-set.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="slang-ir-union.h"> <Filter>Header Files</Filter> </ClInclude> @@ -377,6 +380,9 @@ <ClCompile Include="slang-ir-strip.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="slang-ir-type-set.cpp"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="slang-ir-union.cpp"> <Filter>Source Files</Filter> </ClCompile> |
