summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2018-03-12 12:40:16 -0400
committerTim Foley <tfoleyNV@users.noreply.github.com>2018-03-12 09:40:16 -0700
commit51bc468959b5ab8103c196adaabcafdb5d0b3feb (patch)
tree118ae98567e335e9f8e6d9a35fe38402609fb5f9 /source
parenta22b7520745334ecef3cbd920a0331f01c905935 (diff)
Prevent duplicating global values during specialization (#439)
* Prevent duplicating global values during specialization. * Fixup checking code
Diffstat (limited to 'source')
-rw-r--r--source/slang/ir.cpp36
1 files changed, 34 insertions, 2 deletions
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp
index aeea83760..7a58dca27 100644
--- a/source/slang/ir.cpp
+++ b/source/slang/ir.cpp
@@ -4848,10 +4848,31 @@ namespace Slang
}
+ void checkIRDuplicate(IRParentInst* moduleInst, Name* mangledName)
+ {
+#ifdef _DEBUG
+ for (auto child : moduleInst->getChildren())
+ {
+ if (child->op == kIROp_Func)
+ {
+ auto extName = ((IRGlobalValue*)child)->mangledName;
+ if (extName == mangledName ||
+ (extName && mangledName &&
+ extName->text == mangledName->text))
+ SLANG_UNEXPECTED("duplicate global var");
+ }
+ }
+#else
+ SLANG_UNREFERENCED_PARAMETER(moduleInst);
+ SLANG_UNREFERENCED_PARAMETER(mangledName);
+#endif
+ }
+
void cloneFunctionCommon(
IRSpecContextBase* context,
IRFunc* clonedFunc,
- IRFunc* originalFunc)
+ IRFunc* originalFunc,
+ bool checkDuplicate = true)
{
// First clone all the simple properties.
clonedFunc->mangledName = originalFunc->mangledName;
@@ -4871,6 +4892,8 @@ namespace Slang
//
// TODO: This isn't really a good requirement to place on the IR...
clonedFunc->removeFromParent();
+ if (checkDuplicate)
+ checkIRDuplicate(context->getModule()->getModuleInst(), clonedFunc->mangledName);
clonedFunc->insertAtEnd(context->getModule()->getModuleInst());
}
@@ -4958,7 +4981,7 @@ namespace Slang
IRFunc* cloneSimpleFuncWithoutRegistering(IRSpecContextBase* context, IRFunc* originalFunc)
{
auto clonedFunc = context->builder->createFunc();
- cloneFunctionCommon(context, clonedFunc, originalFunc);
+ cloneFunctionCommon(context, clonedFunc, originalFunc, false);
return clonedFunc;
}
@@ -5137,6 +5160,15 @@ namespace Slang
Name* mangledName,
IRGlobalValue* originalVal)
{
+ // If the global value being cloned is already in target module, don't clone
+ // Why checking this?
+ // When specializing a generic function G (which is already in target module),
+ // where G calls a normal function F (which is already in target module),
+ // then when we are making a copy of G via cloneFuncCommom(), it will recursively clone F,
+ // however we don't want to make a duplicate of F in the target module.
+ if (originalVal->getParent() == context->getModule()->getModuleInst())
+ return originalVal;
+
// Check if we've already cloned this value, for the case where
// an original value has already been established.
IRInst* clonedVal = nullptr;