|
96 | 96 | // |
97 | 97 |
|
98 | 98 | #include "ir/drop.h" |
| 99 | +#include "ir/effects.h" |
99 | 100 | #include "ir/eh-utils.h" |
100 | 101 | #include "ir/find_all.h" |
101 | 102 | #include "ir/local-graph.h" |
@@ -272,6 +273,8 @@ struct InstrumentationProcessor : public WalkerPass<PostWalker<Sub>> { |
272 | 273 | // The condition before the instrumentation (a pointer to it, so we can |
273 | 274 | // replace it). |
274 | 275 | Expression** originalCondition; |
| 276 | + // The local that the original condition is stored in temporarily. |
| 277 | + Index tempLocal; |
275 | 278 | // The call to the logging that the instrumentation added. |
276 | 279 | Call* call; |
277 | 280 | }; |
@@ -330,7 +333,7 @@ struct InstrumentationProcessor : public WalkerPass<PostWalker<Sub>> { |
330 | 333 | return {}; |
331 | 334 | } |
332 | 335 | // Great, this is indeed a prior instrumentation. |
333 | | - return Instrumentation{&set->value, call}; |
| 336 | + return Instrumentation{&set->value, set->index, call}; |
334 | 337 | } |
335 | 338 | }; |
336 | 339 |
|
@@ -374,7 +377,24 @@ struct DeInstrumentBranchHints |
374 | 377 | // IR, and the original condition is still used in another place, until |
375 | 378 | // we remove the logging calls; since we will remove the calls anyhow, we |
376 | 379 | // just need some valid IR there). |
377 | | - std::swap(curr->condition, *info->originalCondition); |
| 380 | + // |
| 381 | + // Check for dangerous effects in the condition we are about to replace, |
| 382 | + // to avoid a situation where the condition looks like this: |
| 383 | + // |
| 384 | + // (set $temp (original condition)) |
| 385 | + // ..effects.. |
| 386 | + // (local.get $temp) |
| 387 | + // |
| 388 | + // We cannot replace all this with the original condition, as it would |
| 389 | + // remove the effects. |
| 390 | + EffectAnalyzer effects(getPassOptions(), *getModule(), curr->condition); |
| 391 | + // The only condition we allow is a write to the temp local from the |
| 392 | + // instrumentation, which getInstrumentation() verified has no other uses |
| 393 | + // than us. |
| 394 | + effects.localsWritten.erase(info->tempLocal); |
| 395 | + if (!effects.hasUnremovableSideEffects()) { |
| 396 | + std::swap(curr->condition, *info->originalCondition); |
| 397 | + } |
378 | 398 | } |
379 | 399 | } |
380 | 400 |
|
@@ -403,6 +423,20 @@ struct DeInstrumentBranchHints |
403 | 423 | } |
404 | 424 | } |
405 | 425 | } |
| 426 | + |
| 427 | + void doWalkModule(Module* module) { |
| 428 | + auto logBranchImport = getLogBranchImport(module); |
| 429 | + if (!logBranchImport) { |
| 430 | + Fatal() |
| 431 | + << "No branch hint logging import found. Was this code instrumented?"; |
| 432 | + } |
| 433 | + |
| 434 | + // Mark the log-branch import as having no side effects - we are removing it |
| 435 | + // entirely here, and its effect should not stop us when we compute effects. |
| 436 | + module->getFunction(logBranchImport)->effects = std::make_shared<EffectAnalyzer>(getPassOptions(), *module); |
| 437 | + |
| 438 | + InstrumentationProcessor<DeInstrumentBranchHints>::doWalkModule(module); |
| 439 | + } |
406 | 440 | }; |
407 | 441 |
|
408 | 442 | } // anonymous namespace |
|
0 commit comments