From d82992e30d5985001870e00afdf27091f59464f2 Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 10 Apr 2023 13:43:18 -0700 Subject: Cleaner impl of unary stdlib derivative functions. (#2785) * Cleaner impl of unary stdlib derivative functions. * fixup * Fix. --------- Co-authored-by: Yong He --- source/slang/slang-ir-inline.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'source/slang/slang-ir-inline.cpp') diff --git a/source/slang/slang-ir-inline.cpp b/source/slang/slang-ir-inline.cpp index d8486d7aa..5223e35cf 100644 --- a/source/slang/slang-ir-inline.cpp +++ b/source/slang/slang-ir-inline.cpp @@ -49,13 +49,26 @@ struct InliningPassBase changed = considerCallSite(call); } - // Note: we defensively iterate through the child instructions - // so that even if `child` gets removed (because of inlining) - // we automatically start at the next instruction after it. + // Note: we iterate until no more changes can be applied. + // This is defensive against changes made by inlining one callsite + // and make sure we get to process all callsites. // - for (auto child : inst->getModifiableChildren()) + for (;;) { - changed |= considerAllCallSitesRec(child); + bool changedInThisIteration = false; + // Note: getModifiableChildren will skip any insts that are no + // longer the chhild of `inst`. If we process one callsite, the + // remaining insts of the block will be moved into a different + // block and therefore we won't process them during this iteration. + // However, those callsites will eventually be processed + // by the outer loop. + for (auto child : inst->getModifiableChildren()) + { + changedInThisIteration = considerAllCallSitesRec(child); + changed |= changedInThisIteration; + } + if (!changedInThisIteration) + break; } return changed; } -- cgit v1.2.3