From f8390b78f88d72e3d51f8a226e15d75bccf23b33 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sun, 20 Feb 2022 17:36:49 -0500 Subject: [PATCH] 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. --- VERSION | 2 +- cif/CIFhier.c | 4 ++-- commands/CmdCD.c | 4 ++-- drc/DRCsubcell.c | 18 ++++++++++-------- drc/drc.h | 4 ++-- extract/ExtSubtree.c | 35 ++++++++++++++++++++--------------- 6 files changed, 37 insertions(+), 30 deletions(-) diff --git a/VERSION b/VERSION index ac6cd144..45f4fa96 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.269 +8.3.270 diff --git a/cif/CIFhier.c b/cif/CIFhier.c index e51d5894..09fd8f05 100644 --- a/cif/CIFhier.c +++ b/cif/CIFhier.c @@ -828,8 +828,8 @@ CIFGenSubcells(def, area, output) if (square.r_ytop > totalArea.r_ytop) square.r_ytop = totalArea.r_ytop; GEO_EXPAND(&square, radius, &square); - if (!DRCFindInteractions(def, &square, radius, - &interaction)) continue; + if (DRCFindInteractions(def, &square, radius, + &interaction) <= 0) continue; /* We've found an interaction. Flatten it into CIFTotalUse, then * make CIF from what's flattened. Yank extra material to diff --git a/commands/CmdCD.c b/commands/CmdCD.c index fb59a10c..f873e43b 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -3824,8 +3824,8 @@ CmdDrc(w, cmd) window = ToolGetBoxWindow(&rootArea, (int *) NULL); if (window == NULL) return; rootUse = (CellUse *) window->w_surfaceID; - if (!DRCFindInteractions(rootUse->cu_def, &rootArea, - radius, &area)) + if (DRCFindInteractions(rootUse->cu_def, &rootArea, + radius, &area) <= 0) { TxPrintf("No interactions in this area for that radius.\n"); return; diff --git a/drc/DRCsubcell.c b/drc/DRCsubcell.c index 89fb7317..34f49223 100644 --- a/drc/DRCsubcell.c +++ b/drc/DRCsubcell.c @@ -365,8 +365,10 @@ drcSubCheckPaint(scx, curUse) * or subcell-paint interactions in a given area of a given cell. * * Results: - * Returns TRUE if there were any interactions in the given - * area, FALSE if there were none. + * Returns 1 if there were any interactions in the given + * 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: * The parameter interaction is set to contain the bounding box @@ -381,7 +383,7 @@ drcSubCheckPaint(scx, curUse) * ---------------------------------------------------------------------------- */ -bool +int DRCFindInteractions(def, area, radius, interaction) CellDef *def; /* Cell to check for interactions. */ 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. */ - if (GEO_RECTNULL(&drcSubIntArea)) return FALSE; + if (GEO_RECTNULL(&drcSubIntArea)) return -1; use = NULL; /* 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_area = drcSubIntArea; if (DBTreeSrCells(&scx, 0, drcSubCheckPaint, (ClientData) &use) == 0) - return FALSE; + return 0; } /* OK, no more excuses, there's really an interaction area here. */ *interaction = drcSubIntArea; GeoClip(interaction, area); - if (GEO_RECTNULL(interaction)) return FALSE; - return TRUE; + if (GEO_RECTNULL(interaction)) return 0; + return 1; } /* @@ -757,7 +759,7 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg) /* Find all the interactions in the square, and clip to the error * 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 * basic check over the area of the erasebox. diff --git a/drc/drc.h b/drc/drc.h index abcc2b40..1fed06c4 100644 --- a/drc/drc.h +++ b/drc/drc.h @@ -271,9 +271,9 @@ extern void DRCWhy(); extern void DRCPrintStats(); extern void DRCCheck(); extern DRCCountList *DRCCount(); -extern int DRCFind(); +extern int DRCFind(); extern void DRCCatchUp(); -extern bool DRCFindInteractions(); +extern int DRCFindInteractions(); extern int DRCBasicCheck(); extern void DRCOffGridError(); diff --git a/extract/ExtSubtree.c b/extract/ExtSubtree.c index 24196d05..916f5177 100644 --- a/extract/ExtSubtree.c +++ b/extract/ExtSubtree.c @@ -165,7 +165,7 @@ extSubtree(parentUse, reg, f) HierExtractArg ha; Rect r, rlab, rbloat, *b; Label *lab; - bool result; + int result; int cuts, totcuts; float pdone, plast; SearchContext scx; @@ -233,21 +233,26 @@ extSubtree(parentUse, reg, f) // any geometry in the cell and therefore do not get flagged by // DRCFindInteractions(). - for (lab = def->cd_labels; lab; lab = lab->lab_next) - if (GEO_OVERLAP(&lab->lab_rect, &r) || GEO_TOUCH(&lab->lab_rect, &r)) { - // Clip the label area to the area of rbloat - rlab = lab->lab_rect; - GEOCLIP(&rlab, &rbloat); - if (!result) { - // If result == FALSE then ha.ha_interArea is invalid. - ha.ha_interArea = rlab; - result = TRUE; + if (result != -1) + { + for (lab = def->cd_labels; lab; lab = lab->lab_next) + if (GEO_OVERLAP(&lab->lab_rect, &r) || + GEO_TOUCH(&lab->lab_rect, &r)) + { + /* Clip the label area to the area of rbloat */ + rlab = lab->lab_rect; + 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; GEOCLIP(&ha.ha_clipArea, &r); @@ -255,7 +260,7 @@ extSubtree(parentUse, reg, f) extSubtreeClippedArea += RECTAREA(&ha.ha_clipArea); extSubtreeInteraction(&ha); } - else + else if (result != -1) { /* Make sure substrate connections have been handled */ /* even if there were no other interactions found. */