Connectivity optimizations
Cache names of potential driving items Change a few data structures based on profiling
This commit is contained in:
parent
fc92fb076e
commit
66bdd37637
|
@ -43,6 +43,13 @@
|
||||||
#include <advanced_config.h> // for realtime connectivity switch
|
#include <advanced_config.h> // for realtime connectivity switch
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flag to enable connectivity profiling
|
||||||
|
* @ingroup trace_env_vars
|
||||||
|
*/
|
||||||
|
static const wxChar ConnProfileMask[] = wxT( "CONN_PROFILE" );
|
||||||
|
|
||||||
|
|
||||||
bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers )
|
bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers )
|
||||||
{
|
{
|
||||||
PRIORITY highest_priority = PRIORITY::INVALID;
|
PRIORITY highest_priority = PRIORITY::INVALID;
|
||||||
|
@ -227,16 +234,17 @@ std::vector<SCH_ITEM*> CONNECTION_SUBGRAPH::GetBusLabels() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wxString CONNECTION_SUBGRAPH::GetNameForDriver( SCH_ITEM* aItem ) const
|
const wxString& CONNECTION_SUBGRAPH::GetNameForDriver( SCH_ITEM* aItem )
|
||||||
{
|
{
|
||||||
wxString name;
|
if( m_driver_name_cache.count( aItem ) )
|
||||||
|
return m_driver_name_cache.at( aItem );
|
||||||
|
|
||||||
switch( aItem->Type() )
|
switch( aItem->Type() )
|
||||||
{
|
{
|
||||||
case SCH_PIN_T:
|
case SCH_PIN_T:
|
||||||
{
|
{
|
||||||
SCH_PIN* pin = static_cast<SCH_PIN*>( aItem );
|
SCH_PIN* pin = static_cast<SCH_PIN*>( aItem );
|
||||||
name = pin->GetDefaultNetName( m_sheet );
|
m_driver_name_cache[aItem] = pin->GetDefaultNetName( m_sheet );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,15 +253,17 @@ wxString CONNECTION_SUBGRAPH::GetNameForDriver( SCH_ITEM* aItem ) const
|
||||||
case SCH_HIER_LABEL_T:
|
case SCH_HIER_LABEL_T:
|
||||||
case SCH_SHEET_PIN_T:
|
case SCH_SHEET_PIN_T:
|
||||||
{
|
{
|
||||||
name = EscapeString( static_cast<SCH_TEXT*>( aItem )->GetShownText(), CTX_NETNAME );
|
m_driver_name_cache[aItem] = EscapeString( static_cast<SCH_TEXT*>( aItem )->GetShownText(),
|
||||||
|
CTX_NETNAME );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
wxFAIL_MSG( "Unhandled item type in GetNameForDriver" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return name;
|
return m_driver_name_cache.at( aItem );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -376,40 +386,45 @@ void CONNECTION_GRAPH::Reset()
|
||||||
|
|
||||||
void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnconditional )
|
void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnconditional )
|
||||||
{
|
{
|
||||||
PROF_COUNTER recalc_time;
|
PROF_COUNTER recalc_time( "CONNECTION_GRAPH::Recalculate" );
|
||||||
PROF_COUNTER update_items;
|
|
||||||
|
|
||||||
if( aUnconditional )
|
if( aUnconditional )
|
||||||
Reset();
|
Reset();
|
||||||
|
|
||||||
|
PROF_COUNTER update_items( "updateItemConnectivity" );
|
||||||
|
|
||||||
for( const SCH_SHEET_PATH& sheet : aSheetList )
|
for( const SCH_SHEET_PATH& sheet : aSheetList )
|
||||||
{
|
{
|
||||||
std::vector<SCH_ITEM*> items;
|
std::vector<SCH_ITEM*> items;
|
||||||
|
|
||||||
for( auto item : sheet.LastScreen()->Items() )
|
for( SCH_ITEM* item : sheet.LastScreen()->Items() )
|
||||||
{
|
{
|
||||||
if( item->IsConnectable() && ( aUnconditional || item->IsConnectivityDirty() ) )
|
if( item->IsConnectable() && ( aUnconditional || item->IsConnectivityDirty() ) )
|
||||||
items.push_back( item );
|
items.push_back( item );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_items.reserve( m_items.size() + items.size() );
|
||||||
|
|
||||||
updateItemConnectivity( sheet, items );
|
updateItemConnectivity( sheet, items );
|
||||||
|
|
||||||
// UpdateDanglingState() also adds connected items for SCH_TEXT
|
// UpdateDanglingState() also adds connected items for SCH_TEXT
|
||||||
sheet.LastScreen()->TestDanglingEnds( &sheet );
|
sheet.LastScreen()->TestDanglingEnds( &sheet );
|
||||||
}
|
}
|
||||||
|
|
||||||
update_items.Stop();
|
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
|
||||||
wxLogTrace( "CONN_PROFILE", "UpdateItemConnectivity() %0.4f ms", update_items.msecs() );
|
update_items.Show();
|
||||||
|
|
||||||
PROF_COUNTER build_graph;
|
PROF_COUNTER build_graph( "buildConnectionGraph" );
|
||||||
|
|
||||||
buildConnectionGraph();
|
buildConnectionGraph();
|
||||||
|
|
||||||
build_graph.Stop();
|
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
|
||||||
wxLogTrace( "CONN_PROFILE", "BuildConnectionGraph() %0.4f ms", build_graph.msecs() );
|
build_graph.Show();
|
||||||
|
|
||||||
recalc_time.Stop();
|
recalc_time.Stop();
|
||||||
wxLogTrace( "CONN_PROFILE", "Recalculate time %0.4f ms", recalc_time.msecs() );
|
|
||||||
|
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
|
||||||
|
recalc_time.Show();
|
||||||
|
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
// Pressure relief valve for release builds
|
// Pressure relief valve for release builds
|
||||||
|
@ -427,7 +442,7 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
|
||||||
void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||||
const std::vector<SCH_ITEM*>& aItemList )
|
const std::vector<SCH_ITEM*>& aItemList )
|
||||||
{
|
{
|
||||||
std::unordered_map< wxPoint, std::vector<SCH_ITEM*> > connection_map;
|
std::map< wxPoint, std::vector<SCH_ITEM*> > connection_map;
|
||||||
|
|
||||||
for( SCH_ITEM* item : aItemList )
|
for( SCH_ITEM* item : aItemList )
|
||||||
{
|
{
|
||||||
|
@ -446,7 +461,7 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||||
pin->Connection( aSheet )->Reset();
|
pin->Connection( aSheet )->Reset();
|
||||||
|
|
||||||
connection_map[ pin->GetTextPos() ].push_back( pin );
|
connection_map[ pin->GetTextPos() ].push_back( pin );
|
||||||
m_items.insert( pin );
|
m_items.emplace_back( pin );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( item->Type() == SCH_COMPONENT_T )
|
else if( item->Type() == SCH_COMPONENT_T )
|
||||||
|
@ -476,12 +491,12 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||||
m_invisible_power_pins.emplace_back( std::make_pair( aSheet, pin ) );
|
m_invisible_power_pins.emplace_back( std::make_pair( aSheet, pin ) );
|
||||||
|
|
||||||
connection_map[ pos ].push_back( pin );
|
connection_map[ pos ].push_back( pin );
|
||||||
m_items.insert( pin );
|
m_items.emplace_back( pin );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_items.insert( item );
|
m_items.emplace_back( item );
|
||||||
auto conn = item->InitializeConnection( aSheet, this );
|
auto conn = item->InitializeConnection( aSheet, this );
|
||||||
|
|
||||||
// Set bus/net property here so that the propagation code uses it
|
// Set bus/net property here so that the propagation code uses it
|
||||||
|
@ -803,37 +818,7 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
||||||
SCH_SHEET_PATH sheet = subgraph->m_sheet;
|
SCH_SHEET_PATH sheet = subgraph->m_sheet;
|
||||||
SCH_CONNECTION* connection = driver->Connection( sheet );
|
SCH_CONNECTION* connection = driver->Connection( sheet );
|
||||||
|
|
||||||
// TODO(JE) This should live in SCH_CONNECTION probably
|
connection->ConfigureFromLabel( subgraph->GetNameForDriver( driver ) );
|
||||||
switch( driver->Type() )
|
|
||||||
{
|
|
||||||
case SCH_LABEL_T:
|
|
||||||
case SCH_GLOBAL_LABEL_T:
|
|
||||||
case SCH_HIER_LABEL_T:
|
|
||||||
{
|
|
||||||
auto text = static_cast<SCH_TEXT*>( driver );
|
|
||||||
connection->ConfigureFromLabel( EscapeString( text->GetShownText(), CTX_NETNAME ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SCH_SHEET_PIN_T:
|
|
||||||
{
|
|
||||||
auto pin = static_cast<SCH_SHEET_PIN*>( driver );
|
|
||||||
connection->ConfigureFromLabel( EscapeString( pin->GetShownText(), CTX_NETNAME ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SCH_PIN_T:
|
|
||||||
{
|
|
||||||
auto pin = static_cast<SCH_PIN*>( driver );
|
|
||||||
// NOTE(JE) GetDefaultNetName is not thread-safe.
|
|
||||||
connection->ConfigureFromLabel( pin->GetDefaultNetName( sheet ) );
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
wxLogTrace( "CONN", "Driver type unsupported: %s",
|
|
||||||
driver->GetSelectMenuText( EDA_UNITS::MILLIMETRES ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
connection->SetDriver( driver );
|
connection->SetDriver( driver );
|
||||||
connection->ClearDirty();
|
connection->ClearDirty();
|
||||||
|
|
||||||
|
@ -1139,7 +1124,7 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
||||||
if( possible_driver == aSubgraph->m_driver )
|
if( possible_driver == aSubgraph->m_driver )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto c = getDefaultConnection( possible_driver, aSubgraph->m_sheet );
|
auto c = getDefaultConnection( possible_driver, aSubgraph );
|
||||||
|
|
||||||
if( c )
|
if( c )
|
||||||
{
|
{
|
||||||
|
@ -1215,9 +1200,7 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
||||||
driver->Type() == SCH_GLOBAL_LABEL_T ||
|
driver->Type() == SCH_GLOBAL_LABEL_T ||
|
||||||
driver->Type() == SCH_HIER_LABEL_T );
|
driver->Type() == SCH_HIER_LABEL_T );
|
||||||
|
|
||||||
auto text = static_cast<SCH_TEXT*>( driver );
|
if( subgraph->GetNameForDriver( driver ) == test_name )
|
||||||
|
|
||||||
if( EscapeString( text->GetShownText(), CTX_NETNAME ) == test_name )
|
|
||||||
{
|
{
|
||||||
match = true;
|
match = true;
|
||||||
break;
|
break;
|
||||||
|
@ -1551,7 +1534,7 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph )
|
||||||
if( !m_sheet_to_subgraphs_map.count( path ) )
|
if( !m_sheet_to_subgraphs_map.count( path ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for( auto candidate : m_sheet_to_subgraphs_map.at( path ) )
|
for( CONNECTION_SUBGRAPH* candidate : m_sheet_to_subgraphs_map.at( path ) )
|
||||||
{
|
{
|
||||||
if( !candidate->m_strong_driver ||
|
if( !candidate->m_strong_driver ||
|
||||||
candidate->m_hier_ports.empty() ||
|
candidate->m_hier_ports.empty() ||
|
||||||
|
@ -1560,7 +1543,7 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph )
|
||||||
|
|
||||||
for( SCH_HIERLABEL* label : candidate->m_hier_ports )
|
for( SCH_HIERLABEL* label : candidate->m_hier_ports )
|
||||||
{
|
{
|
||||||
if( label->GetShownText() == pin->GetShownText() )
|
if( candidate->GetNameForDriver( label ) == aParent->GetNameForDriver( pin ) )
|
||||||
{
|
{
|
||||||
wxLogTrace( "CONN", "%lu: found child %lu (%s)", aParent->m_code,
|
wxLogTrace( "CONN", "%lu: found child %lu (%s)", aParent->m_code,
|
||||||
candidate->m_code, candidate->m_driver_connection->Name() );
|
candidate->m_code, candidate->m_driver_connection->Name() );
|
||||||
|
@ -1582,7 +1565,7 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph )
|
||||||
if( !m_sheet_to_subgraphs_map.count( path ) )
|
if( !m_sheet_to_subgraphs_map.count( path ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for( auto candidate : m_sheet_to_subgraphs_map.at( path ) )
|
for( CONNECTION_SUBGRAPH* candidate : m_sheet_to_subgraphs_map.at( path ) )
|
||||||
{
|
{
|
||||||
if( candidate->m_hier_pins.empty() ||
|
if( candidate->m_hier_pins.empty() ||
|
||||||
visited.count( candidate ) ||
|
visited.count( candidate ) ||
|
||||||
|
@ -1598,7 +1581,7 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph )
|
||||||
if( pin_path != aParent->m_sheet )
|
if( pin_path != aParent->m_sheet )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( label->GetShownText() == pin->GetShownText() )
|
if( aParent->GetNameForDriver( label ) == candidate->GetNameForDriver( pin ) )
|
||||||
{
|
{
|
||||||
wxLogTrace( "CONN", "%lu: found additional parent %lu (%s)",
|
wxLogTrace( "CONN", "%lu: found additional parent %lu (%s)",
|
||||||
aParent->m_code, candidate->m_code,
|
aParent->m_code, candidate->m_code,
|
||||||
|
@ -1639,7 +1622,7 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph )
|
||||||
|
|
||||||
for( SCH_ITEM* driver : sg->m_drivers )
|
for( SCH_ITEM* driver : sg->m_drivers )
|
||||||
{
|
{
|
||||||
auto c = getDefaultConnection( driver, sheet );
|
auto c = getDefaultConnection( driver, sg );
|
||||||
member = matchBusMember( parent, c.get() );
|
member = matchBusMember( parent, c.get() );
|
||||||
|
|
||||||
if( member )
|
if( member )
|
||||||
|
@ -1807,8 +1790,8 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<SCH_CONNECTION>
|
std::shared_ptr<SCH_CONNECTION> CONNECTION_GRAPH::getDefaultConnection( SCH_ITEM* aItem,
|
||||||
CONNECTION_GRAPH::getDefaultConnection( SCH_ITEM* aItem, const SCH_SHEET_PATH& aSheet )
|
CONNECTION_SUBGRAPH* aSubgraph )
|
||||||
{
|
{
|
||||||
auto c = std::shared_ptr<SCH_CONNECTION>( nullptr );
|
auto c = std::shared_ptr<SCH_CONNECTION>( nullptr );
|
||||||
|
|
||||||
|
@ -1819,11 +1802,8 @@ CONNECTION_GRAPH::getDefaultConnection( SCH_ITEM* aItem, const SCH_SHEET_PATH& a
|
||||||
auto pin = static_cast<SCH_PIN*>( aItem );
|
auto pin = static_cast<SCH_PIN*>( aItem );
|
||||||
|
|
||||||
if( pin->IsPowerConnection() )
|
if( pin->IsPowerConnection() )
|
||||||
{
|
c = std::make_shared<SCH_CONNECTION>( aItem, aSubgraph->m_sheet );
|
||||||
c = std::make_shared<SCH_CONNECTION>( aItem, aSheet );
|
|
||||||
c->SetGraph( this );
|
|
||||||
c->ConfigureFromLabel( pin->GetName() );
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1831,11 +1811,7 @@ CONNECTION_GRAPH::getDefaultConnection( SCH_ITEM* aItem, const SCH_SHEET_PATH& a
|
||||||
case SCH_HIER_LABEL_T:
|
case SCH_HIER_LABEL_T:
|
||||||
case SCH_LABEL_T:
|
case SCH_LABEL_T:
|
||||||
{
|
{
|
||||||
auto text = static_cast<SCH_TEXT*>( aItem );
|
c = std::make_shared<SCH_CONNECTION>( aItem, aSubgraph->m_sheet );
|
||||||
|
|
||||||
c = std::make_shared<SCH_CONNECTION>( aItem, aSheet );
|
|
||||||
c->SetGraph( this );
|
|
||||||
c->ConfigureFromLabel( EscapeString( text->GetShownText(), CTX_NETNAME ) );
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1843,6 +1819,12 @@ CONNECTION_GRAPH::getDefaultConnection( SCH_ITEM* aItem, const SCH_SHEET_PATH& a
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( c )
|
||||||
|
{
|
||||||
|
c->SetGraph( this );
|
||||||
|
c->ConfigureFromLabel( aSubgraph->GetNameForDriver( aItem ) );
|
||||||
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1899,8 +1881,8 @@ SCH_CONNECTION* CONNECTION_GRAPH::matchBusMember( SCH_CONNECTION* aBusConnection
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CONNECTION_GRAPH::recacheSubgraphName(
|
void CONNECTION_GRAPH::recacheSubgraphName( CONNECTION_SUBGRAPH* aSubgraph,
|
||||||
CONNECTION_SUBGRAPH* aSubgraph, const wxString& aOldName )
|
const wxString& aOldName )
|
||||||
{
|
{
|
||||||
if( m_net_name_to_subgraphs_map.count( aOldName ) )
|
if( m_net_name_to_subgraphs_map.count( aOldName ) )
|
||||||
{
|
{
|
||||||
|
|
|
@ -110,7 +110,7 @@ public:
|
||||||
std::vector<SCH_ITEM*> GetBusLabels() const;
|
std::vector<SCH_ITEM*> GetBusLabels() const;
|
||||||
|
|
||||||
/// Returns the candidate net name for a driver
|
/// Returns the candidate net name for a driver
|
||||||
wxString GetNameForDriver( SCH_ITEM* aItem ) const;
|
const wxString& GetNameForDriver( SCH_ITEM* aItem );
|
||||||
|
|
||||||
/// Combines another subgraph on the same sheet into this one.
|
/// Combines another subgraph on the same sheet into this one.
|
||||||
void Absorb( CONNECTION_SUBGRAPH* aOther );
|
void Absorb( CONNECTION_SUBGRAPH* aOther );
|
||||||
|
@ -206,6 +206,9 @@ public:
|
||||||
|
|
||||||
// If not null, this indicates the subgraph on a higher level sheet that is linked to this one
|
// If not null, this indicates the subgraph on a higher level sheet that is linked to this one
|
||||||
CONNECTION_SUBGRAPH* m_hier_parent;
|
CONNECTION_SUBGRAPH* m_hier_parent;
|
||||||
|
|
||||||
|
/// A cache of escaped netnames from schematic items
|
||||||
|
std::unordered_map<SCH_ITEM*, wxString> m_driver_name_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Associates a net code with the final name of a net
|
/// Associates a net code with the final name of a net
|
||||||
|
@ -299,7 +302,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::unordered_set<SCH_ITEM*> m_items;
|
std::vector<SCH_ITEM*> m_items;
|
||||||
|
|
||||||
// The owner of all CONNECTION_SUBGRAPH objects
|
// The owner of all CONNECTION_SUBGRAPH objects
|
||||||
std::vector<CONNECTION_SUBGRAPH*> m_subgraphs;
|
std::vector<CONNECTION_SUBGRAPH*> m_subgraphs;
|
||||||
|
@ -423,10 +426,11 @@ private:
|
||||||
* Handles strong drivers (power pins and labels) only
|
* Handles strong drivers (power pins and labels) only
|
||||||
*
|
*
|
||||||
* @param aItem is an item that can generate a connection name
|
* @param aItem is an item that can generate a connection name
|
||||||
|
* @param aSubgraph is used to determine the sheet to use and retrieve the cached name
|
||||||
* @return a connection generated from the item, or nullptr if item is not valid
|
* @return a connection generated from the item, or nullptr if item is not valid
|
||||||
*/
|
*/
|
||||||
std::shared_ptr<SCH_CONNECTION> getDefaultConnection( SCH_ITEM* aItem,
|
std::shared_ptr<SCH_CONNECTION> getDefaultConnection( SCH_ITEM* aItem,
|
||||||
const SCH_SHEET_PATH& aSheet );
|
CONNECTION_SUBGRAPH* aSubgraph );
|
||||||
|
|
||||||
void recacheSubgraphName( CONNECTION_SUBGRAPH* aSubgraph, const wxString& aOldName );
|
void recacheSubgraphName( CONNECTION_SUBGRAPH* aSubgraph, const wxString& aOldName );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue