diff --git a/commands/CmdFI.c b/commands/CmdFI.c index 8669ea3c..178fe9ee 100644 --- a/commands/CmdFI.c +++ b/commands/CmdFI.c @@ -1452,7 +1452,11 @@ CmdIdentify(w, cmd) return; } - if (CmdIllegalChars(cmd->tx_argv[1], "[],/", "Cell use id")) + /* NOTE: Relaxing the definition of illegal characters in cell use IDs */ + /* by allowing brackets. Possibly the list can be reduced further. */ + + /* if (CmdIllegalChars(cmd->tx_argv[1], "[],/", "Cell use id")) */ + if (CmdIllegalChars(cmd->tx_argv[1], ",/", "Cell use id")) return; if (SelEnumCells(FALSE, (int *) NULL, (SearchContext *) NULL, diff --git a/database/DBio.c b/database/DBio.c index 3f6aca45..6389eb23 100644 --- a/database/DBio.c +++ b/database/DBio.c @@ -619,6 +619,9 @@ done: } } } + /* Update timestamp flags */ + DBFlagMismatches(cellDef); + cellDef->cd_timestamp = cellStamp; if (cellStamp == 0) { @@ -869,6 +872,8 @@ DBReadBackup(name) name); return FALSE; } + /* Update timestamp flags from dbCellReadDef() */ + DBFlagMismatches(); } else { diff --git a/database/DBtimestmp.c b/database/DBtimestmp.c index 8143eced..f6900a70 100644 --- a/database/DBtimestmp.c +++ b/database/DBtimestmp.c @@ -270,6 +270,16 @@ dbStampFunc(cellDef) * processing. When DBFixMismatch is called, it will notify * the design-rule checker to recheck both wrongArea, and * the cell's eventual correct area. + * + * This routine has been modified from a poor implementation. Previously + * the parent def of all uses of the cell being checked would be marked + * for a stamp mismatch check. However, when reading a cell with large + * numbers of instances, the list of instances would be parsed for every + * instance added, leading to an O(N^2) computation. Routine DBStampMismatch() + * has been broken into two parts. DBStampMismatch() only records the + * area to be checked. DBFlagMismatches() looks at the parents of each + * celldef only once, after all instances have been read. + * * ---------------------------------------------------------------------------- */ @@ -281,18 +291,32 @@ DBStampMismatch(cellDef, wrongArea) */ { Mismatch *mm; - CellUse *parentUse; mm = (Mismatch *) mallocMagic((unsigned) (sizeof (Mismatch))); mm->mm_cellDef = cellDef; mm->mm_oldArea = *wrongArea; mm->mm_next = mismatch; mismatch = mm; +} - for (parentUse = cellDef->cd_parents; parentUse != NULL; - parentUse = parentUse->cu_nextuse) +/* + * ---------------------------------------------------------------------------- + * ---------------------------------------------------------------------------- + */ + +void +DBFlagMismatches(checkDef) + CellDef *checkDef; +{ + CellUse *parentUse; + long count; + + for (parentUse = checkDef->cd_parents; parentUse != NULL; + parentUse = parentUse->cu_nextuse) { + count++; if (parentUse->cu_parent == NULL) continue; parentUse->cu_parent->cd_flags |= CDSTAMPSCHANGED; } + TxPrintf("Diagnostic: cell %s count = %ld\n", checkDef->cd_name, count); } diff --git a/database/databaseInt.h b/database/databaseInt.h index ae3f0f63..5756c458 100644 --- a/database/databaseInt.h +++ b/database/databaseInt.h @@ -199,6 +199,7 @@ extern void DBUndoPutLabel(); extern void DBUndoEraseLabel(); extern void DBUndoCellUse(); extern void DBStampMismatch(); +extern void DBFlagMismatches(); extern void DBTechAddNameToType(); extern void dbComputeBbox();