diff options
| author | Tim Foley <tim.foley.is@gmail.com> | 2017-08-17 15:22:24 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-08-17 15:22:24 -0700 |
| commit | 7e05e062a0b7c39dbce6e850227d2038aca2f38e (patch) | |
| tree | 53a6a509f3bba87d964ba3a5007b538db1d83a4e /source/slang/ir.h | |
| parent | 1965c3f3f265c43c8d1d96bb49d0850ce5d53cc3 (diff) | |
| parent | ec8175c1f0afe3f7758f70da240aba03a791c3a9 (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.h | 153 |
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); |
