Skip to content

mpl: each rtl_macro_placer call starts from a fresh hierarchy - #11625

Open
oharboe wants to merge 2 commits into
The-OpenROAD-Project:masterfrom
oharboe:mpl-rerun-fresh-hierarchy
Open

oharboe wants to merge 2 commits into
The-OpenROAD-Project:masterfrom
oharboe:mpl-rerun-fresh-hierarchy

Conversation

@oharboe

@oharboe oharboe commented Oct 4, 2026 •

Copy link
Copy Markdown
Collaborator

A completed rtl_macro_placer run releases its PhysicalHierarchy in clear(), and the tree is only created in the constructor. A second call in the same session therefore hands a null tree to the ClusteringEngine and crashes with signal 11 in setFloorplanShape().

ORFS hits this when a MACRO_PLACEMENT_TCL script places some macros with rtl_macro_placer and the macro step then calls it again. Before #11504 the second call happened to stop earlier, on MPL-0050, so the crash was hidden.

There is a second stale-state bug of the same kind. A call that finds no unfixed macro sets skip_macro_placement_, and nothing reset it. Every later call in the session then printed Skipping macro placement. and left its unfixed macros unplaced.

This PR makes init() create the hierarchy and clear the flag for each call. Every setter that writes to the tree runs after init().

Test

rerun1 is a pass/fail test with no golden log or DEF. It calls rtl_macro_placer three times on fixed_macros1 and checks the intended outcome:

  1. Call with every macro fixed.
  2. Call with MACRO_2 unfixed. Check that it is placed (LOCKED).
  3. Call again after that completed run. Check that it is placed again.
binary result
master FAIL: placed after a call with nothing to place: Expected LOCKED, got PLACED
master, without the all-fixed first call signal 11 on the second placement
this PR Summary 2 / 2 (100% pass)

The 37 existing mpl regressions pass unchanged. clang-format, tclfmt, tclint and buildifier are clean.

Seen while testing, not changed here

Each completed run adds a soft blockage per macro in commitMacroPlacementToDb() and does not remove the ones from earlier runs. After a rerun that moves a macro, a blockage stays at its old location. It is left for a separate change.

🤖 Generated with Claude Code

A completed rtl_macro_placer run releases its PhysicalHierarchy in
clear(). The tree is only created in the constructor, so a second call
in the same session handed a null tree to the ClusteringEngine and
crashed in setFloorplanShape() with signal 11. ORFS hits this when a
MACRO_PLACEMENT_TCL script places some macros with rtl_macro_placer and
the macro step then calls it again.

A call that finds no unfixed macro sets skip_macro_placement_, and
nothing reset it: every later call in the session skipped placement,
printed "Skipping macro placement." and left its unfixed macros where
they were.

init() now creates the hierarchy and clears the flag for each call.
Every setter that writes to the tree runs after init().

rerun1 calls rtl_macro_placer three times on fixed_macros1: with every
macro fixed, with one macro to place, and with it to place again after
that completed run. Before this change the last two calls skip the
macro, which stays at ( 0 0 ); the crash is reached once the flag is
reset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@oharboe
oharboe requested a review from a team as a code owner October 4, 2026 13:52
@oharboe
oharboe requested a review from joaomai October 4, 2026 13:52
@github-actions github-actions Bot added the size/S label Oct 4, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates HierRTLMP::init() to reinitialize the physical hierarchy tree and reset the skip_macro_placement_ flag on each call, ensuring that multiple runs of rtl_macro_placer in a single session behave correctly. A new integration test, rerun1, has been added to verify this behavior. No review comments were provided, so there is no additional feedback.

The test asserts what the fix is for: after a call that found every
macro fixed, and again after a completed run, the unfixed macro is
placed (LOCKED). Golden .ok/.defok files would have pinned the rest of
the output as well, including the soft blockages that accumulate over
reruns. rerun1 is a PASSFAIL test in Bazel and CMake.

On master the first check fails ("Expected LOCKED, got PLACED"); with
the first call left out, the second call crashes with signal 11.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant