summaryrefslogtreecommitdiffstats
path: root/source/slang/ir.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2018-09-25 17:59:16 -0400
committerGitHub <noreply@github.com>2018-09-25 17:59:16 -0400
commitee549942335add195df8e69a31f65a691d54aff9 (patch)
tree949513e7a8f4abdfe6be2b333d34fa5f9e4c373a /source/slang/ir.cpp
parent4f979d74acf2800d7bd2b38155d2bdc47b57d54b (diff)
Improve IROp lookup (#650)
* * Change the layout of IROp such that 'main' IROps are 0-x. * Removed MANUAL_RANGE instuction types, as no longer needed. * Work in prog on optimizing. * * Constant time lookup for IROpInfo * Refactor and document a little more the IROp layout * Mark ops that use 'other' bits * Fix typo in definition of kIROpFlag_UseOther
Diffstat (limited to 'source/slang/ir.cpp')
-rw-r--r--source/slang/ir.cpp53
1 files changed, 40 insertions, 13 deletions
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp
index c9131325b..c72a4a705 100644
--- a/source/slang/ir.cpp
+++ b/source/slang/ir.cpp
@@ -23,42 +23,69 @@ namespace Slang
// TODO: We should ideally be speeding up the name->inst
// mapping by using a dictionary, or even by pre-computing
// a hash table to be stored as a `static const` array.
+ //
+ // NOTE! That this array is now constructed in such a way that looking up
+ // an entry from an op is fast, by keeping blocks of main, and pseudo ops in same order
+ // as the ops themselves. Care must be taken to keep this constraint.
static const IROpMapEntry kIROps[] =
{
- { kIROp_Invalid, { "invalid", 0, 0 } },
-
+
+ // Main ops in order
#define INST(ID, MNEMONIC, ARG_COUNT, FLAGS) \
{ kIROp_##ID, { #MNEMONIC, ARG_COUNT, FLAGS, } },
+#include "ir-inst-defs.h"
+
+ // Pseudo ops
+#define INST(ID, MNEMONIC, ARG_COUNT, FLAGS) /* empty */
#define PSEUDO_INST(ID) \
{ kIRPseudoOp_##ID, { #ID, 0, 0 } },
+
+ // First is 'invalid'
+ { kIROp_Invalid,{ "invalid", 0, 0 } },
+ // Then all the other psuedo ops
#include "ir-inst-defs.h"
};
- //
-
- IROp findIROp(char const* name)
+ IROpInfo getIROpInfo(IROp opIn)
{
- for (auto ee : kIROps)
+ const int op = opIn & kIROpMeta_OpMask;
+ if ((op & kIROpMeta_IsPseudoOp) && op < kIRPseudoOp_LastPlusOne)
{
- if (strcmp(name, ee.info.name) == 0)
- return ee.op;
+ // It's a pseudo op
+ const int index = op - kIRPseudoOp_First;
+ // Pseudo ops start from kIROpcount
+ const auto& entry = kIROps[kIROpCount + index];
+ SLANG_ASSERT(entry.op == op);
+ return entry.info;
+ }
+ else if (op < kIROpCount)
+ {
+ // It's a main op
+ const auto& entry = kIROps[op];
+ SLANG_ASSERT(entry.op == op);
+ return entry.info;
}
- return IROp(kIROp_Invalid);
+ // Don't know what this is
+ SLANG_ASSERT(!"Invalid op");
+ SLANG_ASSERT(kIROps[kIROpCount].op == kIROp_Invalid);
+ return kIROps[kIROpCount].info;
}
- IROpInfo getIROpInfo(IROp op)
+ IROp findIROp(char const* name)
{
for (auto ee : kIROps)
{
- if (ee.op == op)
- return ee.info;
+ if (strcmp(name, ee.info.name) == 0)
+ return ee.op;
}
- return kIROps[0].info;
+ return IROp(kIROp_Invalid);
}
+
+
//
void IRUse::debugValidate()