From 6bb32aa976494466bd6303f8ae6e348b297edb44 Mon Sep 17 00:00:00 2001 From: Sai Praveen Bangaru <31557731+saipraveenb25@users.noreply.github.com> Date: Tue, 27 Aug 2024 21:13:00 -0400 Subject: Adds a warning for using `[PreferRecompute]` on methods that may contain side effects (#4707) * Adds a warning for using prefer-recompute on methods that contain side effects * Rename `SideEffects` -> `SideEffectBehavior` --------- Co-authored-by: Yong He --- source/slang/slang-ir-autodiff.cpp | 60 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 3 deletions(-) (limited to 'source/slang/slang-ir-autodiff.cpp') diff --git a/source/slang/slang-ir-autodiff.cpp b/source/slang/slang-ir-autodiff.cpp index b7c2037e5..bf83d8d7f 100644 --- a/source/slang/slang-ir-autodiff.cpp +++ b/source/slang/slang-ir-autodiff.cpp @@ -1123,19 +1123,33 @@ IRInst* DifferentiableTypeConformanceContext::getExtractExistensialTypeWitness( return nullptr; } - void copyCheckpointHints(IRBuilder* builder, IRGlobalValueWithCode* oldInst, IRGlobalValueWithCode* newInst) { for (auto decor = oldInst->getFirstDecoration(); decor; decor = decor->getNextDecoration()) { if (auto chkHint = as(decor)) { - SLANG_ASSERT(chkHint->getOperandCount() == 0); - builder->addDecoration(newInst, chkHint->getOp()); + cloneCheckpointHint(builder, chkHint, newInst); } } } +void cloneCheckpointHint(IRBuilder* builder, IRCheckpointHintDecoration* chkHint, IRGlobalValueWithCode* target) +{ + // Grab all the operands + List operands; + for (UCount operand = 0; operand < chkHint->getOperandCount(); operand++) + { + operands.add(chkHint->getOperand(operand)); + } + + builder->addDecoration( + target, + chkHint->getOp(), + operands.getBuffer(), + operands.getCount()); +} + void stripDerivativeDecorations(IRInst* inst) { for (auto decor = inst->getFirstDecoration(); decor; ) @@ -2096,6 +2110,46 @@ protected: }; +void checkAutodiffPatterns( + TargetProgram* target, + IRModule* module, + DiagnosticSink* sink) +{ + SLANG_UNUSED(target); + + enum SideEffectBehavior + { + Warn = 0, + Allow = 1, + }; + + // For now, we have only 1 check to see if methods that have side-effects + // are marked with prefer-recompute + // + for (auto inst : module->getGlobalInsts()) + { + if (auto func = as(inst)) + { + if (func->sourceLoc.isValid() && // Don't diagnose for synthesized functions + func->findDecoration() && + !func->findDecoration()) + { + auto preferRecomputeDecor = func->findDecoration(); + auto sideEffectBehavior = as(preferRecomputeDecor->getOperand(0))->getValue(); + + if (sideEffectBehavior == SideEffectBehavior::Allow) + continue; + + // Find function name. (don't diagnose on nameless functions) + if (auto nameHint = func->findDecoration()) + { + sink->diagnose(func, Diagnostics::potentialIssuesWithPreferRecomputeOnSideEffectMethod, nameHint->getName()); + } + } + } + } +} + bool processAutodiffCalls( TargetProgram* target, IRModule* module, -- cgit v1.2.3