summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/hlsl.meta.slang2
-rw-r--r--source/slang/hlsl.meta.slang.h4
-rw-r--r--source/slang/ir-legalize-types.cpp66
-rw-r--r--source/slang/ir-specialize.cpp48
-rw-r--r--source/slang/ir.cpp71
-rw-r--r--source/slang/ir.h8
6 files changed, 131 insertions, 68 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 4044600aa..a12e45c36 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -1036,10 +1036,12 @@ __generic<let N : int> float noise(vector<float, N> x);
/// is more semantically "correct."
__target_intrinsic(glsl, nonuniformEXT)
__glsl_extension(GL_EXT_nonuniform_qualifier)
+[__readNone]
uint NonUniformResourceIndex(uint index);
__target_intrinsic(glsl, nonuniformEXT)
__glsl_extension(GL_EXT_nonuniform_qualifier)
+[__readNone]
int NonUniformResourceIndex(int index);
// Normalize a vector
diff --git a/source/slang/hlsl.meta.slang.h b/source/slang/hlsl.meta.slang.h
index 1342badb8..a82a733ac 100644
--- a/source/slang/hlsl.meta.slang.h
+++ b/source/slang/hlsl.meta.slang.h
@@ -1112,10 +1112,12 @@ SLANG_RAW("/// the user's responsibility, so that the default behavior of the la
SLANG_RAW("/// is more semantically \"correct.\"\n")
SLANG_RAW("__target_intrinsic(glsl, nonuniformEXT)\n")
SLANG_RAW("__glsl_extension(GL_EXT_nonuniform_qualifier)\n")
+SLANG_RAW("[__readNone]\n")
SLANG_RAW("uint NonUniformResourceIndex(uint index);\n")
SLANG_RAW("\n")
SLANG_RAW("__target_intrinsic(glsl, nonuniformEXT)\n")
SLANG_RAW("__glsl_extension(GL_EXT_nonuniform_qualifier)\n")
+SLANG_RAW("[__readNone]\n")
SLANG_RAW("int NonUniformResourceIndex(int index);\n")
SLANG_RAW("\n")
SLANG_RAW("// Normalize a vector\n")
@@ -1529,7 +1531,7 @@ for (int aa = 0; aa < kBaseBufferAccessLevelCount; ++aa)
sb << "};\n";
}
-SLANG_RAW("#line 1456 \"hlsl.meta.slang\"")
+SLANG_RAW("#line 1458 \"hlsl.meta.slang\"")
SLANG_RAW("\n")
SLANG_RAW("\n")
SLANG_RAW("\n")
diff --git a/source/slang/ir-legalize-types.cpp b/source/slang/ir-legalize-types.cpp
index 0c1465fb4..00b8109ee 100644
--- a/source/slang/ir-legalize-types.cpp
+++ b/source/slang/ir-legalize-types.cpp
@@ -560,6 +560,60 @@ static LegalVal wrapBufferValue(
}
}
+static IRType* getPointedToType(
+ IRTypeLegalizationContext* context,
+ IRType* ptrType)
+{
+ auto valueType = tryGetPointedToType(context->builder, ptrType);
+ if( !valueType )
+ {
+ SLANG_UNEXPECTED("expected a pointer type during type legalization");
+ }
+ return valueType;
+}
+
+static LegalType getPointedToType(
+ IRTypeLegalizationContext* context,
+ LegalType type)
+{
+ switch( type.flavor )
+ {
+ case LegalType::Flavor::none:
+ return LegalType();
+
+ case LegalType::Flavor::simple:
+ return LegalType::simple(getPointedToType(context, type.getSimple()));
+
+ case LegalType::Flavor::implicitDeref:
+ return type.getImplicitDeref()->valueType;
+
+ case LegalType::Flavor::pair:
+ {
+ auto pairType = type.getPair();
+ auto ordinary = getPointedToType(context, pairType->ordinaryType);
+ auto special = getPointedToType(context, pairType->specialType);
+ return LegalType::pair(ordinary, special, pairType->pairInfo);
+ }
+
+ case LegalType::Flavor::tuple:
+ {
+ auto tupleType = type.getTuple();
+ RefPtr<TuplePseudoType> resultTuple = new TuplePseudoType();
+ for( auto ee : tupleType->elements )
+ {
+ TuplePseudoType::Element resultElement;
+ resultElement.key = ee.key;
+ resultElement.type = getPointedToType(context, ee.type);
+ }
+ return LegalType::tuple(resultTuple);
+ }
+
+ default:
+ SLANG_UNEXPECTED("unhandled case in type legalization");
+ UNREACHABLE_RETURN(LegalType());
+ }
+}
+
static LegalVal legalizeFieldAddress(
IRTypeLegalizationContext* context,
LegalType type,
@@ -678,8 +732,8 @@ static LegalVal legalizeFieldAddress(
// adding an implicit dereference on top of that.
//
auto implicitDerefVal = legalPtrOperand.getImplicitDeref();
-
- return LegalVal::implicitDeref(legalizeFieldExtract(context,type, implicitDerefVal, fieldKey));
+ auto valueType = getPointedToType(context, type);
+ return LegalVal::implicitDeref(legalizeFieldExtract(context, valueType, implicitDerefVal, fieldKey));
}
default:
@@ -816,7 +870,6 @@ static LegalVal legalizeGetElement(
indexOperand);
}
-
static LegalVal legalizeGetElementPtr(
IRTypeLegalizationContext* context,
LegalType type,
@@ -914,10 +967,15 @@ static LegalVal legalizeGetElementPtr(
// instead (and then wrap the element value with an
// implicit dereference).
//
+ // The result type for our `getElement` instruction needs
+ // to be the type *pointed to* by `type`, and not `type.
+ //
+ auto valueType = getPointedToType(context, type);
+
auto implicitDerefVal = legalPtrOperand.getImplicitDeref();
return LegalVal::implicitDeref(legalizeGetElement(
context,
- type,
+ valueType,
implicitDerefVal,
indexOperand));
}
diff --git a/source/slang/ir-specialize.cpp b/source/slang/ir-specialize.cpp
index 7a129a03b..e491eaa31 100644
--- a/source/slang/ir-specialize.cpp
+++ b/source/slang/ir-specialize.cpp
@@ -1153,54 +1153,6 @@ struct SpecializationContext
}
}
- /// Given a type being used as pointer, try to determine the type it points to.
- IRType* tryGetPointedToType(
- IRBuilder* builder,
- IRType* type)
- {
- // The "true" pointers and the pointer-like stdlib types are the easy cases.
- if( auto ptrType = as<IRPtrTypeBase>(type) )
- {
- return ptrType->getValueType();
- }
- else if( auto ptrLikeType = as<IRPointerLikeType>(type) )
- {
- return ptrLikeType->getElementType();
- }
- //
- // A more interesting case arises when we have a `BindExistentials<P<T>, ...>`
- // where `P<T>` is a pointer(-like) type.
- //
- else if( auto bindExistentials = as<IRBindExistentialsType>(type) )
- {
- // We know that `BindExistentials` won't introduce its own
- // existential type parameters, nor will any of the pointer(-like)
- // type constructors `P`.
- //
- // Thus we know that the type that is pointed to should be
- // the same as `BindExistentials<T, ...>`.
- //
- auto baseType = bindExistentials->getBaseType();
- if( auto baseElementType = tryGetPointedToType(builder, baseType) )
- {
- UInt existentialArgCount = bindExistentials->getExistentialArgCount();
- List<IRInst*> existentialArgs;
- for( UInt ii = 0; ii < existentialArgCount; ++ii )
- {
- existentialArgs.Add(bindExistentials->getExistentialArg(ii));
- }
- return builder->getBindExistentialsType(
- baseElementType,
- existentialArgCount,
- existentialArgs.Buffer());
- }
- }
-
- // TODO: We may need to handle other cases here.
-
- return nullptr;
- }
-
void maybeSpecializeLoad(IRLoad* inst)
{
auto ptrArg = inst->ptr.get();
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp
index 677429e32..3f6f8e0a3 100644
--- a/source/slang/ir.cpp
+++ b/source/slang/ir.cpp
@@ -236,6 +236,60 @@ namespace Slang
return nullptr;
}
+ // IRPtrTypeBase
+
+ IRType* tryGetPointedToType(
+ IRBuilder* builder,
+ IRType* type)
+ {
+ if( auto rateQualType = as<IRRateQualifiedType>(type) )
+ {
+ type = rateQualType->getDataType();
+ }
+
+ // The "true" pointers and the pointer-like stdlib types are the easy cases.
+ if( auto ptrType = as<IRPtrTypeBase>(type) )
+ {
+ return ptrType->getValueType();
+ }
+ else if( auto ptrLikeType = as<IRPointerLikeType>(type) )
+ {
+ return ptrLikeType->getElementType();
+ }
+ //
+ // A more interesting case arises when we have a `BindExistentials<P<T>, ...>`
+ // where `P<T>` is a pointer(-like) type.
+ //
+ else if( auto bindExistentials = as<IRBindExistentialsType>(type) )
+ {
+ // We know that `BindExistentials` won't introduce its own
+ // existential type parameters, nor will any of the pointer(-like)
+ // type constructors `P`.
+ //
+ // Thus we know that the type that is pointed to should be
+ // the same as `BindExistentials<T, ...>`.
+ //
+ auto baseType = bindExistentials->getBaseType();
+ if( auto baseElementType = tryGetPointedToType(builder, baseType) )
+ {
+ UInt existentialArgCount = bindExistentials->getExistentialArgCount();
+ List<IRInst*> existentialArgs;
+ for( UInt ii = 0; ii < existentialArgCount; ++ii )
+ {
+ existentialArgs.Add(bindExistentials->getExistentialArg(ii));
+ }
+ return builder->getBindExistentialsType(
+ baseElementType,
+ existentialArgCount,
+ existentialArgs.Buffer());
+ }
+ }
+
+ // TODO: We may need to handle other cases here.
+
+ return nullptr;
+ }
+
// IRBlock
@@ -2395,21 +2449,8 @@ namespace Slang
// results) at the "default" rate of the parent function,
// unless a subsequent analysis pass constraints it.
- IRType* valueType = nullptr;
- if(auto ptrType = as<IRPtrTypeBase>(ptr->getDataType()))
- {
- valueType = ptrType->getValueType();
- }
- else if(auto ptrLikeType = as<IRPointerLikeType>(ptr->getDataType()))
- {
- valueType = ptrLikeType->getElementType();
- }
- else
- {
- // Bad!
- SLANG_ASSERT(ptrType);
- return nullptr;
- }
+ IRType* valueType = tryGetPointedToType(this, ptr->getFullType());
+ SLANG_ASSERT(valueType);
// Ugly special case: if the front-end created a variable with
// type `Ptr<@R T>` instead of `@R Ptr<T>`, then the above
diff --git a/source/slang/ir.h b/source/slang/ir.h
index 09013fe48..d4497ec91 100644
--- a/source/slang/ir.h
+++ b/source/slang/ir.h
@@ -25,6 +25,7 @@ class Layout;
class Type;
class Session;
class Name;
+struct IRBuilder;
struct IRFunc;
struct IRGlobalValueWithCode;
struct IRInst;
@@ -934,6 +935,13 @@ SIMPLE_IR_TYPE(OutType, OutTypeBase)
SIMPLE_IR_TYPE(InOutType, OutTypeBase)
SIMPLE_IR_TYPE(ExistentialBoxType, PtrTypeBase)
+ /// Get the type pointed to be `ptrType`, or `nullptr` if it is not a pointer(-like) type.
+ ///
+ /// The given IR `builder` will be used if new instructions need to be created.
+IRType* tryGetPointedToType(
+ IRBuilder* builder,
+ IRType* type);
+
struct IRFuncType : IRType
{
IRType* getResultType() { return (IRType*) getOperand(0); }