summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/emit.cpp26
-rw-r--r--source/slang/ir-clone.cpp15
-rw-r--r--source/slang/ir-clone.h13
-rw-r--r--source/slang/ir-inst-defs.h1
-rw-r--r--source/slang/ir-insts.h1
-rw-r--r--source/slang/ir-ssa.cpp40
-rw-r--r--source/slang/lower-to-ir.cpp4
-rw-r--r--source/slang/modifier-defs.h2
-rw-r--r--source/slang/parser.cpp2
9 files changed, 88 insertions, 16 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index e69ee2a93..8bb2a244b 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -2554,6 +2554,14 @@ struct EmitVisitor
if(inst->mightHaveSideEffects())
return false;
+ // Don't fold instructions that are marked `[precise]`.
+ // This could in principle be extended to any other
+ // decorations that affect the semantics of an instruction
+ // in ways that require a temporary to be introduced.
+ //
+ if(inst->findDecoration<IRPreciseDecoration>())
+ return false;
+
// Okay, at this point we know our instruction must have a single use.
auto use = inst->firstUse;
SLANG_ASSERT(use);
@@ -2707,6 +2715,8 @@ struct EmitVisitor
if (as<IRVoidType>(type))
return;
+ emitIRTempModifiers(ctx, inst);
+
emitIRRateQualifiers(ctx, inst);
emitIRType(ctx, type, getIRName(inst));
@@ -5141,6 +5151,7 @@ struct EmitVisitor
{
for (auto pp = bb->getFirstParam(); pp; pp = pp->getNextParam())
{
+ emitIRTempModifiers(ctx, pp);
emitIRType(ctx, pp->getFullType(), getIRName(pp));
emit(";\n");
}
@@ -5849,6 +5860,19 @@ struct EmitVisitor
}
}
+ /// Emit modifiers that should apply even for a declaration of an SSA temporary.
+ void emitIRTempModifiers(
+ EmitContext* ctx,
+ IRInst* temp)
+ {
+ SLANG_UNUSED(ctx);
+
+ if(temp->findDecoration<IRPreciseDecoration>())
+ {
+ emit("precise ");
+ }
+ }
+
void emitIRVarModifiers(
EmitContext* ctx,
VarLayout* layout,
@@ -5897,6 +5921,8 @@ struct EmitVisitor
}
}
+ emitIRTempModifiers(ctx, varDecl);
+
if (!layout)
return;
diff --git a/source/slang/ir-clone.cpp b/source/slang/ir-clone.cpp
index b648efec6..bd5f9bcaa 100644
--- a/source/slang/ir-clone.cpp
+++ b/source/slang/ir-clone.cpp
@@ -241,10 +241,11 @@ IRInst* cloneInst(
void cloneDecoration(
IRDecoration* oldDecoration,
- IRInst* newParent)
+ IRInst* newParent,
+ IRModule* module)
{
SharedIRBuilder sharedBuilder;
- sharedBuilder.module = newParent->getModule();
+ sharedBuilder.module = module;
IRBuilder builder;
builder.sharedBuilder = &sharedBuilder;
@@ -258,6 +259,16 @@ void cloneDecoration(
cloneInst(&env, &builder, oldDecoration);
}
+void cloneDecoration(
+ IRDecoration* oldDecoration,
+ IRInst* newParent)
+{
+ cloneDecoration(
+ oldDecoration,
+ newParent,
+ newParent->getModule());
+}
+
bool IRSimpleSpecializationKey::operator==(IRSimpleSpecializationKey const& other) const
{
auto valCount = vals.Count();
diff --git a/source/slang/ir-clone.h b/source/slang/ir-clone.h
index ce5ebed42..bafbfa69d 100644
--- a/source/slang/ir-clone.h
+++ b/source/slang/ir-clone.h
@@ -127,6 +127,19 @@ IRInst* cloneInst(
/// Clone `oldDecoration` and attach the clone to `newParent`.
///
+ /// Uses `module` to allocate any new instructions.
+ ///
+void cloneDecoration(
+ IRDecoration* oldDecoration,
+ IRInst* newParent,
+ IRModule* module);
+
+ /// Clone `oldDecoration` and attach the clone to `newParent`.
+ ///
+ /// Uses the module of `newParent` to allocate any new instructions,
+ /// so that `newParent` must already be installed somewhere
+ /// in the ownership hierarchy of an existing module.
+ ///
void cloneDecoration(
IRDecoration* oldDecoration,
IRInst* newParent);
diff --git a/source/slang/ir-inst-defs.h b/source/slang/ir-inst-defs.h
index 5ac7bd24e..f2393b2b3 100644
--- a/source/slang/ir-inst-defs.h
+++ b/source/slang/ir-inst-defs.h
@@ -400,6 +400,7 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0)
INST(VulkanCallablePayloadDecoration, vulkanCallablePayload, 0, 0)
INST(EarlyDepthStencilDecoration, earlyDepthStencil, 0, 0)
INST(GloballyCoherentDecoration, globallyCoherent, 0, 0)
+ INST(PreciseDecoration, precise, 0, 0)
INST(PatchConstantFuncDecoration, patchConstantFunc, 1, 0)
/// An `[entryPoint]` decoration marks a function that represents a shader entry point.
diff --git a/source/slang/ir-insts.h b/source/slang/ir-insts.h
index 26a5b32be..ab333f2be 100644
--- a/source/slang/ir-insts.h
+++ b/source/slang/ir-insts.h
@@ -226,6 +226,7 @@ struct IRRequireGLSLExtensionDecoration : IRDecoration
IR_SIMPLE_DECORATION(ReadNoneDecoration)
IR_SIMPLE_DECORATION(EarlyDepthStencilDecoration)
IR_SIMPLE_DECORATION(GloballyCoherentDecoration)
+IR_SIMPLE_DECORATION(PreciseDecoration)
/// A decoration that marks a value as having linkage.
///
diff --git a/source/slang/ir-ssa.cpp b/source/slang/ir-ssa.cpp
index 8c5db68fe..624454a43 100644
--- a/source/slang/ir-ssa.cpp
+++ b/source/slang/ir-ssa.cpp
@@ -2,6 +2,7 @@
#include "ir-ssa.h"
#include "ir.h"
+#include "ir-clone.h"
#include "ir-insts.h"
namespace Slang {
@@ -350,21 +351,36 @@ IRInst* readVar(
SSABlockInfo* blockInfo,
IRVar* var);
-/// Try to take any name hint on `var` and apply it to `val`.
-///
-/// Doesn't do anything if `val` already has a name hint,
-/// or if `var` doesn't have one to transfer over.
-///
-void maybeApplyNameHint(
- ConstructSSAContext* context,
+ /// Try to copy any relevant decorations from `var` over to `val`.
+ ///
+static void cloneRelevantDecorations(
IRVar* var,
IRInst* val)
{
- if( auto nameHint = var->findDecoration<IRNameHintDecoration>() )
+ // Copy selected decorations over from the original
+ // variable to the SSA variable, when doing so is
+ // required for semantics.
+ //
+ for( auto decoration : var->getDecorations() )
{
- if( !val->findDecoration<IRNameHintDecoration>() )
+ switch(decoration->op)
{
- context->getBuilder()->addNameHintDecoration(val, nameHint->getName());
+ default:
+ // Ignore most decorations.
+ //
+ // TODO: Should we include or exclude by default?
+ break;
+
+ case kIROp_PreciseDecoration:
+ case kIROp_NameHintDecoration:
+ // Copy these decorations if the target doesn't already have them,
+ // but don't make duplicate decorations on the target.
+ //
+ if( !val->findDecorationImpl(decoration->op) )
+ {
+ cloneDecoration(decoration, val, var->getModule());
+ }
+ break;
}
}
}
@@ -383,7 +399,7 @@ PhiInfo* addPhi(
valueType = context->getBuilder()->getRateQualifiedType(rate, valueType);
}
IRParam* phi = builder->createParam(valueType);
- maybeApplyNameHint(context, var, phi);
+ cloneRelevantDecorations(var, phi);
RefPtr<PhiInfo> phiInfo = new PhiInfo();
context->phiInfos.Add(phi, phiInfo);
@@ -808,7 +824,7 @@ void processBlock(
// block.
auto val = readVar(context, blockInfo, var);
- maybeApplyNameHint(context, var, val);
+ cloneRelevantDecorations(var, val);
val = applyAccessChain(context, &blockInfo->builder, ptrArg, val);
diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp
index 0cc5b2a5c..0864d4bfe 100644
--- a/source/slang/lower-to-ir.cpp
+++ b/source/slang/lower-to-ir.cpp
@@ -1680,6 +1680,10 @@ void addVarDecorations(
{
builder->addSimpleDecoration<IRGloballyCoherentDecoration>(inst);
}
+ else if(as<PreciseModifier>(mod))
+ {
+ builder->addSimpleDecoration<IRPreciseDecoration>(inst);
+ }
else if(auto formatAttr = as<FormatAttribute>(mod))
{
builder->addFormatDecoration(inst, formatAttr->format);
diff --git a/source/slang/modifier-defs.h b/source/slang/modifier-defs.h
index 1fa3a1f8e..01ed792a9 100644
--- a/source/slang/modifier-defs.h
+++ b/source/slang/modifier-defs.h
@@ -275,7 +275,7 @@ SIMPLE_SYNTAX_CLASS(HLSLSampleModifier, InterpolationModeModifier)
SIMPLE_SYNTAX_CLASS(HLSLCentroidModifier, InterpolationModeModifier)
// HLSL `precise` modifier
-SIMPLE_SYNTAX_CLASS(HLSLPreciseModifier, Modifier)
+SIMPLE_SYNTAX_CLASS(PreciseModifier, Modifier)
// HLSL `shared` modifier (which is used by the effect system,
// and shouldn't be confused with `groupshared`)
diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp
index 5cb712489..a6063a2a9 100644
--- a/source/slang/parser.cpp
+++ b/source/slang/parser.cpp
@@ -4663,7 +4663,7 @@ namespace Slang
MODIFIER(linear, HLSLLinearModifier);
MODIFIER(sample, HLSLSampleModifier);
MODIFIER(centroid, HLSLCentroidModifier);
- MODIFIER(precise, HLSLPreciseModifier);
+ MODIFIER(precise, PreciseModifier);
MODIFIER(shared, HLSLEffectSharedModifier);
MODIFIER(groupshared, HLSLGroupSharedModifier);
MODIFIER(static, HLSLStaticModifier);