summaryrefslogtreecommitdiff
path: root/source/slang/ir.h
diff options
context:
space:
mode:
authorTim Foley <tim.foley.is@gmail.com>2017-08-17 15:22:24 -0700
committerGitHub <noreply@github.com>2017-08-17 15:22:24 -0700
commit7e05e062a0b7c39dbce6e850227d2038aca2f38e (patch)
tree53a6a509f3bba87d964ba3a5007b538db1d83a4e /source/slang/ir.h
parent1965c3f3f265c43c8d1d96bb49d0850ce5d53cc3 (diff)
parentec8175c1f0afe3f7758f70da240aba03a791c3a9 (diff)
Merge pull request #170 from tfoleyNV/ir
Add some dummy logic to print IR to HLSL
Diffstat (limited to 'source/slang/ir.h')
-rw-r--r--source/slang/ir.h153
1 files changed, 141 insertions, 12 deletions
diff --git a/source/slang/ir.h b/source/slang/ir.h
index 0a0c8d612..fcebf5d15 100644
--- a/source/slang/ir.h
+++ b/source/slang/ir.h
@@ -27,6 +27,15 @@ enum : IROpFlags
kIROpFlag_Parent = 1 << 0,
};
+enum IROp : uint16_t
+{
+
+#define INST(ID, MNEMONIC, ARG_COUNT, FLAGS) \
+ kIROp_##ID,
+
+#include "ir-inst-defs.h"
+};
+
// A logical operation/opcode in the IR
struct IROpInfo
{
@@ -60,6 +69,22 @@ struct IRUse
void init(IRInst* user, IRInst* usedValue);
};
+enum IRDecorationOp : uint16_t
+{
+ kIRDecorationOp_HighLevelDecl,
+};
+
+// A "decoration" that gets applied to an instruction.
+// These usually don't affect semantics, but are useful
+// for preserving high-level source information.
+struct IRDecoration
+{
+ // Next decoration attached to the same instruction
+ IRDecoration* next;
+
+ IRDecorationOp op;
+};
+
typedef uint32_t IRInstID;
// In the IR, almost *everything* is an instruction,
@@ -67,7 +92,7 @@ typedef uint32_t IRInstID;
struct IRInst
{
// The operation that this value represents
- IROpInfo const* op;
+ IROp op;
// A unique ID to represent the op when printing
// (or zero to indicate that the value of this
@@ -90,14 +115,52 @@ struct IRInst
// The first use of this value (start of a linked list)
IRUse* firstUse;
+ // The linked list of decorations attached to this instruction
+ IRDecoration* firstDecoration;
+
+ IRDecoration* findDecorationImpl(IRDecorationOp op);
+
+ template<typename T>
+ T* findDecoration()
+ {
+ return (T*) findDecorationImpl(IRDecorationOp(T::kDecorationOp));
+ }
+
+
// The type of this value
IRUse type;
+ IRType* getType() { return (IRType*) type.usedValue; }
+
+ UInt getArgCount()
+ {
+ return argCount;
+ }
+
IRUse* getArgs();
+
+ IRInst* getArg(UInt index)
+ {
+ return getArgs()[index].usedValue;
+ }
};
+// This type alias exists because I waffled on the name for a bit.
+// All existing uses of `IRValue` should move to `IRInst`
typedef IRInst IRValue;
+class Decl;
+
+// Associates an IR-level decoration with a source declaration
+// in the high-level AST, that can be used to extract
+// additional information that informs code emission.
+struct IRHighLevelDeclDecoration : IRDecoration
+{
+ enum { kDecorationOp = kIRDecorationOp_HighLevelDecl };
+
+ Decl* decl;
+};
+
typedef long long IRIntegerValue;
typedef double IRFloatingPointValue;
@@ -127,15 +190,35 @@ struct IRVectorType : IRType
{
IRUse elementType;
IRUse elementCount;
+
+ IRType* getElementType() { return (IRType*) elementType.usedValue; }
+ IRInst* getElementCount() { return elementCount.usedValue; }
};
-struct IRStructType : IRType
-{};
+struct IRFuncType : IRType
+{
+ IRUse resultType;
+ // parameter tyeps are varargs...
+ IRType* getResultType() { return (IRType*) resultType.usedValue; }
+ UInt getParamCount()
+ {
+ return getArgCount() - 2;
+ }
+ IRType* getParamType(UInt index)
+ {
+ return (IRType*) getArg(2 + index);
+ }
+};
+
+struct IRStructField;
struct IRFieldExtract : IRInst
{
IRUse base;
- UInt fieldIndex;
+ IRUse field;
+
+ IRInst* getBase() { return base.usedValue; }
+ IRStructField* getField() { return (IRStructField*) field.usedValue; }
};
// A instruction that ends a basic block (usually because of control flow)
@@ -148,6 +231,8 @@ struct IRReturn : IRTerminatorInst
struct IRReturnVal : IRReturn
{
IRUse val;
+
+ IRInst* getVal() { return val.usedValue; }
};
struct IRReturnVoid : IRReturn
@@ -164,6 +249,20 @@ struct IRParentInst : IRInst
IRInst* lastChild;
};
+struct IRStructField : IRInst
+{
+ IRType* getFieldType() { return (IRType*) type.usedValue; }
+
+ IRStructField* getNextField() { return (IRStructField*) nextInst; }
+};
+
+struct IRStructDecl : IRParentInst
+{
+ IRStructField* getFirstField() { return (IRStructField*) firstChild; }
+ IRStructField* getLastField() { return (IRStructField*) lastChild; }
+};
+
+
// A basic block is a parent instruction that adds the constraint
// that all the children need to be "ordinary" instructions (so
// no function declarations, or nested blocks). We also expect
@@ -174,14 +273,16 @@ struct IRBlock : IRParentInst
// Note that in a valid program, every block must end with
// a "terminator" instruction, so these should be non-NULL,
// and `last` should actually be an `IRTerminatorInst`.
- IRInst* firstChild;
- IRInst* lastChild;
+
+ IRBlock* getPrevBlock() { return (IRBlock*) prevInst; }
+ IRBlock* getNextBlock() { return (IRBlock*) nextInst; }
};
// A function parameter is represented by an instruction
// in the entry block of a function.
struct IRParam : IRInst
{
+ IRParam* getNextParam();
};
// A function is a parent to zero or more blocks of instructions.
@@ -190,6 +291,16 @@ struct IRParam : IRInst
// an instruction (e.g., a call).
struct IRFunc : IRParentInst
{
+ IRFuncType* getType() { return (IRFuncType*) type.usedValue; }
+
+ IRType* getResultType() { return getType()->getResultType(); }
+ UInt getParamCount() { return getType()->getParamCount(); }
+ IRType* getParamType(UInt index) { return getType()->getParamType(index); }
+
+ IRBlock* getFirstBlock() { return (IRBlock*) firstChild; }
+ IRBlock* getLastBlock() { return (IRBlock*) lastChild; }
+
+ IRParam* getFirstParam();
};
// A module is a parent to functions, global variables, types, etc.
@@ -248,9 +359,14 @@ struct IRBuilder
IRType* getTypeType();
IRType* getVoidType();
IRType* getBlockType();
- IRType* getStructType(
- UInt fieldCount,
- IRType* const* fieldTypes);
+
+ IRStructDecl* createStructType();
+ IRStructField* createStructField(IRType* fieldType);
+
+ IRType* getFuncType(
+ UInt paramCount,
+ IRType* const* paramTypes,
+ IRType* resultType);
IRValue* getBoolValue(bool value);
IRValue* getIntValue(IRType* type, IRIntegerValue value);
@@ -278,14 +394,27 @@ struct IRBuilder
IRType* type);
IRInst* emitFieldExtract(
- IRType* type,
- IRValue* base,
- UInt fieldIndex);
+ IRType* type,
+ IRValue* base,
+ IRStructField* field);
IRInst* emitReturn(
IRValue* val);
IRInst* emitReturn();
+
+ IRDecoration* addDecorationImpl(
+ IRInst* inst,
+ UInt decorationSize,
+ IRDecorationOp op);
+
+ template<typename T>
+ T* addDecoration(IRInst* inst, IRDecorationOp op)
+ {
+ return (T*) addDecorationImpl(inst, sizeof(T), op);
+ }
+
+ IRHighLevelDeclDecoration* addHighLevelDeclDecoration(IRInst* inst, Decl* decl);
};
void dumpIR(IRModule* module);