Tackling a section of code with poor performance in extraction.

The extSubtree() routine cuts a layout into squares and extracts
each separately, checking for subcell interactions.  In each
square it parses all labels looking for unconnected ones.  This
section of code not only parses all labels M x N times, but it
then marks interaction areas where there may be none, forcing
additional unnecessary processing.  This commit makes the first
quick optimization, which is to change the return value of
DRCFindInteractions() from boolean to integer, allowing it to
return a value indicating that there are no subcells in the
area.  This prevents the loop through labels from happening in
cases where there can never be interactions.  More to come.
This commit is contained in:
Tim Edwards 2022-02-20 17:36:49 -05:00
parent 7d601628e4
commit f8390b78f8
6 changed files with 37 additions and 30 deletions

View File

@ -1 +1 @@
8.3.269 8.3.270

View File

@ -828,8 +828,8 @@ CIFGenSubcells(def, area, output)
if (square.r_ytop > totalArea.r_ytop) if (square.r_ytop > totalArea.r_ytop)
square.r_ytop = totalArea.r_ytop; square.r_ytop = totalArea.r_ytop;
GEO_EXPAND(&square, radius, &square); GEO_EXPAND(&square, radius, &square);
if (!DRCFindInteractions(def, &square, radius, if (DRCFindInteractions(def, &square, radius,
&interaction)) continue; &interaction) <= 0) continue;
/* We've found an interaction. Flatten it into CIFTotalUse, then /* We've found an interaction. Flatten it into CIFTotalUse, then
* make CIF from what's flattened. Yank extra material to * make CIF from what's flattened. Yank extra material to

View File

@ -3824,8 +3824,8 @@ CmdDrc(w, cmd)
window = ToolGetBoxWindow(&rootArea, (int *) NULL); window = ToolGetBoxWindow(&rootArea, (int *) NULL);
if (window == NULL) return; if (window == NULL) return;
rootUse = (CellUse *) window->w_surfaceID; rootUse = (CellUse *) window->w_surfaceID;
if (!DRCFindInteractions(rootUse->cu_def, &rootArea, if (DRCFindInteractions(rootUse->cu_def, &rootArea,
radius, &area)) radius, &area) <= 0)
{ {
TxPrintf("No interactions in this area for that radius.\n"); TxPrintf("No interactions in this area for that radius.\n");
return; return;

View File

@ -365,8 +365,10 @@ drcSubCheckPaint(scx, curUse)
* or subcell-paint interactions in a given area of a given cell. * or subcell-paint interactions in a given area of a given cell.
* *
* Results: * Results:
* Returns TRUE if there were any interactions in the given * Returns 1 if there were any interactions in the given
* area, FALSE if there were none. * area, 0 if there were none, and -1 if there were no subcells
* in the area (implies no interactions, but may be treated
* differently, e.g., by extSubtree()).
* *
* Side effects: * Side effects:
* The parameter interaction is set to contain the bounding box * The parameter interaction is set to contain the bounding box
@ -381,7 +383,7 @@ drcSubCheckPaint(scx, curUse)
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
bool int
DRCFindInteractions(def, area, radius, interaction) DRCFindInteractions(def, area, radius, interaction)
CellDef *def; /* Cell to check for interactions. */ CellDef *def; /* Cell to check for interactions. */
Rect *area; /* Area of def to check for interacting Rect *area; /* Area of def to check for interacting
@ -425,7 +427,7 @@ DRCFindInteractions(def, area, radius, interaction)
* have overlapping bounding boxes without overlapping paint. * have overlapping bounding boxes without overlapping paint.
*/ */
if (GEO_RECTNULL(&drcSubIntArea)) return FALSE; if (GEO_RECTNULL(&drcSubIntArea)) return -1;
use = NULL; use = NULL;
/* If errors are being propagated up from child to parent, */ /* If errors are being propagated up from child to parent, */
@ -447,15 +449,15 @@ DRCFindInteractions(def, area, radius, interaction)
scx.scx_trans = GeoIdentityTransform; scx.scx_trans = GeoIdentityTransform;
scx.scx_area = drcSubIntArea; scx.scx_area = drcSubIntArea;
if (DBTreeSrCells(&scx, 0, drcSubCheckPaint, (ClientData) &use) == 0) if (DBTreeSrCells(&scx, 0, drcSubCheckPaint, (ClientData) &use) == 0)
return FALSE; return 0;
} }
/* OK, no more excuses, there's really an interaction area here. */ /* OK, no more excuses, there's really an interaction area here. */
*interaction = drcSubIntArea; *interaction = drcSubIntArea;
GeoClip(interaction, area); GeoClip(interaction, area);
if (GEO_RECTNULL(interaction)) return FALSE; if (GEO_RECTNULL(interaction)) return 0;
return TRUE; return 1;
} }
/* /*
@ -757,7 +759,7 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg)
/* Find all the interactions in the square, and clip to the error /* Find all the interactions in the square, and clip to the error
* area we're interested in. */ * area we're interested in. */
if (!DRCFindInteractions(def, &cliparea, DRCTechHalo, &intArea)) if (DRCFindInteractions(def, &cliparea, DRCTechHalo, &intArea) <= 0)
{ {
/* Added May 4, 2008---if there are no subcells, run the /* Added May 4, 2008---if there are no subcells, run the
* basic check over the area of the erasebox. * basic check over the area of the erasebox.

View File

@ -271,9 +271,9 @@ extern void DRCWhy();
extern void DRCPrintStats(); extern void DRCPrintStats();
extern void DRCCheck(); extern void DRCCheck();
extern DRCCountList *DRCCount(); extern DRCCountList *DRCCount();
extern int DRCFind(); extern int DRCFind();
extern void DRCCatchUp(); extern void DRCCatchUp();
extern bool DRCFindInteractions(); extern int DRCFindInteractions();
extern int DRCBasicCheck(); extern int DRCBasicCheck();
extern void DRCOffGridError(); extern void DRCOffGridError();

View File

@ -165,7 +165,7 @@ extSubtree(parentUse, reg, f)
HierExtractArg ha; HierExtractArg ha;
Rect r, rlab, rbloat, *b; Rect r, rlab, rbloat, *b;
Label *lab; Label *lab;
bool result; int result;
int cuts, totcuts; int cuts, totcuts;
float pdone, plast; float pdone, plast;
SearchContext scx; SearchContext scx;
@ -233,21 +233,26 @@ extSubtree(parentUse, reg, f)
// any geometry in the cell and therefore do not get flagged by // any geometry in the cell and therefore do not get flagged by
// DRCFindInteractions(). // DRCFindInteractions().
for (lab = def->cd_labels; lab; lab = lab->lab_next) if (result != -1)
if (GEO_OVERLAP(&lab->lab_rect, &r) || GEO_TOUCH(&lab->lab_rect, &r)) { {
// Clip the label area to the area of rbloat for (lab = def->cd_labels; lab; lab = lab->lab_next)
rlab = lab->lab_rect; if (GEO_OVERLAP(&lab->lab_rect, &r) ||
GEOCLIP(&rlab, &rbloat); GEO_TOUCH(&lab->lab_rect, &r))
if (!result) { {
// If result == FALSE then ha.ha_interArea is invalid. /* Clip the label area to the area of rbloat */
ha.ha_interArea = rlab; rlab = lab->lab_rect;
result = TRUE; GEOCLIP(&rlab, &rbloat);
if (result == 0) {
/* If result == FALSE then ha.ha_interArea is invalid. */
ha.ha_interArea = rlab;
result = 1;
}
else
GeoIncludeAll(&rlab, &ha.ha_interArea);
} }
else }
result |= GeoIncludeAll(&rlab, &ha.ha_interArea);
}
if (result) if (result > 0)
{ {
ha.ha_clipArea = ha.ha_interArea; ha.ha_clipArea = ha.ha_interArea;
GEOCLIP(&ha.ha_clipArea, &r); GEOCLIP(&ha.ha_clipArea, &r);
@ -255,7 +260,7 @@ extSubtree(parentUse, reg, f)
extSubtreeClippedArea += RECTAREA(&ha.ha_clipArea); extSubtreeClippedArea += RECTAREA(&ha.ha_clipArea);
extSubtreeInteraction(&ha); extSubtreeInteraction(&ha);
} }
else else if (result != -1)
{ {
/* Make sure substrate connections have been handled */ /* Make sure substrate connections have been handled */
/* even if there were no other interactions found. */ /* even if there were no other interactions found. */