summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-emit-glsl.cpp18
-rw-r--r--source/slang/slang-emit-hlsl.cpp17
-rw-r--r--source/slang/slang-ir-string-hash.cpp34
-rw-r--r--source/slang/slang-ir-string-hash.h8
-rw-r--r--source/slang/slang-lower-to-ir.cpp46
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.