{"record":{"id":"6f5b22cf8a200339","repo":"oracle/graal","slug":"non-reducible-loop-requires-too-much-duplication","errorCode":null,"errorMessage":"Non-reducible loop requires too much duplication. Setting %s to a value higher than %s may resolve this.","messagePattern":"Non-reducible loop requires too much duplication\\. Setting (.+?) to a value higher than (.+?) may resolve this\\.","errorType":"exception","errorClass":"PermanentBailoutException","httpStatus":null,"severity":"warning","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/java/BciBlockMapping.java","lineNumber":1887,"sourceCode":"                    }\n                } else if (step instanceof DuplicationTraversalStep) {\n                    workStack.push(new DuplicationTraversalStep((DuplicationTraversalStep) step, successor));\n                } else {\n                    workStack.push(new TraversalStep(step, successor));\n                }\n                step.currentSuccessorIndex++;\n            } else {\n                // We processed all the successors of this block.\n                block.active = false;\n                assert checkBlocks(blocksNotYetAssignedId, block);\n                blocksNotYetAssignedId--;\n                if (blocksNotYetAssignedId < 0) {\n                    // this should only happen if duplication is active\n                    OptionValues options = debug.getOptions();\n                    double factor = MaxDuplicationFactor.getValue(options);\n                    duplicateBlocks += newDuplicateBlocks;\n                    if (duplicateBlocks > postJsrBlockCount * factor) {\n                        throw new PermanentBailoutException(\"Non-reducible loop requires too much duplication. \" +\n                                        \"Setting \" + MaxDuplicationFactor.getName() + \" to a value higher than \" + factor + \" may resolve this.\");\n                    }\n                    // there are new duplicate blocks, re-number\n                    debug.log(DebugContext.INFO_LEVEL, \"Re-numbering blocks to make room for duplicates (old length: %d; new blocks: %d)\", blocks.length, newDuplicateBlocks);\n                    BciBlock[] newBlocks = new BciBlock[blocks.length + newDuplicateBlocks];\n                    for (int i = 0; i < blocks.length; i++) {\n                        newBlocks[i + newDuplicateBlocks] = blocks[i];\n                        int id = blocks[i].id;\n                        assert id == UNASSIGNED_ID : id;\n                    }\n                    blocksNotYetAssignedId += newDuplicateBlocks;\n                    assert NumUtil.assertNonNegativeInt(blocksNotYetAssignedId);\n                    newDuplicateBlocks = 0;\n                    blocks = newBlocks;\n                }\n                blocks[blocksNotYetAssignedId] = block;\n                debug.log(\"computeBlockOrder(%s) -> %s\", block, block.loops);\n                debug.dump(DebugContext.DETAILED_LEVEL, this, \"After adding %s\", block);","sourceCodeStart":1869,"sourceCodeEnd":1905,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/java/BciBlockMapping.java#L1869-L1905","documentation":"Thrown when making an irreducible loop reducible would require duplicating more blocks than -Dgraal.MaxDuplicationFactor allows. The mapping pass tracks duplicateBlocks versus postJSRBlockCount * factor; exceeding the budget bails out permanently and the message explicitly tells you which flag to raise.","triggerScenarios":"Compiling a method with a non-reducible loop where the duplication pass (enabled because MaxDuplicationFactor > 1.0) generates more duplicate blocks than postJsrBlockCount * MaxDuplicationFactor before all blocks are assigned IDs (blocksNotYetAssignedId < 0).","commonSituations":"Obfuscated or generated bytecode with large irreducible regions; a MaxDuplicationFactor raised from the default (to fix error 168) but still too small for the amount of duplication the method needs; pathological CFGs where duplication cascades.","solutions":["Increase -Dgraal.MaxDuplicationFactor (e.g. from 2 to 4 or 8) as the message suggests, mindful of compile-time and memory growth.","Recompile/regenerate the class with reducible control flow so no duplication is needed.","If duplication keeps exploding, exclude the method from Graal compilation (-XX:CompileCommand=exclude) as a last resort."],"exampleFix":"# before\njava -Dgraal.MaxDuplicationFactor=2 MyApp\n# throws: Non-reducible loop requires too much duplication. Setting MaxDuplicationFactor to a value higher than 2.0 may resolve this.\n\n# after\njava -Dgraal.MaxDuplicationFactor=6 MyApp","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// permanent bailout by design; HotSpot falls back. Adjust the flag or the bytecode.","preventionTips":["Raise MaxDuplicationFactor incrementally (2 -> 4 -> 8) rather than disabling the cap entirely.","Watch compile time and memory when raising it; duplication is bounded for a reason."],"tags":["graalvm","bytecode-parsing","irreducible-loops","duplication","bailout","flags"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}