Skip to content

Sta latest 0618#372

Merged
maliberty merged 5 commits into
The-OpenROAD-Project:masterfrom
The-OpenROAD-Project-staging:sta_latest_0618
Jun 18, 2026
Merged

Sta latest 0618#372
maliberty merged 5 commits into
The-OpenROAD-Project:masterfrom
The-OpenROAD-Project-staging:sta_latest_0618

Conversation

@dsengupta0628

Copy link
Copy Markdown
Contributor

Update from latest codes in Parallaxsw/OpenSTA

James Cherry and others added 5 commits June 13, 2026 16:31
Signed-off-by: James Cherry <cherry@CerezoBook.local>
Signed-off-by: James Cherry <cherry@CerezoBook.local>
Signed-off-by: James Cherry <cherry@CerezoBook.local>
Signed-off-by: James Cherry <cherry@CerezoBook.local>
@dsengupta0628 dsengupta0628 self-assigned this Jun 18, 2026
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ dsengupta0628
❌ James Cherry


James Cherry seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

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

Copy link
Copy Markdown

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 introduces support for bidirectional port paths and input delay reference pin edges by creating virtual edges in the timing graph. While these changes improve timing analysis accuracy, several critical issues were identified during the review. First, there are potential null pointer dereferences in Graph::makeInstDrvrWireEdges and Sdc::ensureInputDelayRefPinEdges if the lookup for pin vertices returns null. Second, the virtual edges created for input delay reference pins are never cleaned up when SDC constraints are cleared or re-read, which can lead to memory leaks and performance degradation. Implementing a helper method to delete these virtual edges during cleanup is highly recommended.

Comment thread graph/Graph.cc
Comment on lines +253 to +259
if (network_->isTopInstance(inst)
&& network_->direction(pin)->isBidirect()) {
Vertex *bidir_load, *bidir_drvr;
pinVertices(pin, bidir_load, bidir_drvr);
Edge *edge = makeEdge(bidir_load, bidir_drvr, TimingArcSet::wireTimingArcSet());
edge->setIsBidirectPortPath(true);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Potential null pointer dereference. If bidir_load or bidir_drvr is null (for example, if the pin is a power or ground pin, or if the vertices were not created), calling makeEdge will dereference a null pointer when calling id(from) or id(to). A null check should be added before creating the edge.

    if (network_->isTopInstance(inst)
        && network_->direction(pin)->isBidirect()) {
      Vertex *bidir_load, *bidir_drvr;
      pinVertices(pin, bidir_load, bidir_drvr);
      if (bidir_load && bidir_drvr) {
        Edge *edge = makeEdge(bidir_load, bidir_drvr, TimingArcSet::wireTimingArcSet());
        edge->setIsBidirectPortPath(true);
      }
    }

Comment thread sdc/Sdc.cc
Comment on lines +2824 to +2841
Sdc::ensureInputDelayRefPinEdges()
{
if (have_input_delay_ref_pins_) {
for (InputDelay *input_delay : input_delays_) {
const Pin *ref_pin = input_delay->refPin();
if (ref_pin
&& !input_delay->refPinEdgesExist()) {
Vertex *ref_pin_vertex = graph_->pinLoadVertex(ref_pin);
for (const Pin *pin : input_delay->leafPins()) {
Vertex *input_vertex = graph_->pinDrvrVertex(pin);
graph_->makeEdge(ref_pin_vertex, input_vertex,
TimingArcSet::portRefPinTimingArcSet());
}
input_delay->setRefPinEdgesExist(true);
}
}
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Potential null pointer dereference. If ref_pin_vertex or input_vertex is null (for example, if the pin is a power or ground pin, or if the vertices were not created), calling makeEdge will dereference a null pointer. Null checks should be added before creating the edge.

void
Sdc::ensureInputDelayRefPinEdges()
{
  if (have_input_delay_ref_pins_) {
    for (InputDelay *input_delay : input_delays_) {
      const Pin *ref_pin = input_delay->refPin();
      if (ref_pin
          && !input_delay->refPinEdgesExist()) {
        Vertex *ref_pin_vertex = graph_->pinLoadVertex(ref_pin);
        if (ref_pin_vertex) {
          for (const Pin *pin : input_delay->leafPins()) {
            Vertex *input_vertex = graph_->pinDrvrVertex(pin);
            if (input_vertex) {
              graph_->makeEdge(ref_pin_vertex, input_vertex,
                               TimingArcSet::portRefPinTimingArcSet());
            }
          }
        }
        input_delay->setRefPinEdgesExist(true);
      }
    }
  }
}

Comment thread sdc/Sdc.cc
@@ -287,12 +285,10 @@ Sdc::deleteConstraints()
deleteContents(input_delays_);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

When SDC constraints are cleared or re-read, the virtual edges created for input delay reference pins (TimingRole::portDelayRefPin()) are not removed from the graph. This causes virtual edges to accumulate in the graph across multiple SDC reads, leading to memory leaks and performance degradation. We should clean up these virtual edges when the input delays are deleted.

  deleteInputDelayRefPinEdges();
  deleteContents(input_delays_);

Comment thread sdc/Sdc.cc
}
}
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Implement the helper method to clean up virtual edges created for input delay reference pins.

}

void
Sdc::deleteInputDelayRefPinEdges()
{
  if (have_input_delay_ref_pins_) {
    for (InputDelay *input_delay : input_delays_) {
      const Pin *ref_pin = input_delay->refPin();
      if (ref_pin && input_delay->refPinEdgesExist()) {
        Vertex *ref_pin_vertex = graph_->pinLoadVertex(ref_pin);
        if (ref_pin_vertex) {
          for (const Pin *pin : input_delay->leafPins()) {
            Vertex *input_vertex = graph_->pinDrvrVertex(pin);
            if (input_vertex) {
              VertexOutEdgeIterator edge_iter(ref_pin_vertex, graph_);
              while (edge_iter.hasNext()) {
                Edge *edge = edge_iter.next();
                if (edge->to(graph_) == input_vertex
                    && edge->role() == TimingRole::portDelayRefPin()) {
                  graph_->deleteEdge(edge);
                  break;
                }
              }
            }
          }
        }
      }
    }
  }
}

Comment thread include/sta/Sdc.hh
InputDelay *except);
void deleteInputDelaysReferencing(const Clock *clk);
void deleteInputDelay(InputDelay *input_delay);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Declare a helper method to clean up virtual edges created for input delay reference pins when the input delays are deleted.

Suggested change
void deleteInputDelayRefPinEdges();

@maliberty maliberty merged commit 8572175 into The-OpenROAD-Project:master Jun 18, 2026
6 of 7 checks passed
@maliberty maliberty deleted the sta_latest_0618 branch June 18, 2026 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants