Honestly a pragmatic solution would be to have printing to stderr (debug print, logs, whatever) not be an "effect". then as an added benefit if its context is elided out in an optimization you know.
It needs to be an effect so the compiler knows how optimizations are permitted to handle it. Otherwise your print statements might appear in totally the wrong order or even not at all.
Imagine saying that certain memory stores are allowed to cross a memory barrier operation, you'd completely lose the ability to reason about concurrency around those stores.
[1] https://hackage.haskell.org/package/base-4.21.0.0/docs/Debug...