This patch implements a new class that can be used to allow optimizations to be selectively disabled at compile time in response to a command line option. This will allow a binary search for optimization related failures to be performed directly from LLVM-based front end invocations without otherwise changing the compiler's behavior.
I still need to create some sort of test for this code, but I wanted to begin the review process first to see if I could get consensus on this general approach.
The behavior is fairly straightforward. Any time a pass manager is about to run an optimization, it checks with the OptBisect helper object to see whether or not the pass should be run. The OptBisect tool maintains a simple count of the number of optimizations that have been run and returns false once the specified limit is reached. I am also providing (but not currently using) a function that optimization passes can use to opt in for a finer grained control of individual optimizations.
I am making two choices that require discussion. First, I am currently allowing all analysis passes (at least with the legacy pass manager) regardless of the optimization count. My reasoning is that any given analysis pass may be needed for some later pass that cannot be skipped (register allocation passes, for instance) and so running all analysis passes avoids the problem of anticipating such dependencies. I am not currently attempting this with the new pass manager as I haven't yet found a clean and simple way to identify passes as analysis passes at the level at which I am hooking in to the control flow.
Second, because the intention is that a front end will be able to produce object files while using the bisecting feature, certain passes may not be skipped. I am currently handling this in a very clumsy and fragile way by maintaining a hard-coded list of passes which must not be skipped. I hope that a better solution can be implemented and that the current approach will be short-lived (perhaps not even surviving the review process). My list is almost certainly incomplete and may also be overly conservative. I generated the list using x86 targets. Additional passes will need to be added for other target architectures.