summaryrefslogtreecommitdiff
path: root/source/slang/ir.h
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-08-17 09:46:19 -0700
committerTim Foley <tfoley@nvidia.com>2017-08-17 11:22:22 -0700
commit5de3003af561bad33680940ab1809622c428e94b (patch)
treeceb6f8b5f4d3c7e941f4edd47984b426d03fb980 /source/slang/ir.h
parent5230ad2edb28e176d0d7d2a9873ffb8f65285269 (diff)
IR generation cleanup work
- Make all instructions store their argument count for now, so we can iterate over them easily. - Longer term we might try to optimize for space because the common case is that the operand count is known, but keeping it simpler seems better for now - Split apart the creation of an instruction from adding it to a parent - Use the above capability to make sure that we add a function to its parent *after* all the parameter/result type emission has occured. - Perform simple value numbering for types during IR creation - This logic also tries to pick a good parent for any type instructions, so that types don't get created local to a function unless they really need to - Create all constants at global scope, and re-use when values are identical
Diffstat (limited to 'source/slang/ir.h')
-rw-r--r--source/slang/ir.h71
1 files changed, 56 insertions, 15 deletions
diff --git a/source/slang/ir.h b/source/slang/ir.h
index 95dec6007..0a0c8d612 100644
--- a/source/slang/ir.h
+++ b/source/slang/ir.h
@@ -60,6 +60,8 @@ struct IRUse
void init(IRInst* user, IRInst* usedValue);
};
+typedef uint32_t IRInstID;
+
// In the IR, almost *everything* is an instruction,
// in order to make the representation as uniform as possible.
struct IRInst
@@ -70,7 +72,11 @@ struct IRInst
// A unique ID to represent the op when printing
// (or zero to indicate that the value of this
// op isn't special).
- UInt id;
+ IRInstID id;
+
+ // The total number of arguments of this instruction
+ // (including the type)
+ uint32_t argCount;
// The parent of this instruction.
// This will often be a basic block, but we
@@ -95,14 +101,16 @@ typedef IRInst IRValue;
typedef long long IRIntegerValue;
typedef double IRFloatingPointValue;
-struct IRIntLit : IRInst
-{
- IRIntegerValue value;
-};
-
-struct IRFloatLit : IRInst
+struct IRConstant : IRInst
{
- IRFloatingPointValue value;
+ union
+ {
+ IRIntegerValue intVal;
+ IRFloatingPointValue floatVal;
+
+ // HACK: allows us to hash the value easily
+ void* ptrData[2];
+ } u;
};
// Representation of a type at the IR level.
@@ -188,20 +196,52 @@ struct IRFunc : IRParentInst
struct IRModule : IRParentInst
{
// The designated entry-point function, if any
- IRFunc* entryPoint;
+ IRFunc* entryPoint;
// A special counter used to assign logical ids to instructions in this module.
- UInt idCounter;
+ IRInstID idCounter;
};
-struct IRBuilder
+// Description of an instruction to be used for global value numbering
+struct IRInstKey
+{
+ IRInst* inst;
+
+ int GetHashCode();
+};
+
+bool operator==(IRInstKey const& left, IRInstKey const& right);
+
+struct IRConstantKey
+{
+ IRConstant* inst;
+
+ int GetHashCode();
+};
+bool operator==(IRConstantKey const& left, IRConstantKey const& right);
+
+struct SharedIRBuilder
{
// The module that will own all of the IR
IRModule* module;
+ Dictionary<IRInstKey, IRInst*> globalValueNumberingMap;
+ Dictionary<IRConstantKey, IRConstant*> constantMap;
+};
+
+struct IRBuilder
+{
+ // Shared state for all IR builders working on the same module
+ SharedIRBuilder* shared;
+
+ IRModule* getModule() { return shared->module; }
+
// The parent instruction to add children to.
IRParentInst* parentInst;
+ void addInst(IRParentInst* parent, IRInst* inst);
+ void addInst(IRInst* inst);
+
IRType* getBaseType(BaseType flavor);
IRType* getBoolType();
IRType* getVectorType(IRType* elementType, IRValue* elementCount);
@@ -232,19 +272,20 @@ struct IRBuilder
IRFunc* createFunc();
IRBlock* createBlock();
+ IRBlock* emitBlock();
- IRParam* createParam(
+ IRParam* emitParam(
IRType* type);
- IRInst* createFieldExtract(
+ IRInst* emitFieldExtract(
IRType* type,
IRValue* base,
UInt fieldIndex);
- IRInst* createReturn(
+ IRInst* emitReturn(
IRValue* val);
- IRInst* createReturn();
+ IRInst* emitReturn();
};
void dumpIR(IRModule* module);