diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-emit-glsl.cpp | 18 | ||||
| -rw-r--r-- | source/slang/slang-emit-hlsl.cpp | 17 | ||||
| -rw-r--r-- | source/slang/slang-ir-string-hash.cpp | 34 | ||||
| -rw-r--r-- | source/slang/slang-ir-string-hash.h | 8 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 46 |
5 files changed, 62 insertions, 61 deletions
diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp index fbae21f75..1191a170c 100644 --- a/source/slang/slang-emit-glsl.cpp +++ b/source/slang/slang-emit-glsl.cpp @@ -1279,6 +1279,23 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu // `FRem` there is no direct GLSL translation, so we will // leave things with the default behavior for now. + case kIROp_StringLit: + { + IRStringLit* lit = cast<IRStringLit>(inst); + m_writer->emit(GetHashCode(lit->getStringSlice())); + return true; + } + case kIROp_GetStringHash: + { + // On GLSL target, the `String` type is just an `int` + // that is the hash of the string, so we can emit + // the first operand to `getStringHash` directly. + // + EmitOpInfo outerPrec = inOuterPrec; + emitOperand(inst->getOperand(0), outerPrec); + return true; + } + default: break; } @@ -1480,6 +1497,7 @@ void GLSLSourceEmitter::emitSimpleTypeImpl(IRType* type) } return; } + case kIROp_StringType: m_writer->emit("int"); return; default: break; } diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp index f615d41fb..4225b1bf3 100644 --- a/source/slang/slang-emit-hlsl.cpp +++ b/source/slang/slang-emit-hlsl.cpp @@ -458,6 +458,22 @@ bool HLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu m_writer->emit(")"); return true; } + case kIROp_StringLit: + { + IRStringLit* lit = cast<IRStringLit>(inst); + m_writer->emit(GetHashCode(lit->getStringSlice())); + return true; + } + case kIROp_GetStringHash: + { + // On GLSL target, the `String` type is just an `int` + // that is the hash of the string, so we can emit + // the first operand to `getStringHash` directly. + // + EmitOpInfo outerPrec = inOuterPrec; + emitOperand(inst->getOperand(0), outerPrec); + return true; + } default: break; } // Not handled @@ -584,6 +600,7 @@ void HLSLSourceEmitter::emitSimpleTypeImpl(IRType* type) } return; } + case kIROp_StringType: m_writer->emit("int"); return; default: break; } diff --git a/source/slang/slang-ir-string-hash.cpp b/source/slang/slang-ir-string-hash.cpp index 0a15ba52d..2d5d78d7e 100644 --- a/source/slang/slang-ir-string-hash.cpp +++ b/source/slang/slang-ir-string-hash.cpp @@ -18,40 +18,6 @@ static void _findGetStringHashRec(IRInst* inst, List<IRGetStringHash*>& 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(StringSlicePool::Style::Empty); - replaceGetStringHash(module, sharedBuilder, pool); - addGlobalHashedStringLiterals(pool, sharedBuilder); -} - void findGlobalHashedStringLiterals(IRModule* module, StringSlicePool& pool) { IRModuleInst* moduleInst = module->getModuleInst(); diff --git a/source/slang/slang-ir-string-hash.h b/source/slang/slang-ir-string-hash.h index 13dbe12df..ccbbf4049 100644 --- a/source/slang/slang-ir-string-hash.h +++ b/source/slang/slang-ir-string-hash.h @@ -11,14 +11,6 @@ namespace Slang struct IRModule; struct SharedIRBuilder; -// Find all of the calls to 'getStringHash' and replace them with the an int literal of the value. Place all -// of the string literal values into the ioPool. -void replaceGetStringHash(IRModule* module, SharedIRBuilder& sharedBuilder, StringSlicePool& ioPool); - -// Does the same as replaceGetStringHash, but also adds a GlobalHashedStringLiterals instruction of any -// string literals referenced via 'getStringHash'. If there are none, it does nothing. -void replaceGetStringHashWithGlobal(IRModule* module, SharedIRBuilder& sharedBuilder); - // Finds the global GlobalHashedStringLiterals instruction for the module if there is one, and then // adds all of it's strings to ioPool. void findGlobalHashedStringLiterals(IRModule* module, StringSlicePool& ioPool); diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index 14cc68b16..fdbb2cb27 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -343,6 +343,18 @@ struct SharedIRGenContext // to the appropriate basic block to jump to. Dictionary<Stmt*, IRBlock*> breakLabels; Dictionary<Stmt*, IRBlock*> continueLabels; + + // List of all string literals used in user code, regardless + // of how they were used (i.e., whether or not they were hashed). + // + // This does *not* collect: + // * String literals that were only used for attributes/modifiers in + // the user's code (e.g., `"compute"` in `[shader("compute")]`) + // * Any IR string literals constructed for the purpose of decorations, + // reflection, or other meta-data that did not appear as a literal + // in the source code. + // + List<IRInst*> m_stringLiterals; }; @@ -778,21 +790,6 @@ LoweredValInfo emitCallToDeclRef( } else { - switch (intrinsicOp) - { - case kIROp_GetStringHash: - { - IRStringLit* stringLit = as<IRStringLit>(args[0]); - if (stringLit == nullptr) - { - auto sink = context->getSink(); - sink->diagnose(funcDecl, Diagnostics::getStringHashRequiresStringLiteral); - return LoweredValInfo(); - } - - } - } - // The intrinsic op maps to a single IR instruction, // so we will emit an instruction with the chosen // opcode, and the arguments to the call as its operands. @@ -2515,7 +2512,9 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo> LoweredValInfo visitStringLiteralExpr(StringLiteralExpr* expr) { - return LoweredValInfo::simple(context->irBuilder->getStringValue(expr->value.getUnownedSlice())); + auto irLit = context->irBuilder->getStringValue(expr->value.getUnownedSlice()); + context->shared->m_stringLiterals.add(irLit); + return LoweredValInfo::simple(irLit); } LoweredValInfo visitAggTypeCtorExpr(AggTypeCtorExpr* /*expr*/) @@ -6813,6 +6812,18 @@ IRModule* generateIRForTranslationUnit( ensureAllDeclsRec(context, decl); } + // Build a global instruction to hold all the string + // literals used in the module. + { + auto& stringLits = sharedContext->m_stringLiterals; + auto stringLitCount = stringLits.getCount(); + if(stringLitCount != 0) + { + builder->setInsertInto(module->getModuleInst()); + builder->emitIntrinsicInst(builder->getVoidType(), kIROp_GlobalHashedStringLiterals, stringLitCount, stringLits.getBuffer()); + } + } + #if 0 fprintf(stderr, "### GENERATED\n"); dumpIR(module); @@ -6852,9 +6863,6 @@ IRModule* generateIRForTranslationUnit( // call graph) based on constraints imposed by different instructions. propagateConstExpr(module, compileRequest->getSink()); - // Replace calls to getStringHash, and save all the unique string lits in a GlobalHashedStringLiterals inst - replaceGetStringHashWithGlobal(module, *sharedBuilder); - // TODO: give error messages if any `undefined` or // `unreachable` instructions remain. |
