summaryrefslogtreecommitdiffstats
path: root/source/slang/ir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/ir.cpp')
-rw-r--r--source/slang/ir.cpp288
1 files changed, 185 insertions, 103 deletions
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp
index c40b0f048..8e4f789ef 100644
--- a/source/slang/ir.cpp
+++ b/source/slang/ir.cpp
@@ -6,51 +6,19 @@
namespace Slang
{
-#define OP(ID, MNEMONIC, ARG_COUNT, FLAGS) \
- static const IROpInfo kIROpInfo_##ID { \
- #MNEMONIC, ARG_COUNT, FLAGS, }
-
-#define PARENT kIROpFlag_Parent
-
- OP(TypeType, type.type, 0, 0);
- OP(VoidType, type.void, 0, 0);
- OP(BlockType, type.block, 0, 0);
- OP(VectorType, type.vector, 2, 0);
- OP(BoolType, type.bool, 0, 0);
- OP(Float32Type, type.f32, 0, 0);
- OP(Int32Type, type.i32, 0, 0);
- OP(UInt32Type, type.u32, 0, 0);
- OP(StructType, type.struct, 0, 0);
-
- OP(IntLit, integer_constant, 0, 0);
- OP(FloatLit, float_constant, 0, 0);
-
- OP(Construct, construct, 0, 0);
-
- OP(Module, module, 0, PARENT);
- OP(Func, func, 0, PARENT);
- OP(Block, block, 0, PARENT);
-
- OP(Param, param, 0, 0);
-
- OP(FieldExtract, get_field, 1, 0);
- OP(ReturnVal, return_val, 1, 0);
- OP(ReturnVoid, return_void, 1, 0);
-
-#define INTRINSIC(NAME) \
- static const IROpInfo kIROpInfo_Intrinsic_##NAME { \
- "intrinsic." #NAME, 0, 0, };
-#include "intrinsic-defs.h"
-
-#undef PARENT
-#undef OP
+ static const IROpInfo kIROpInfos[] =
+ {
+#define INST(ID, MNEMONIC, ARG_COUNT, FLAGS) \
+ { #MNEMONIC, ARG_COUNT, FLAGS, },
+#include "ir-inst-defs.h"
+ };
- static IROpInfo const* const kIRIntrinsicOpInfos[] =
+ static const IROp kIRIntrinsicOps[] =
{
- nullptr,
+ (IROp) 0,
-#define INTRINSIC(NAME) &kIROpInfo_Intrinsic_##NAME,
+#define INTRINSIC(NAME) kIROp_Intrinsic_##NAME,
#include "intrinsic-defs.h"
};
@@ -78,6 +46,43 @@ namespace Slang
return &type;
}
+ IRDecoration* IRInst::findDecorationImpl(IRDecorationOp decorationOp)
+ {
+ for( auto dd = firstDecoration; dd; dd = dd->next )
+ {
+ if(dd->op == decorationOp)
+ return dd;
+ }
+ return nullptr;
+ }
+
+ //
+
+ IRParam* IRFunc::getFirstParam()
+ {
+ auto entryBlock = getFirstBlock();
+ if(!entryBlock) return nullptr;
+
+ auto firstInst = entryBlock->firstChild;
+ if(!firstInst) return nullptr;
+
+ if(firstInst->op != kIROp_Param)
+ return nullptr;
+
+ return (IRParam*) firstInst;
+ }
+
+ IRParam* IRParam::getNextParam()
+ {
+ auto next = nextInst;
+ if(!next) return nullptr;
+
+ if(next->op != kIROp_Param)
+ return nullptr;
+
+ return (IRParam*) next;
+ }
+
//
// Add an instruction to a specific parent
@@ -124,18 +129,18 @@ namespace Slang
static IRValue* createInstImpl(
IRBuilder* builder,
UInt size,
- IROpInfo const* op,
+ IROp op,
IRType* type,
- UInt argCount,
- IRValue* const* args)
+ UInt fixedArgCount,
+ IRValue* const* fixedArgs,
+ UInt varArgCount = 0,
+ IRValue* const* varArgs = nullptr)
{
IRValue* inst = (IRInst*) malloc(size);
memset(inst, 0, size);
- IRUse* instArgs = inst->getArgs();
-
auto module = builder->getModule();
- if (!module || (type && type->op == &kIROpInfo_VoidType))
+ if (!module || (type && type->op == kIROp_VoidType))
{
// Can't or shouldn't assign an ID to this op
}
@@ -143,15 +148,25 @@ namespace Slang
{
inst->id = ++module->idCounter;
}
- inst->argCount = argCount + 1;
+ inst->argCount = fixedArgCount + varArgCount + 1;
inst->op = op;
- inst->type.init(inst, type);
+ auto operand = inst->getArgs();
- for( UInt aa = 0; aa < argCount; ++aa )
+ operand->init(inst, type);
+ operand++;
+
+ for( UInt aa = 0; aa < fixedArgCount; ++aa )
{
- instArgs[aa+1].init(inst, args[aa]);
+ operand->init(inst, fixedArgs[aa]);
+ operand++;
+ }
+
+ for( UInt aa = 0; aa < varArgCount; ++aa )
+ {
+ operand->init(inst, varArgs[aa]);
+ operand++;
}
return inst;
@@ -165,7 +180,7 @@ namespace Slang
static IRValue* createInstImpl(
IRBuilder* builder,
UInt size,
- IROpInfo const* op,
+ IROp op,
UInt argCount,
IRValue* const* args)
{
@@ -181,7 +196,7 @@ namespace Slang
template<typename T>
static T* createInst(
IRBuilder* builder,
- IROpInfo const* op,
+ IROp op,
IRType* type,
UInt argCount,
IRValue* const* args)
@@ -198,7 +213,7 @@ namespace Slang
template<typename T>
static T* createInst(
IRBuilder* builder,
- IROpInfo const* op,
+ IROp op,
IRType* type)
{
return (T*)createInstImpl(
@@ -213,7 +228,7 @@ namespace Slang
template<typename T>
static T* createInst(
IRBuilder* builder,
- IROpInfo const* op,
+ IROp op,
IRType* type,
IRValue* arg)
{
@@ -229,7 +244,7 @@ namespace Slang
template<typename T>
static T* createInst(
IRBuilder* builder,
- IROpInfo const* op,
+ IROp op,
IRType* type,
IRValue* arg1,
IRValue* arg2)
@@ -247,7 +262,7 @@ namespace Slang
template<typename T>
static T* createInstWithTrailingArgs(
IRBuilder* builder,
- IROpInfo const* op,
+ IROp op,
IRType* type,
UInt argCount,
IRValue* const* args)
@@ -261,6 +276,27 @@ namespace Slang
args);
}
+ template<typename T>
+ static T* createInstWithTrailingArgs(
+ IRBuilder* builder,
+ IROp op,
+ IRType* type,
+ UInt fixedArgCount,
+ IRValue* const* fixedArgs,
+ UInt varArgCount,
+ IRValue* const* varArgs)
+ {
+ return (T*)createInstImpl(
+ builder,
+ sizeof(T) + varArgCount * sizeof(IRUse),
+ op,
+ type,
+ fixedArgCount,
+ fixedArgs,
+ varArgCount,
+ varArgs);
+ }
+
//
bool operator==(IRInstKey const& left, IRInstKey const& right)
@@ -327,7 +363,7 @@ namespace Slang
static IRInst* findOrEmitInstImpl(
IRBuilder* builder,
UInt size,
- IROpInfo const* op,
+ IROp op,
IRType* type,
UInt argCount,
IRValue* const* args)
@@ -354,7 +390,7 @@ namespace Slang
parent = builder->parentInst;
}
- if( parent->op == &kIROpInfo_Func )
+ if( parent->op == kIROp_Func )
{
// We are trying to insert into a function, and we should really
// be inserting into its entry block.
@@ -398,7 +434,7 @@ namespace Slang
template<typename T>
static T* findOrEmitInst(
IRBuilder* builder,
- IROpInfo const* op,
+ IROp op,
IRType* type,
UInt argCount,
IRValue* const* args)
@@ -415,7 +451,7 @@ namespace Slang
template<typename T>
static T* findOrEmitInst(
IRBuilder* builder,
- IROpInfo const* op,
+ IROp op,
IRType* type)
{
return (T*) findOrEmitInstImpl(
@@ -430,7 +466,7 @@ namespace Slang
template<typename T>
static T* findOrEmitInst(
IRBuilder* builder,
- IROpInfo const* op,
+ IROp op,
IRType* type,
IRInst* arg)
{
@@ -446,7 +482,7 @@ namespace Slang
template<typename T>
static T* findOrEmitInst(
IRBuilder* builder,
- IROpInfo const* op,
+ IROp op,
IRType* type,
IRInst* arg1,
IRInst* arg2)
@@ -482,11 +518,11 @@ namespace Slang
}
static IRConstant* findOrEmitConstant(
- IRBuilder* builder,
- IROpInfo const* op,
- IRType* type,
- UInt valueSize,
- void const* value)
+ IRBuilder* builder,
+ IROp op,
+ IRType* type,
+ UInt valueSize,
+ void const* value)
{
// First, we need to pick a good insertion point
// for the instruction, which we do by looking
@@ -531,7 +567,7 @@ namespace Slang
//
- static IRType* getBaseTypeImpl(IRBuilder* builder, IROpInfo const* op)
+ static IRType* getBaseTypeImpl(IRBuilder* builder, IROp op)
{
auto inst = findOrEmitInst<IRType>(
builder,
@@ -544,10 +580,10 @@ namespace Slang
{
switch( flavor )
{
- case BaseType::Bool: return getBaseTypeImpl(this, &kIROpInfo_BoolType);
- case BaseType::Float: return getBaseTypeImpl(this, &kIROpInfo_Float32Type);
- case BaseType::Int: return getBaseTypeImpl(this, &kIROpInfo_Int32Type);
- case BaseType::UInt: return getBaseTypeImpl(this, &kIROpInfo_UInt32Type);
+ case BaseType::Bool: return getBaseTypeImpl(this, kIROp_BoolType);
+ case BaseType::Float: return getBaseTypeImpl(this, kIROp_Float32Type);
+ case BaseType::Int: return getBaseTypeImpl(this, kIROp_Int32Type);
+ case BaseType::UInt: return getBaseTypeImpl(this, kIROp_UInt32Type);
default:
SLANG_UNEXPECTED("unhandled base type");
@@ -564,7 +600,7 @@ namespace Slang
{
return findOrEmitInst<IRVectorType>(
this,
- &kIROpInfo_VectorType,
+ kIROp_VectorType,
getTypeType(),
elementType,
elementCount);
@@ -574,7 +610,7 @@ namespace Slang
{
return findOrEmitInst<IRType>(
this,
- &kIROpInfo_TypeType,
+ kIROp_TypeType,
nullptr);
}
@@ -582,7 +618,7 @@ namespace Slang
{
return findOrEmitInst<IRType>(
this,
- &kIROpInfo_VoidType,
+ kIROp_VoidType,
getTypeType());
}
@@ -590,20 +626,40 @@ namespace Slang
{
return findOrEmitInst<IRType>(
this,
- &kIROpInfo_BlockType,
+ kIROp_BlockType,
+ getTypeType());
+ }
+
+ IRStructDecl* IRBuilder::createStructType()
+ {
+ return createInst<IRStructDecl>(
+ this,
+ kIROp_StructType,
getTypeType());
}
- IRType* IRBuilder::getStructType(
- UInt fieldCount,
- IRType* const* fieldTypes)
+ IRStructField* IRBuilder::createStructField(IRType* fieldType)
{
- auto inst = createInstWithTrailingArgs<IRStructType>(
+ return createInst<IRStructField>(
this,
- &kIROpInfo_StructType,
+ kIROp_StructField,
+ fieldType);
+ }
+
+
+ IRType* IRBuilder::getFuncType(
+ UInt paramCount,
+ IRType* const* paramTypes,
+ IRType* resultType)
+ {
+ auto inst = createInstWithTrailingArgs<IRFuncType>(
+ this,
+ kIROp_FuncType,
getTypeType(),
- fieldCount,
- (IRValue* const*)fieldTypes);
+ 1,
+ (IRValue* const*) &resultType,
+ paramCount,
+ (IRValue* const*) paramTypes);
addInst(inst);
return inst;
}
@@ -617,7 +673,7 @@ namespace Slang
{
return findOrEmitConstant(
this,
- &kIROpInfo_IntLit,
+ kIROp_IntLit,
type,
sizeof(value),
&value);
@@ -627,7 +683,7 @@ namespace Slang
{
return findOrEmitConstant(
this,
- &kIROpInfo_FloatLit,
+ kIROp_FloatLit,
type,
sizeof(value),
&value);
@@ -641,7 +697,7 @@ namespace Slang
{
auto inst = createInstWithTrailingArgs<IRInst>(
this,
- kIRIntrinsicOpInfos[(int)intrinsicOp],
+ kIRIntrinsicOps[(int)intrinsicOp],
type,
argCount,
args);
@@ -656,7 +712,7 @@ namespace Slang
{
auto inst = createInstWithTrailingArgs<IRInst>(
this,
- &kIROpInfo_Construct,
+ kIROp_Construct,
type,
argCount,
args);
@@ -668,7 +724,7 @@ namespace Slang
{
return createInst<IRModule>(
this,
- &kIROpInfo_Module,
+ kIROp_Module,
nullptr);
}
@@ -677,7 +733,7 @@ namespace Slang
{
return createInst<IRFunc>(
this,
- &kIROpInfo_Func,
+ kIROp_Func,
nullptr);
}
@@ -685,7 +741,7 @@ namespace Slang
{
return createInst<IRBlock>(
this,
- &kIROpInfo_Block,
+ kIROp_Block,
getBlockType());
}
@@ -701,24 +757,23 @@ namespace Slang
{
auto inst = createInst<IRParam>(
this,
- &kIROpInfo_Param,
+ kIROp_Param,
type);
addInst(inst);
return inst;
}
IRInst* IRBuilder::emitFieldExtract(
- IRType* type,
- IRValue* base,
- UInt fieldIndex)
+ IRType* type,
+ IRValue* base,
+ IRStructField* field)
{
auto inst = createInst<IRFieldExtract>(
this,
- &kIROpInfo_FieldExtract,
+ kIROp_FieldExtract,
type,
- base);
-
- inst->fieldIndex = fieldIndex;
+ base,
+ field);
addInst(inst);
return inst;
@@ -729,7 +784,7 @@ namespace Slang
{
auto inst = createInst<IRReturnVal>(
this,
- &kIROpInfo_ReturnVal,
+ kIROp_ReturnVal,
getVoidType(),
val);
addInst(inst);
@@ -740,12 +795,38 @@ namespace Slang
{
auto inst = createInst<IRReturnVoid>(
this,
- &kIROpInfo_ReturnVoid,
+ kIROp_ReturnVoid,
getVoidType());
addInst(inst);
return inst;
}
+ IRDecoration* IRBuilder::addDecorationImpl(
+ IRInst* inst,
+ UInt decorationSize,
+ IRDecorationOp op)
+ {
+ auto decoration = (IRDecoration*) malloc(decorationSize);
+ memset(decoration, 0, decorationSize);
+
+ decoration->op = op;
+
+ decoration->next = inst->firstDecoration;
+ inst->firstDecoration = decoration;
+
+ return decoration;
+ }
+
+ IRHighLevelDeclDecoration* IRBuilder::addHighLevelDeclDecoration(IRInst* inst, Decl* decl)
+ {
+ auto decoration = addDecoration<IRHighLevelDeclDecoration>(inst, kIRDecorationOp_HighLevelDecl);
+ decoration->decl = decl;
+ return decoration;
+ }
+
+ //
+
+
struct IRDumpContext
{
FILE* file;
@@ -803,6 +884,7 @@ namespace Slang
// TODO: need to display a name for the result...
auto op = inst->op;
+ auto opInfo = &kIROpInfos[op];
if (inst->id)
{
@@ -810,7 +892,7 @@ namespace Slang
dump(context, " = ");
}
- dump(context, op->name);
+ dump(context, opInfo->name);
// TODO: dump operands
uint32_t argCount = inst->argCount;
@@ -832,7 +914,7 @@ namespace Slang
dump(context, "\n");
- if (op->flags & kIROpFlag_Parent)
+ if (opInfo->flags & kIROpFlag_Parent)
{
dumpIndent(context);
dump(context, "{\n");