From a810aa31f5f366d69e67be96c169fec7d6041df7 Mon Sep 17 00:00:00 2001 From: Yong He Date: Thu, 7 Mar 2024 17:28:19 -0800 Subject: Link-time constant and linkage API improvements. (#3708) * Link-time constant and linkage API improvements. * Fix. * Allow module name to be empty. * Fix. * Fix. * Fix compile error. --- source/slang/slang-check-expr.cpp | 44 +++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 16 deletions(-) (limited to 'source/slang/slang-check-expr.cpp') diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp index 33a1fa680..8b6fe76c7 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -1411,6 +1411,7 @@ namespace Slang IntVal* SemanticsVisitor::tryConstantFoldExpr( SubstExpr invokeExpr, + ConstantFoldingKind kind, ConstantFoldingCircularityInfo* circularityInfo) { // We need all the operands to the expression @@ -1448,7 +1449,7 @@ namespace Slang for(Index a = 0; a < argCount; ++a) { auto argExpr = getArg(invokeExpr, a); - auto argVal = tryFoldIntegerConstantExpression(argExpr, circularityInfo); + auto argVal = tryFoldIntegerConstantExpression(argExpr, kind, circularityInfo); if (!argVal) return nullptr; @@ -1647,6 +1648,7 @@ namespace Slang IntVal* SemanticsVisitor::tryConstantFoldDeclRef( DeclRef const& declRef, + ConstantFoldingKind kind, ConstantFoldingCircularityInfo* circularityInfo) { auto decl = declRef.getDecl(); @@ -1657,9 +1659,17 @@ namespace Slang // In HLSL, `const` is used to mark compile-time constant expressions. if(!decl->hasModifier()) return nullptr; - // Extern const is not considered compile-time constant by the front-end. if (decl->hasModifier()) - return nullptr; + { + // Extern const is not considered compile-time constant by the front-end. + if (kind == ConstantFoldingKind::CompileTime) + return nullptr; + // But if we are OK with link-time constants, we can still fold it into a val. + auto rs = m_astBuilder->getOrCreate( + declRef.substitute(m_astBuilder, declRef.getDecl()->getType()), + declRef); + return rs; + } if (isInterfaceRequirement(decl)) { @@ -1678,11 +1688,12 @@ namespace Slang ensureDecl(declRef.getDecl(), DeclCheckState::DefinitionChecked); ConstantFoldingCircularityInfo newCircularityInfo(decl, circularityInfo); - return tryConstantFoldExpr(getInitExpr(m_astBuilder, declRef), &newCircularityInfo); + return tryConstantFoldExpr(getInitExpr(m_astBuilder, declRef), kind, &newCircularityInfo); } IntVal* SemanticsVisitor::tryConstantFoldExpr( SubstExpr expr, + ConstantFoldingKind kind, ConstantFoldingCircularityInfo* circularityInfo) { @@ -1738,7 +1749,7 @@ namespace Slang // are defined in a way that can be used as a constant expression: if(auto varRef = declRef.as()) { - return tryConstantFoldDeclRef(varRef, circularityInfo); + return tryConstantFoldDeclRef(varRef, kind, circularityInfo); } else if(auto enumRef = declRef.as()) { @@ -1750,7 +1761,7 @@ namespace Slang return nullptr; ConstantFoldingCircularityInfo newCircularityInfo(enumCaseDecl, circularityInfo); - return tryConstantFoldExpr(tagExpr, &newCircularityInfo); + return tryConstantFoldExpr(tagExpr, kind, &newCircularityInfo); } } } @@ -1762,7 +1773,7 @@ namespace Slang return nullptr; if (!isScalarIntegerType(substType)) return nullptr; - auto val = tryConstantFoldExpr(getArg(castExpr, 0), circularityInfo); + auto val = tryConstantFoldExpr(getArg(castExpr, 0), kind, circularityInfo); if (val) { if (!castExpr.getExpr()->type) @@ -1777,7 +1788,7 @@ namespace Slang } else if (auto invokeExpr = expr.as()) { - auto val = tryConstantFoldExpr(invokeExpr, circularityInfo); + auto val = tryConstantFoldExpr(invokeExpr, kind, circularityInfo); if (val) return val; } @@ -1803,6 +1814,7 @@ namespace Slang IntVal* SemanticsVisitor::tryFoldIntegerConstantExpression( SubstExpr expr, + ConstantFoldingKind kind, ConstantFoldingCircularityInfo* circularityInfo) { // Check if type is acceptable for an integer constant expression @@ -1812,10 +1824,10 @@ namespace Slang // Consider operations that we might be able to constant-fold... // - return tryConstantFoldExpr(expr, circularityInfo); + return tryConstantFoldExpr(expr, kind, circularityInfo); } - IntVal* SemanticsVisitor::CheckIntegerConstantExpression(Expr* inExpr, IntegerConstantExpressionCoercionType coercionType, Type* expectedType, DiagnosticSink* sink) + IntVal* SemanticsVisitor::CheckIntegerConstantExpression(Expr* inExpr, IntegerConstantExpressionCoercionType coercionType, Type* expectedType, ConstantFoldingKind kind, DiagnosticSink* sink) { // No need to issue further errors if the expression didn't even type-check. if(IsErrorExpr(inExpr)) return nullptr; @@ -1840,7 +1852,7 @@ namespace Slang // No need to issue further errors if the type coercion failed. if(IsErrorExpr(expr)) return nullptr; - auto result = tryFoldIntegerConstantExpression(expr, nullptr); + auto result = tryFoldIntegerConstantExpression(expr, kind, nullptr); if (!result && sink) { sink->diagnose(expr, Diagnostics::expectedIntegerConstantNotConstant); @@ -1848,12 +1860,12 @@ namespace Slang return result; } - IntVal* SemanticsVisitor::CheckIntegerConstantExpression(Expr* inExpr, IntegerConstantExpressionCoercionType coercionType, Type* expectedType) + IntVal* SemanticsVisitor::CheckIntegerConstantExpression(Expr* inExpr, IntegerConstantExpressionCoercionType coercionType, Type* expectedType, ConstantFoldingKind kind) { - return CheckIntegerConstantExpression(inExpr, coercionType, expectedType, getSink()); + return CheckIntegerConstantExpression(inExpr, coercionType, expectedType, kind, getSink()); } - IntVal* SemanticsVisitor::CheckEnumConstantExpression(Expr* expr) + IntVal* SemanticsVisitor::CheckEnumConstantExpression(Expr* expr, ConstantFoldingKind kind) { // No need to issue further errors if the expression didn't even type-check. if(IsErrorExpr(expr)) return nullptr; @@ -1861,7 +1873,7 @@ namespace Slang // No need to issue further errors if the type coercion failed. if(IsErrorExpr(expr)) return nullptr; - auto result = tryConstantFoldExpr(expr, nullptr); + auto result = tryConstantFoldExpr(expr, kind, nullptr); if (!result) { getSink()->diagnose(expr, Diagnostics::expectedIntegerConstantNotConstant); @@ -1936,7 +1948,7 @@ namespace Slang IntVal* elementCount = nullptr; if (subscriptExpr->indexExprs.getCount() == 1) { - elementCount = CheckIntegerConstantExpression(subscriptExpr->indexExprs[0], IntegerConstantExpressionCoercionType::AnyInteger, nullptr); + elementCount = CheckIntegerConstantExpression(subscriptExpr->indexExprs[0], IntegerConstantExpressionCoercionType::AnyInteger, nullptr, ConstantFoldingKind::LinkTime); } else if (subscriptExpr->indexExprs.getCount() != 0) { -- cgit v1.2.3