BTW, so that we don't have to completely retrace our steps, this topic was also discussed in depth on Python-Ideas in May 2014: https://firstname.lastname@example.org/thread/X6VCB2E...
On 4/6/20 6:56 AM, Ned Batchelder wrote:
On 4/6/20 5:41 AM, Mark Shannon wrote:
On 05/04/2020 12:47 pm, Ned Batchelder wrote:
On 4/3/20 11:13 AM, joannah nanjekye wrote:
Hey all, From my CS theory, a control flow graph models a program flow and one of its main characteristics is it has one entry and exit point. IIRC, CPython’s compilation process involves generation of a control flow graph.
Contrary to peephole optimizations, optimizations on the control flow graph are more global allowing us to have complex and global optimizations like branch and checkpoint eliminations etc.
I have seen several implementations of control flow optimizations. The one I am familiar with is the V8 control flow optimizer.
I tried to investigate this for one of my directed courses last fall but I want to know if there are people who have been thinking about this for CPython and what their thoughts are.
Please make it possible to disable any optimizations. Sometimes programs are run to understand the program, not for speed (for example, during debugging, or coverage measurement.)
I have to disagree. The behavior of a program should not depend on whether a flag is set or not. It makes debugging harder, IMO, if the behavior changes depending on some flag.
I agree. But perhaps we need to be clearer what we mean by behavior. I don't think an optimizer should change the behavior of a program, that is, the results it produces. If an optimizer meets that criterion, then enabling or disabling it doesn't affect the behavior of the program.
For example, `pass` statements should never be executed. This is an "optimization", but it is easier to understand if `pass` is never executed. It becomes confusing it "executes" some of the time, depending on some compiler flag.
IMO, a coverage tool should be not rely on `pass`, `while True:` and other similarly trivial statements existing in the bytecode. By "trivial statements", I mean any unconditional control flow statements, conditional control flow statements with a constant test, "pass", and any expression statements that are constant and without side effect.
The results of a coverage tool depend very much on exactly which lines get executed. If an optimizer decides it can skip a certain line, then the coverage results will show that line as unexecuted. This alarms users, and causes bug reports. See https://bugs.python.org/issue2506 for an example that has caused me headaches since 2008.
When you work in C, do you ever use the -O0 flag to disable optimizations? If so, why do you use it? Why does Python not have the same problems, and why does it not deserve a similar solution?
E.g. the following statements are "trivial": try: while False: pass 1 + 1
On the other hand, other more powerful optimization should always preserve the observable behavior of the program. Since the observable behavior is unchanged, there would be no need to turn them off.
My point is that coverage measurement is a different kind of observation. Please don't overlook developers' needs in this regard.