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/slang/slang-ir-type-set.cpp | |
| 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/slang/slang-ir-type-set.cpp')
| -rw-r--r-- | source/slang/slang-ir-type-set.cpp | 229 |
1 files changed, 229 insertions, 0 deletions
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()); + } +} + +} |
