diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2019-12-03 09:58:59 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-12-03 09:58:59 -0500 |
| commit | 9653dcc2c9d5d20d3d0e8918aaf1d5b09e963060 (patch) | |
| tree | aa1b42132361b2920d9f9301f0b0e44ea82d6b8c /source/slang/slang-ir-string-hash.cpp | |
| parent | a3651d99fb8f3a046365d60751d1f3f806e48f7a (diff) | |
getStringHash on string literals (#1140)
* WIP getStringHash
* Have a use.
* Add slang-string-hash.h/.cpp
* Use StringSlicePool for holding strings for StringHash.
Add outputBuffer to string-literal-hash.slang so value can be tested.
Ignore the GlobalHashedStringLiterals instruction on emit.
* Add all the hashed string literals to ProgramLayout.
* Add reflection support for hashed string literals to reflection test.
* Fix string literal hash test.
* Small fixes to pass test suite.
* Fix issue in serialization where IRUse is not correctly initialized.
* Fix problem initializing IRUse for string hash pass.
Remove hack from slang-ir-specialize - specially handling if user is not null.
* * Use shared builder when replacing getStringHash
* Comments for functions in slang-ir-string-hash
* Do not allow zero length string literals. Could be allowed, but doing so would require StringSlicePool to have a special case (or some other mechanism)
Diffstat (limited to 'source/slang/slang-ir-string-hash.cpp')
| -rw-r--r-- | source/slang/slang-ir-string-hash.cpp | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/source/slang/slang-ir-string-hash.cpp b/source/slang/slang-ir-string-hash.cpp new file mode 100644 index 000000000..b9e2d4045 --- /dev/null +++ b/source/slang/slang-ir-string-hash.cpp @@ -0,0 +1,108 @@ +// slang-ir-string-hash.cpp +#include "slang-ir-string-hash.h" + +#include "slang-ir.h" +#include "slang-ir-insts.h" + +namespace Slang { + +static void _findGetStringHashRec(IRInst* inst, List<IRGetStringHash*>& outInsts) +{ + for (IRInst* child = inst->getFirstDecorationOrChild(); child; child = child->getNextInst()) + { + if (IRGetStringHash* getInst = as<IRGetStringHash>(child)) + { + outInsts.add(getInst); + } + _findGetStringHashRec(child, outInsts); + } +} + +void replaceGetStringHash(IRModule* module, SharedIRBuilder& sharedBuilder, StringSlicePool& ioPool) +{ + IRBuilder builder; + builder.sharedBuilder = &sharedBuilder; + + builder.setInsertInto(module->getModuleInst()); + + List<IRGetStringHash*> insts; + _findGetStringHashRec(module->getModuleInst(), insts); + + // Then we want to add the GlobalHashedString instruction in the root + for (auto inst : insts) + { + IRStringLit* stringLit = inst->getStringLit(); + ioPool.add(stringLit->getStringSlice()); + + // Okay work out what the hash is + const int hash = GetHashCode(stringLit->getStringSlice()); + + IRInst* intLit = builder.getIntValue(builder.getIntType(), int32_t(hash)); + + // Okay we want to replace all uses with the literal + inst->replaceUsesWith(intLit); + inst->removeAndDeallocate(); + } +} + +void replaceGetStringHashWithGlobal(IRModule* module, SharedIRBuilder& sharedBuilder) +{ + StringSlicePool pool; + replaceGetStringHash(module, sharedBuilder, pool); + addGlobalHashedStringLiterals(pool, sharedBuilder); +} + +void findGlobalHashedStringLiterals(IRModule* module, StringSlicePool& pool) +{ + IRModuleInst* moduleInst = module->getModuleInst(); + + for (IRInst* child = moduleInst->getFirstDecorationOrChild(); child; child = child->getNextInst()) + { + if (IRGlobalHashedStringLiterals* hashedStringLits = as<IRGlobalHashedStringLiterals>(child)) + { + const Index count = hashedStringLits->getOperandCount(); + for (Index i = 0; i < count; ++i) + { + IRStringLit* stringLit = as<IRStringLit>(hashedStringLits->getOperand(i)); + pool.add(stringLit->getStringSlice()); + } + } + } +} + +void addGlobalHashedStringLiterals(const StringSlicePool& pool, SharedIRBuilder& sharedBuilder) +{ + if (pool.getNumSlices() <= StringSlicePool::kNumDefaultHandles) + { + return; + } + + IRBuilder builder; + builder.sharedBuilder = &sharedBuilder; + + // + IRModule* module = builder.getModule(); + + // We need to add a global instruction that references all of these string literals + builder.setInsertInto(module->getModuleInst()); + + Index numSlices = Index(pool.getNumSlices() - StringSlicePool::kNumDefaultHandles); + + IRInst* globalHashedInst = createEmptyInst(module, kIROp_GlobalHashedStringLiterals, int(numSlices)); + builder.addInst(globalHashedInst); + + auto operands = globalHashedInst->getOperands(); + + for (Index i = 0; i < numSlices; ++i) + { + UnownedStringSlice slice = pool.getSlice(StringSlicePool::Handle(i + StringSlicePool::kNumDefaultHandles)); + IRStringLit* stringLit = builder.getStringValue(slice); + + operands[i].init(globalHashedInst, stringLit); + } + + // Mark to keep alive + builder.addKeepAliveDecoration(globalHashedInst); +} + +} |
