194 lines · plain
1====================================================2Using -opt-bisect-limit to debug optimization errors3====================================================4.. contents::5 :local:6 :depth: 17 8Introduction9============10 11The ``-opt-bisect-limit`` option provides a way to disable all optimization passes12above a specified limit without modifying the way in which the Pass Managers13are populated. The intention of this option is to assist in tracking down14problems where incorrect transformations during optimization result in incorrect15run-time behavior.16 17This feature is implemented on an opt-in basis. Passes which can be safely18skipped while still allowing correct code generation call a function to19check the opt-bisect limit before performing optimizations. Passes which20either must be run or do not modify the IR do not perform this check and are21therefore never skipped. Generally, this means analysis passes, passes22that are run at ``CodeGenOptLevel::None`` and passes which are required for register23allocation.24 25The ``-opt-bisect-limit`` option can be used with any tool, including front ends26such as clang, that uses the core LLVM library for optimization and code27generation. The exact syntax for invoking the option is discussed below.28 29This feature is not intended to replace other debugging tools such as bugpoint.30Rather it provides an alternate course of action when reproducing the problem31requires a complex build infrastructure that would make using bugpoint32impractical or when reproducing the failure requires a sequence of33transformations that is difficult to replicate with tools like opt and llc.34 35 36Getting Started37===============38 39The ``-opt-bisect-limit`` command-line option can be passed directly to tools such40as opt, llc and lli. The syntax is as follows:41 42::43 44 <tool name> [other options] -opt-bisect-limit=<limit>45 46If a value of -1 is used the tool will perform all optimizations but a message47will be printed to stderr for each optimization that could be skipped48indicating the index value that is associated with that optimization. To skip49optimizations, pass the value of the last optimization to be performed as the50opt-bisect-limit. All optimizations with a higher index value will be skipped.51 52In order to use the ``-opt-bisect-limit`` option with a driver that provides a53wrapper around the LLVM core library, an additional prefix option may be54required, as defined by the driver. For example, to use this option with55clang, the ``-mllvm`` prefix must be used. A typical clang invocation would look56like this:57 58::59 60 clang -O2 -mllvm -opt-bisect-limit=256 my_file.c61 62The ``-opt-bisect-limit`` option may also be applied to link-time optimizations by63using a prefix to indicate that this is a plug-in option for the linker. The64following syntax will set a bisect limit for LTO transformations:65 66::67 68 # When using lld, or ld64 (macOS)69 clang -flto -Wl,-mllvm,-opt-bisect-limit=256 my_file.o my_other_file.o70 # When using Gold71 clang -flto -Wl,-plugin-opt,-opt-bisect-limit=256 my_file.o my_other_file.o72 73LTO passes are run by a library instance invoked by the linker. Therefore any74passes run in the primary driver compilation phase are not affected by options75passed via ``-Wl,-plugin-opt`` and LTO passes are not affected by options76passed to the driver-invoked LLVM invocation via ``-mllvm``.77 78Passing ``-opt-bisect-print-ir-path=path/foo.ll`` will dump the IR to79``path/foo.ll`` when ``-opt-bisect-limit`` starts skipping passes.80 81Bisection Index Values82======================83 84The granularity of the optimizations associated with a single index value is85variable. Depending on how the optimization pass has been instrumented the86value may be associated with as much as all transformations that would have87been performed by an optimization pass on an IR unit for which it is invoked88(for instance, during a single call of ``runOnFunction`` for a ``FunctionPass``) or as89little as a single transformation. The index values may also be nested so that90if an invocation of the pass is not skipped individual transformations within91that invocation may still be skipped.92 93The order of the values assigned is guaranteed to remain stable and consistent94from one run to the next up to and including the value specified as the limit.95Above the limit value skipping of optimizations can cause a change in the96numbering, but because all optimizations above the limit are skipped this97is not a problem.98 99When an opt-bisect index value refers to an entire invocation of the run100function for a pass, the pass will query whether or not it should be skipped101each time it is invoked and each invocation will be assigned a unique value.102For example, if a ``FunctionPass`` is used with a module containing three functions103a different index value will be assigned to the pass for each of the functions104as the pass is run. The pass may be run on two functions but skipped for the105third.106 107If the pass internally performs operations on a smaller IR unit the pass must be108specifically instrumented to enable bisection at this finer level of granularity109(see below for details).110 111 112Example Usage113=============114 115.. code-block:: console116 117 $ opt -O2 -o test-opt.bc -opt-bisect-limit=16 test.ll118 119 BISECT: running pass (1) Simplify the CFG on function (g)120 BISECT: running pass (2) SROA on function (g)121 BISECT: running pass (3) Early CSE on function (g)122 BISECT: running pass (4) Infer set function attributes on module (test.ll)123 BISECT: running pass (5) Interprocedural Sparse Conditional Constant Propagation on module (test.ll)124 BISECT: running pass (6) Global Variable Optimizer on module (test.ll)125 BISECT: running pass (7) Promote Memory to Register on function (g)126 BISECT: running pass (8) Dead Argument Elimination on module (test.ll)127 BISECT: running pass (9) Combine redundant instructions on function (g)128 BISECT: running pass (10) Simplify the CFG on function (g)129 BISECT: running pass (11) Remove unused exception handling info on SCC (<<null function>>)130 BISECT: running pass (12) Function Integration/Inlining on SCC (<<null function>>)131 BISECT: running pass (13) Deduce function attributes on SCC (<<null function>>)132 BISECT: running pass (14) Remove unused exception handling info on SCC (f)133 BISECT: running pass (15) Function Integration/Inlining on SCC (f)134 BISECT: running pass (16) Deduce function attributes on SCC (f)135 BISECT: NOT running pass (17) Remove unused exception handling info on SCC (g)136 BISECT: NOT running pass (18) Function Integration/Inlining on SCC (g)137 BISECT: NOT running pass (19) Deduce function attributes on SCC (g)138 BISECT: NOT running pass (20) SROA on function (g)139 BISECT: NOT running pass (21) Early CSE on function (g)140 BISECT: NOT running pass (22) Speculatively execute instructions if target has divergent branches on function (g)141 ... etc. ...142 143 144Pass Skipping Implementation145============================146 147The ``-opt-bisect-limit`` implementation depends on individual passes opting in to148the opt-bisect process. The ``OptBisect`` object that manages the process is149entirely passive and has no knowledge of how any pass is implemented. When a150pass is run if the pass may be skipped, it should call the ``OptBisect`` object to151see if it should be skipped.152 153The ``OptBisect`` object is intended to be accessed through ``LLVMContext`` and each154Pass base class contains a helper function that abstracts the details in order155to make this check uniform across all passes. These helper functions are:156 157.. code-block:: c++158 159 bool ModulePass::skipModule(Module &M);160 bool FunctionPass::skipFunction(const Function &F);161 bool LoopPass::skipLoop(const Loop *L);162 163A ``MachineFunctionPass`` should use ``FunctionPass::skipFunction()`` as such:164 165.. code-block:: c++166 167 bool MyMachineFunctionPass::runOnMachineFunction(Function &MF) {168 if (skipFunction(*MF.getFunction())169 return false;170 // Otherwise, run the pass normally.171 }172 173In addition to checking with the ``OptBisect`` class to see if the pass should be174skipped, the ``skipFunction()``, ``skipLoop()`` and ``skipBasicBlock()`` helper functions175also look for the presence of the ``optnone`` function attribute. The calling176pass will be unable to determine whether it is being skipped because the177``optnone`` attribute is present or because the ``opt-bisect-limit`` has been178reached. This is desirable because the behavior should be the same in either179case.180 181The majority of LLVM passes which can be skipped have already been instrumented182in the manner described above. If you are adding a new pass or believe you183have found a pass which is not being included in the opt-bisect process but184should be, you can add it as described above.185 186 187Adding Finer Granularity188========================189 190Once the pass in which an incorrect transformation is performed has been191determined, it may be useful to perform further analysis in order to determine192which specific transformation is causing the problem. Debug counters193can be used for this purpose.194