summaryrefslogtreecommitdiffstats
path: root/source/slang/emit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/emit.cpp')
-rw-r--r--source/slang/emit.cpp487
1 files changed, 344 insertions, 143 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index d4c1be706..64ac85bd4 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -93,6 +93,10 @@ struct SharedEmitContext
bool needHackSamplerForTexelFetch = false;
ExtensionUsageTracker extensionUsageTracker;
+
+ Dictionary<IRValue*, UInt> mapIRValueToID;
+
+ HashSet<Decl*> irDeclsVisited;
};
struct EmitContext
@@ -1025,6 +1029,9 @@ struct EmitVisitor
UNEXPECTED(GenericDeclRefType);
UNEXPECTED(InitializerListType);
+ UNEXPECTED(IRBasicBlockType);
+ UNEXPECTED(PtrType);
+
#undef UNEXPECTED
void visitNamedExpressionType(NamedExpressionType* type, TypeEmitArg const& arg)
@@ -1231,6 +1238,17 @@ struct EmitVisitor
EmitType(type, SourceLoc(), name, SourceLoc());
}
+ void EmitType(RefPtr<Type> type, String const& name)
+ {
+ // HACK: the rest of the code wants a `Name`,
+ // so we'll create one for a bit...
+ Name tempName;
+ tempName.text = name;
+
+ EmitType(type, SourceLoc(), &tempName, SourceLoc());
+ }
+
+
void EmitType(RefPtr<Type> type)
{
emitTypeImpl(type, nullptr);
@@ -3942,8 +3960,34 @@ emitDeclImpl(decl, nullptr);
// IR-level emit logc
- String getName(IRInst* inst)
+ UInt getID(IRValue* value)
+ {
+ auto& mapIRValueToID = context->shared->mapIRValueToID;
+
+ UInt id = 0;
+ if (mapIRValueToID.TryGetValue(value, id))
+ return id;
+
+ id = mapIRValueToID.Count() + 1;
+ mapIRValueToID.Add(value, id);
+ return id;
+ }
+
+ String getName(IRValue* inst)
{
+ switch(inst->op)
+ {
+ case kIROp_decl_ref:
+ {
+ auto irDeclRef = (IRDeclRef*) inst;
+ return getText(irDeclRef->declRef.GetName());
+ }
+ break;
+
+ default:
+ break;
+ }
+
if(auto decoration = inst->findDecoration<IRHighLevelDeclDecoration>())
{
auto decl = decoration->decl;
@@ -3957,7 +4001,7 @@ emitDeclImpl(decl, nullptr);
StringBuilder sb;
sb << "_S";
- sb << inst->id;
+ sb << getID(inst);
return sb.ProduceString();
}
@@ -4035,7 +4079,7 @@ emitDeclImpl(decl, nullptr);
}
-
+#if 0
void emitIRSimpleType(
EmitContext* context,
IRType* type)
@@ -4153,12 +4197,14 @@ emitDeclImpl(decl, nullptr);
}
}
+#endif
CodeGenTarget getTarget(EmitContext* context)
{
return context->shared->target;
}
+#if 0
void emitGLSLTypePrefix(
EmitContext* context,
IRType* type)
@@ -4194,44 +4240,9 @@ emitDeclImpl(decl, nullptr);
break;
}
}
+#endif
- void emitIRVectorType(
- EmitContext* context,
- IRVectorType* type)
- {
- switch(getTarget(context))
- {
- case CodeGenTarget::GLSL:
- // HLSL style: `<elementTypePrefix>vec<elementCount>`
- // e.g., `ivec4`
- //
- emitGLSLTypePrefix(context, type->getElementType());
- emit("vec");
- emitIRSimpleValue(context, type->getElementCount());
- break;
-
- default:
- // HLSL style: `<elementTypeName><elementCount>`
- // e.g., `int4`
- //
- emitIRSimpleType(context, type->getElementType());
- emitIRSimpleValue(context, type->getElementCount());
- break;
- }
- }
-
- void emitIRMatrixType(
- EmitContext* context,
- IRMatrixType* type)
- {
- // TODO: this is a GLSL-vs-HLSL decision point
-
- emitIRSimpleType(context, type->getElementType());
- emitIRSimpleValue(context, type->getRowCount());
- emit("x");
- emitIRSimpleValue(context, type->getColumnCount());
- }
-
+#if 0
void emitIRType(
EmitContext* context,
IRType* type,
@@ -4287,10 +4298,11 @@ emitDeclImpl(decl, nullptr);
{
emitIRType(context, type, (IRDeclaratorInfo*) nullptr);
}
+#endif
bool shouldFoldIRInstIntoUseSites(
EmitContext* context,
- IRInst* inst)
+ IRValue* inst)
{
// Certain opcodes should always be folded in
switch( inst->op )
@@ -4306,27 +4318,24 @@ emitDeclImpl(decl, nullptr);
return true;
}
- // Certain *types* will usually want to be folded in
+ // Certain *types* will usually want to be folded in,
+ // because they aren't allowed as types for temporary
+ // variables.
auto type = inst->getType();
- switch (type->op)
+ if(type->As<UniformParameterBlockType>())
{
- case kIROp_ConstantBufferType:
- case kIROp_TextureBufferType:
// TODO: we need to be careful here, because
// HLSL shader model 6 allows these as explicit
// types.
return true;
-
- case kIROp_TextureType:
+ }
+ else if(type->As<TextureTypeBase>())
+ {
// GLSL doesn't allow texture/resource types to
// be used as first-class values, so we need
// to fold them into their use sites in all cases
if(getTarget(context) == CodeGenTarget::GLSL)
return true;
- break;
-
- default:
- break;
}
// By default we will *not* fold things into their use sites.
@@ -4335,20 +4344,16 @@ emitDeclImpl(decl, nullptr);
bool isDerefBaseImplicit(
EmitContext* context,
- IRInst* inst)
+ IRValue* inst)
{
auto type = inst->getType();
- switch (type->op)
+
+ if(type->As<UniformParameterBlockType>())
{
- case kIROp_ConstantBufferType:
- case kIROp_TextureBufferType:
// TODO: we need to be careful here, because
// HLSL shader model 6 allows these as explicit
// types.
return true;
-
- default:
- break;
}
return false;
@@ -4358,7 +4363,7 @@ emitDeclImpl(decl, nullptr);
void emitIROperand(
EmitContext* context,
- IRInst* inst)
+ IRValue* inst)
{
if( shouldFoldIRInstIntoUseSites(context, inst) )
{
@@ -4380,8 +4385,8 @@ emitDeclImpl(decl, nullptr);
EmitContext* context,
IRInst* inst)
{
- UInt argCount = inst->argCount - 1;
- IRUse* args = inst->getArgs() + 1;
+ UInt argCount = inst->argCount;
+ IRUse* args = inst->getArgs();
emit("(");
for(UInt aa = 0; aa < argCount; ++aa)
@@ -4392,12 +4397,35 @@ emitDeclImpl(decl, nullptr);
emit(")");
}
+ void emitIRType(
+ EmitContext* context,
+ IRType* type,
+ String const& name)
+ {
+ EmitType(type, name);
+ }
+
+ void emitIRType(
+ EmitContext* context,
+ IRType* type,
+ Name* name)
+ {
+ EmitType(type, name);
+ }
+
+ void emitIRType(
+ EmitContext* context,
+ IRType* type)
+ {
+ EmitType(type);
+ }
+
void emitIRInstResultDecl(
EmitContext* context,
IRInst* inst)
{
auto type = inst->getType();
- if(!type || type->op == kIROp_VoidType)
+ if(!type)
return;
emitIRType(context, type, getName(inst));
@@ -4406,9 +4434,10 @@ emitDeclImpl(decl, nullptr);
void emitIRInstExpr(
EmitContext* context,
- IRInst* inst)
+ IRValue* value)
{
- switch(inst->op)
+ IRInst* inst = (IRInst*) value;
+ switch(value->op)
{
case kIROp_IntLit:
case kIROp_FloatLit:
@@ -4418,13 +4447,13 @@ emitDeclImpl(decl, nullptr);
case kIROp_Construct:
// Simple constructor call
- if( inst->getArgCount() == 2 && getTarget(context) == CodeGenTarget::HLSL)
+ if( inst->getArgCount() == 1 && getTarget(context) == CodeGenTarget::HLSL)
{
// Need to emit as cast for HLSL
emit("(");
emitIRType(context, inst->getType());
emit(") ");
- emitIROperand(context, inst->getArg(1));
+ emitIROperand(context, inst->getArg(0));
}
else
{
@@ -4446,7 +4475,7 @@ emitDeclImpl(decl, nullptr);
emitIRType(context, inst->getType());
}
emit("(");
- emitIROperand(context, inst->getArg(1));
+ emitIROperand(context, inst->getArg(0));
emit(")");
break;
@@ -4480,9 +4509,9 @@ emitDeclImpl(decl, nullptr);
#define CASE(OPCODE, OP) \
case OPCODE: \
- emitIROperand(context, inst->getArg(1)); \
+ emitIROperand(context, inst->getArg(0)); \
emit("" #OP " "); \
- emitIROperand(context, inst->getArg(2)); \
+ emitIROperand(context, inst->getArg(1)); \
break
CASE(kIROp_Add, +);
@@ -4512,7 +4541,7 @@ emitDeclImpl(decl, nullptr);
case kIROp_Not:
{
- if (inst->getType()->op == kIROp_BoolType)
+ if (inst->getType()->Equals(getSession()->getBoolType()))
{
emit("!");
}
@@ -4520,73 +4549,72 @@ emitDeclImpl(decl, nullptr);
{
emit("~");
}
- emitIROperand(context, inst->getArg(1));
+ emitIROperand(context, inst->getArg(0));
}
break;
case kIROp_Sample:
- // argument 0 is the instruction's type
- emitIROperand(context, inst->getArg(1));
+ emitIROperand(context, inst->getArg(0));
emit(".Sample(");
- emitIROperand(context, inst->getArg(2));
+ emitIROperand(context, inst->getArg(1));
emit(", ");
- emitIROperand(context, inst->getArg(3));
+ emitIROperand(context, inst->getArg(2));
emit(")");
break;
case kIROp_SampleGrad:
// argument 0 is the instruction's type
- emitIROperand(context, inst->getArg(1));
+ emitIROperand(context, inst->getArg(0));
emit(".SampleGrad(");
+ emitIROperand(context, inst->getArg(1));
+ emit(", ");
emitIROperand(context, inst->getArg(2));
emit(", ");
emitIROperand(context, inst->getArg(3));
emit(", ");
emitIROperand(context, inst->getArg(4));
- emit(", ");
- emitIROperand(context, inst->getArg(5));
emit(")");
break;
case kIROp_Load:
// TODO: this logic will really only work for a simple variable reference...
- emitIROperand(context, inst->getArg(1));
+ emitIROperand(context, inst->getArg(0));
break;
case kIROp_Store:
// TODO: this logic will really only work for a simple variable reference...
- emitIROperand(context, inst->getArg(1));
+ emitIROperand(context, inst->getArg(0));
emit(" = ");
- emitIROperand(context, inst->getArg(2));
+ emitIROperand(context, inst->getArg(1));
break;
case kIROp_Call:
{
- emitIROperand(context, inst->getArg(1));
+ emitIROperand(context, inst->getArg(0));
emit("(");
- UInt argCount = inst->getArgCount() - 2;
+ UInt argCount = inst->getArgCount() - 1;
for( UInt aa = 0; aa < argCount; ++aa )
{
if(aa != 0) emit(", ");
- emitIROperand(context, inst->getArg(aa + 2));
+ emitIROperand(context, inst->getArg(aa + 1));
}
emit(")");
}
break;
case kIROp_BufferLoad:
- emitIROperand(context, inst->getArg(1));
+ emitIROperand(context, inst->getArg(0));
emit("[");
- emitIROperand(context, inst->getArg(2));
+ emitIROperand(context, inst->getArg(1));
emit("]");
break;
case kIROp_BufferStore:
- emitIROperand(context, inst->getArg(1));
+ emitIROperand(context, inst->getArg(0));
emit("[");
- emitIROperand(context, inst->getArg(2));
+ emitIROperand(context, inst->getArg(1));
emit("] = ");
- emitIROperand(context, inst->getArg(3));
+ emitIROperand(context, inst->getArg(2));
break;
case kIROp_GroupMemoryBarrierWithGroupSync:
@@ -4595,9 +4623,9 @@ emitDeclImpl(decl, nullptr);
case kIROp_getElement:
case kIROp_getElementPtr:
- emitIROperand(context, inst->getArg(1));
+ emitIROperand(context, inst->getArg(0));
emit("[");
- emitIROperand(context, inst->getArg(2));
+ emitIROperand(context, inst->getArg(1));
emit("]");
break;
@@ -4605,9 +4633,9 @@ emitDeclImpl(decl, nullptr);
case kIROp_Mul_Matrix_Vector:
case kIROp_Mul_Matrix_Matrix:
emit("mul(");
- emitIROperand(context, inst->getArg(1));
+ emitIROperand(context, inst->getArg(0));
emit(", ");
- emitIROperand(context, inst->getArg(2));
+ emitIROperand(context, inst->getArg(1));
emit(")");
break;
@@ -4619,7 +4647,7 @@ emitDeclImpl(decl, nullptr);
UInt elementCount = ii->getElementCount();
for (UInt ee = 0; ee < elementCount; ++ee)
{
- IRInst* irElementIndex = ii->getElementIndex(ee);
+ IRValue* irElementIndex = ii->getElementIndex(ee);
assert(irElementIndex->op == kIROp_IntLit);
IRConstant* irConst = (IRConstant*)irElementIndex;
@@ -4658,7 +4686,7 @@ emitDeclImpl(decl, nullptr);
case kIROp_Var:
{
auto ptrType = inst->getType();
- auto valType = ((IRPtrType*)ptrType)->getValueType();
+ auto valType = ((PtrType*)ptrType)->getValueType();
auto name = getName(inst);
emitIRType(context, valType, name);
@@ -4689,14 +4717,14 @@ emitDeclImpl(decl, nullptr);
{
auto ii = (IRSwizzleSet*)inst;
emitIRInstResultDecl(context, inst);
- emitIROperand(context, inst->getArg(1));
+ emitIROperand(context, inst->getArg(0));
emit(";\n");
emitIROperand(context, inst);
emit(".");
UInt elementCount = ii->getElementCount();
for (UInt ee = 0; ee < elementCount; ++ee)
{
- IRInst* irElementIndex = ii->getElementIndex(ee);
+ IRValue* irElementIndex = ii->getElementIndex(ee);
assert(irElementIndex->op == kIROp_IntLit);
IRConstant* irConst = (IRConstant*)irElementIndex;
@@ -4707,34 +4735,16 @@ emitDeclImpl(decl, nullptr);
emit(kComponents[elementIndex]);
}
emit(" = ");
- emitIROperand(context, inst->getArg(2));
+ emitIROperand(context, inst->getArg(1));
emit(";\n");
}
break;
-
-#if 0
- case kIROp_unconditionalBranch:
- emit("// unconditionalBranch ");
- emitIROperand(context, inst->getArg(1));
- emit("\n");
- break;
-
- case kIROp_conditionalBranch:
- emit("// conditionalBranch ");
- emitIROperand(context, inst->getArg(1));
- emit(" ");
- emitIROperand(context, inst->getArg(2));
- emit(" ");
- emitIROperand(context, inst->getArg(3));
- emit("\n");
- break;
-#endif
}
}
void emitIRSemantics(
EmitContext* context,
- IRInst* inst)
+ IRValue* inst)
{
auto decoration = inst->findDecoration<IRHighLevelDeclDecoration>();
if( decoration )
@@ -4745,7 +4755,7 @@ emitDeclImpl(decl, nullptr);
VarLayout* getVarLayout(
EmitContext* context,
- IRInst* var)
+ IRValue* var)
{
auto decoration = var->findDecoration<IRLayoutDecoration>();
if (!decoration)
@@ -4756,7 +4766,7 @@ emitDeclImpl(decl, nullptr);
void emitIRLayoutSemantics(
EmitContext* context,
- IRInst* inst,
+ IRValue* inst,
char const* uniformSemanticSpelling = "register")
{
auto layout = getVarLayout(context, inst);
@@ -4784,9 +4794,9 @@ emitDeclImpl(decl, nullptr);
while(block != end)
{
// Start by emitting the non-terminator instructions in the block.
- auto terminator = block->lastChild;
+ auto terminator = block->getLastInst();
assert(isTerminatorInst(terminator));
- for (auto inst = block->firstChild; inst != terminator; inst = inst->nextInst)
+ for (auto inst = block->getFirstInst(); inst != terminator; inst = inst->nextInst)
{
emitIRInst(context, inst);
}
@@ -5095,10 +5105,8 @@ emitDeclImpl(decl, nullptr);
// encoded as a parameter of pointer type, so
// we need to decode that here.
//
- if( paramType->op == kIROp_PtrType )
+ if( auto ptrType = paramType->As<PtrType>() )
{
- auto ptrType = (IRPtrType*) paramType;
-
// TODO: we need a way to distinguish `out`
// from `inout`. The easiest way to do
// that might be to have each be a distinct
@@ -5243,7 +5251,7 @@ emitDeclImpl(decl, nullptr);
}
}
-
+#if 0
void emitIRStruct(
EmitContext* context,
IRStructDecl* structType)
@@ -5263,6 +5271,7 @@ emitDeclImpl(decl, nullptr);
}
emit("};\n");
}
+#endif
void emitIRVarModifiers(
EmitContext* context,
@@ -5317,9 +5326,9 @@ emitDeclImpl(decl, nullptr);
}
void emitIRParameterBlock(
- EmitContext* context,
- IRVar* varDecl,
- IRUniformBufferType* type)
+ EmitContext* context,
+ IRGlobalVar* varDecl,
+ UniformParameterBlockType* type)
{
emit("cbuffer ");
emit(getName(varDecl));
@@ -5341,17 +5350,15 @@ emitDeclImpl(decl, nullptr);
typeLayout = parameterBlockTypeLayout->elementTypeLayout;
}
- switch( elementType->op )
+ if(auto declRefType = elementType->As<DeclRefType>())
{
- case kIROp_StructType:
+ if(auto structDeclRef = declRefType->declRef.As<StructDecl>())
{
- auto structType = (IRStructDecl*) elementType;
-
auto structTypeLayout = typeLayout.As<StructTypeLayout>();
assert(structTypeLayout);
UInt fieldIndex = 0;
- for(auto ff = structType->getFirstField(); ff; ff = ff->getNextField())
+ for(auto ff : GetFields(structDeclRef))
{
// TODO: need a plan to deal with the case where the IR-level
// `struct` type might not match the high-level type, so that
@@ -5367,19 +5374,18 @@ emitDeclImpl(decl, nullptr);
emitIRVarModifiers(context, fieldLayout);
- auto fieldType = ff->getFieldType();
- emitIRType(context, fieldType, getName(ff));
+ auto fieldType = GetType(ff);
+ emitIRType(context, fieldType, ff.GetName());
emitHLSLParameterBlockFieldLayoutSemantics(layout, fieldLayout);
emit(";\n");
}
}
- break;
-
- default:
+ }
+ else
+ {
emit("/* unexpected */");
- break;
}
emit("}\n");
@@ -5391,8 +5397,9 @@ emitDeclImpl(decl, nullptr);
{
auto allocatedType = varDecl->getType();
auto varType = allocatedType->getValueType();
- auto addressSpace = allocatedType->getAddressSpace();
+// auto addressSpace = allocatedType->getAddressSpace();
+#if 0
switch( varType->op )
{
case kIROp_ConstantBufferType:
@@ -5403,6 +5410,7 @@ emitDeclImpl(decl, nullptr);
default:
break;
}
+#endif
// Need to emit appropriate modifiers here.
@@ -5410,6 +5418,7 @@ emitDeclImpl(decl, nullptr);
emitIRVarModifiers(context, layout);
+#if 0
switch (addressSpace)
{
default:
@@ -5419,6 +5428,51 @@ emitDeclImpl(decl, nullptr);
emit("groupshared ");
break;
}
+#endif
+
+ emitIRType(context, varType, getName(varDecl));
+
+ emitIRSemantics(context, varDecl);
+
+ emitIRLayoutSemantics(context, varDecl);
+
+ emit(";\n");
+ }
+
+ void emitIRGlobalVar(
+ EmitContext* context,
+ IRGlobalVar* varDecl)
+ {
+ auto allocatedType = varDecl->getType();
+ auto varType = allocatedType->getValueType();
+// auto addressSpace = allocatedType->getAddressSpace();
+
+ if (auto paramBlockType = varType->As<UniformParameterBlockType>())
+ {
+ emitIRParameterBlock(
+ context,
+ varDecl,
+ paramBlockType);
+ return;
+ }
+
+ // Need to emit appropriate modifiers here.
+
+ auto layout = getVarLayout(context, varDecl);
+
+ emitIRVarModifiers(context, layout);
+
+#if 0
+ switch (addressSpace)
+ {
+ default:
+ break;
+
+ case kIRAddressSpace_GroupShared:
+ emit("groupshared ");
+ break;
+ }
+#endif
emitIRType(context, varType, getName(varDecl));
@@ -5431,7 +5485,7 @@ emitDeclImpl(decl, nullptr);
void emitIRGlobalInst(
EmitContext* context,
- IRInst* inst)
+ IRGlobalValue* inst)
{
// TODO: need to be able to `switch` on the IR opcode here,
// so there is some work to be done.
@@ -5441,9 +5495,15 @@ emitDeclImpl(decl, nullptr);
emitIRFunc(context, (IRFunc*) inst);
break;
+ case kIROp_global_var:
+ emitIRGlobalVar(context, (IRGlobalVar*) inst);
+ break;
+
+#if 0
case kIROp_StructType:
emitIRStruct(context, (IRStructDecl*) inst);
break;
+#endif
case kIROp_Var:
emitIRVar(context, (IRVar*) inst);
@@ -5454,13 +5514,154 @@ emitDeclImpl(decl, nullptr);
}
}
+ void ensureStructDecl(
+ EmitContext* context,
+ DeclRef<StructDecl> declRef)
+ {
+ // TODO: Eventually need to deal with the case where
+ // we have user-defined generic types.
+ //
+ auto decl = declRef.getDecl();
+
+ if(context->shared->irDeclsVisited.Contains(decl))
+ return;
+
+ context->shared->irDeclsVisited.Add(decl);
+
+ // First emit any types used by fields of this type
+ for( auto ff : GetFields(declRef) )
+ {
+ if(ff.getDecl()->HasModifier<HLSLStaticModifier>())
+ continue;
+
+ auto fieldType = GetType(ff);
+ emitIRUsedType(context, fieldType);
+ }
+
+ Emit("struct ");
+ emit(declRef.GetName());
+ Emit("\n{\n");
+ for( auto ff : GetFields(declRef) )
+ {
+ if(ff.getDecl()->HasModifier<HLSLStaticModifier>())
+ continue;
+
+ auto fieldType = GetType(ff);
+ emitIRType(context, fieldType, ff.GetName());
+
+ EmitSemantics(ff.getDecl());
+
+ emit(";\n");
+ }
+ Emit("};\n");
+ }
+
+ // A type is going to be used by the IR, so
+ // make sure that we have emitted whatever
+ // it needs.
+ void emitIRUsedType(
+ EmitContext* context,
+ Type* type)
+ {
+ if(type->As<BasicExpressionType>())
+ {}
+ else if(type->As<VectorExpressionType>())
+ {}
+ else if(type->As<MatrixExpressionType>())
+ {}
+ else if(auto arrayType = type->As<ArrayExpressionType>())
+ {
+ emitIRUsedType(context, arrayType->baseType);
+ }
+ else if( auto textureType = type->As<TextureTypeBase>() )
+ {
+ emitIRUsedType(context, textureType->elementType);
+ }
+ else if( auto genericType = type->As<BuiltinGenericType>() )
+ {
+ emitIRUsedType(context, genericType->elementType);
+ }
+ else if( auto ptrType = type->As<PtrType>() )
+ {
+ emitIRUsedType(context, ptrType->getValueType());
+ }
+ else if(type->As<SamplerStateType>() )
+ {
+ }
+ else if( auto declRefType = type->As<DeclRefType>() )
+ {
+ auto declRef = declRefType->declRef;
+ auto decl = declRef.getDecl();
+
+ if(decl->HasModifier<BuiltinTypeModifier>()
+ || decl->HasModifier<MagicTypeModifier>())
+ {
+ return;
+ }
+
+ if( auto structDeclRef = declRef.As<StructDecl>() )
+ {
+ //
+ ensureStructDecl(context, structDeclRef);
+ }
+ }
+ else
+ {}
+ }
+
+ void emitIRUsedTypesForValue(
+ EmitContext* context,
+ IRValue* value)
+ {
+ if(!value) return;
+ switch( value->op )
+ {
+ case kIROp_Func:
+ {
+ auto irFunc = (IRFunc*) value;
+ emitIRUsedType(context, irFunc->getResultType());
+ for( auto bb = irFunc->getFirstBlock(); bb; bb = bb->getNextBlock() )
+ {
+ for( auto pp = bb->getFirstParam(); pp; pp = pp->getNextParam() )
+ {
+ emitIRUsedTypesForValue(context, pp);
+ }
+
+ for( auto ii = bb->getFirstInst(); ii; ii = ii->nextInst )
+ {
+ emitIRUsedTypesForValue(context, ii);
+ }
+ }
+ }
+ break;
+
+ default:
+ {
+ emitIRUsedType(context, value->type);
+ }
+ break;
+ }
+ }
+
+ void emitIRUsedTypesForModule(
+ EmitContext* context,
+ IRModule* module)
+ {
+ for (auto gv : module->globalValues)
+ {
+ emitIRUsedTypesForValue(context, gv);
+ }
+ }
+
void emitIRModule(
EmitContext* context,
IRModule* module)
{
- for(auto ii = module->firstChild; ii; ii = ii->nextInst )
+ emitIRUsedTypesForModule(context, module);
+
+ for (auto gv : module->globalValues)
{
- emitIRGlobalInst(context, ii);
+ emitIRGlobalInst(context, gv);
}
}