summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-type-set.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-12-19 16:40:33 -0500
committerGitHub <noreply@github.com>2019-12-19 16:40:33 -0500
commit9f0e9d6ba431d8deb000b4fe6ff03c879d662f45 (patch)
treea5097a8367a767fcf8caf6476de1bebe57066b0c /source/slang/slang-ir-type-set.cpp
parente3fe0319467546bae070137c58dcf8f9fbe93c79 (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.cpp229
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());
+ }
+}
+
+}