@@ -165,6 +165,24 @@ ObjectId dbNetwork::getDbNwkObjectId(const dbObject* object) const
165165 return 0 ;
166166}
167167
168+ // We have exactly 8 values avalible in the lower 3 bits of the
169+ // pointer due to these classes all having 8 byte alignment. Used
170+ // to avoid having to call into the database to figure out the
171+ // type information, which requires a lot of pointer indirection.
172+
173+ // Used to clear the pointer tag.
174+ static constexpr std::uintptr_t kPointerClearTag = ~(std::uintptr_t (0b111U ));
175+ // Used to get the value of the pointer tag.
176+ static constexpr std::uintptr_t kPointerTagMask = std::uintptr_t (0b111U );
177+
178+ enum class PinPointerTags : std::uintptr_t
179+ {
180+ kNone = 0U ,
181+ kDbIterm = 1U ,
182+ kDbBterm = 2U ,
183+ kDbModIterm = 3U ,
184+ };
185+
168186class DbLibraryIterator1 : public Iterator <Library*>
169187{
170188 public:
@@ -470,14 +488,14 @@ bool DbNetPinIterator::hasNext()
470488 while (iitr_ != iitr_end_) {
471489 dbITerm* iterm = *iitr_;
472490 if (!iterm->getSigType ().isSupply ()) {
473- next_ = reinterpret_cast <Pin*> (*iitr_);
491+ next_ = network_-> dbToSta (*iitr_);
474492 ++iitr_;
475493 return true ;
476494 }
477495 iitr_++;
478496 }
479497 if ((mitr_ != mitr_end_) && (network_->hasHierarchy ())) {
480- next_ = reinterpret_cast <Pin*> (*mitr_);
498+ next_ = network_-> dbToSta (*mitr_);
481499 ++mitr_;
482500 return true ;
483501 }
@@ -1212,14 +1230,17 @@ ObjectId dbNetwork::id(const Pin* pin) const
12121230
12131231 if (hierarchy_) {
12141232 // get the id for hierarchical objects using dbid.
1215- const dbObject* obj = reinterpret_cast <const dbObject*>(pin);
1233+ std::uintptr_t pointer_without_tag
1234+ = reinterpret_cast <std::uintptr_t >(pin) & kPointerClearTag ;
1235+ const dbObject* obj
1236+ = reinterpret_cast <const dbObject*>(pointer_without_tag);
12161237 return getDbNwkObjectId (obj);
12171238 }
12181239 if (iterm != nullptr ) {
12191240 return iterm->getId () << 1 ;
12201241 }
12211242 if (bterm != nullptr ) {
1222- return (bterm->getId () << 1 ) + 1 ;
1243+ return (bterm->getId () << 1 ) | 1U ;
12231244 }
12241245 return 0 ;
12251246}
@@ -2765,17 +2786,24 @@ void dbNetwork::staToDb(const Pin* pin,
27652786 iterm = nullptr ;
27662787 bterm = nullptr ;
27672788 moditerm = nullptr ;
2768- if (pin) {
2769- dbObject* obj = reinterpret_cast <dbObject*>(const_cast <Pin*>(pin));
2770- dbObjectType type = obj->getObjectType ();
2771- if (type == dbITermObj) {
2772- iterm = static_cast <dbITerm*>(obj);
2773- } else if (type == dbBTermObj) {
2774- bterm = static_cast <dbBTerm*>(obj);
2775- } else if (type == dbModITermObj) {
2776- moditerm = static_cast <dbModITerm*>(obj);
2777- } else {
2778- logger_->error (ORD, 2018 , " Pin is not ITerm or BTerm or modITerm." );
2789+ std::uintptr_t pointer_with_tag = reinterpret_cast <std::uintptr_t >(pin);
2790+ PinPointerTags tag_value
2791+ = static_cast <PinPointerTags>(pointer_with_tag & kPointerTagMask );
2792+ std::uintptr_t pointer_without_tag = pointer_with_tag & kPointerClearTag ;
2793+ if (pointer_without_tag) {
2794+ switch (tag_value) {
2795+ case PinPointerTags::kDbIterm :
2796+ iterm = reinterpret_cast <dbITerm*>(pointer_without_tag);
2797+ break ;
2798+ case PinPointerTags::kDbBterm :
2799+ bterm = reinterpret_cast <dbBTerm*>(pointer_without_tag);
2800+ break ;
2801+ case PinPointerTags::kDbModIterm :
2802+ moditerm = reinterpret_cast <dbModITerm*>(pointer_without_tag);
2803+ break ;
2804+ case PinPointerTags::kNone :
2805+ logger_->error (ORD, 2018 , " Pin is not ITerm or BTerm or modITerm." );
2806+ break ;
27792807 }
27802808 }
27812809}
@@ -2938,7 +2966,10 @@ Instance* dbNetwork::dbToSta(dbModInst* inst) const
29382966
29392967Pin* dbNetwork::dbToSta (dbModITerm* mod_iterm) const
29402968{
2941- return reinterpret_cast <Pin*>(mod_iterm);
2969+ auto mod_iterm_tagged_ptr = reinterpret_cast <std::uintptr_t >(mod_iterm);
2970+ mod_iterm_tagged_ptr
2971+ |= static_cast <std::uintptr_t >(PinPointerTags::kDbModIterm );
2972+ return reinterpret_cast <Pin*>(mod_iterm_tagged_ptr);
29422973}
29432974
29442975Net* dbNetwork::dbToSta (dbModNet* net) const
@@ -2983,12 +3014,16 @@ const Net* dbNetwork::dbToSta(const dbModNet* net) const
29833014
29843015Pin* dbNetwork::dbToSta (dbBTerm* bterm) const
29853016{
2986- return reinterpret_cast <Pin*>(bterm);
3017+ auto bterm_tagged_ptr = reinterpret_cast <std::uintptr_t >(bterm);
3018+ bterm_tagged_ptr |= static_cast <std::uintptr_t >(PinPointerTags::kDbBterm );
3019+ return reinterpret_cast <Pin*>(bterm_tagged_ptr);
29873020}
29883021
29893022Pin* dbNetwork::dbToSta (dbITerm* iterm) const
29903023{
2991- return reinterpret_cast <Pin*>(iterm);
3024+ auto iterm_tagged_ptr = reinterpret_cast <std::uintptr_t >(iterm);
3025+ iterm_tagged_ptr |= static_cast <std::uintptr_t >(PinPointerTags::kDbIterm );
3026+ return reinterpret_cast <Pin*>(iterm_tagged_ptr);
29923027}
29933028
29943029Term* dbNetwork::dbToStaTerm (dbBTerm* bterm) const
@@ -3572,9 +3607,10 @@ void dbNetwork::hierarchicalConnect(dbITerm* source_pin,
35723607 dest_mod_net = dest_moditerm->getModNet ();
35733608 }
35743609 if (dest_mod_net) {
3575- dbNet* dest_flat_net = flatNet ((Pin*) dest_pin);
3576- disconnectPin ((Pin*) dest_pin);
3577- connectPin ((Pin*) dest_pin, (Net*) dest_flat_net, (Net*) dest_mod_net);
3610+ Pin* sta_dest_pin = dbToSta (dest_pin);
3611+ dbNet* dest_flat_net = flatNet (sta_dest_pin);
3612+ disconnectPin (sta_dest_pin);
3613+ connectPin (sta_dest_pin, (Net*) dest_flat_net, (Net*) dest_mod_net);
35783614 return ;
35793615 }
35803616 }
@@ -3610,11 +3646,12 @@ void dbNetwork::hierarchicalConnect(dbITerm* source_pin,
36103646
36113647 // at leaf level make connection
36123648 if (level == 0 ) {
3613- dbModNet* source_pin_mod_net = hierNet ((Pin*) source_pin);
3649+ Pin* sta_source_pin = dbToSta (source_pin);
3650+ dbModNet* source_pin_mod_net = hierNet (sta_source_pin);
36143651 if (source_pin_mod_net) {
3615- disconnectPin ((Pin*) source_pin , (Net*) source_pin_mod_net);
3652+ disconnectPin (sta_source_pin , (Net*) source_pin_mod_net);
36163653 }
3617- connectPin ((Pin*) source_pin , (Net*) source_db_mod_net);
3654+ connectPin (sta_source_pin , (Net*) source_db_mod_net);
36183655 }
36193656
36203657 dbModInst* parent_inst = cur_module->getModInst ();
@@ -3642,11 +3679,12 @@ void dbNetwork::hierarchicalConnect(dbITerm* source_pin,
36423679 mod_bterm->setSigType (dbSigType::SIGNAL);
36433680
36443681 if (level == 0 ) {
3645- dbModNet* dest_pin_mod_net = hierNet ((Pin*) dest_pin);
3682+ Pin* sta_dest_pin = dbToSta (dest_pin);
3683+ dbModNet* dest_pin_mod_net = hierNet (sta_dest_pin);
36463684 if (dest_pin_mod_net) {
3647- disconnectPin ((Pin*) dest_pin , (Net*) dest_pin_mod_net);
3685+ disconnectPin (sta_dest_pin , (Net*) dest_pin_mod_net);
36483686 }
3649- connectPin ((Pin*) dest_pin , (Net*) dest_db_mod_net);
3687+ connectPin (sta_dest_pin , (Net*) dest_db_mod_net);
36503688 }
36513689
36523690 dbModInst* parent_inst = cur_module->getModInst ();
@@ -3670,9 +3708,10 @@ void dbNetwork::hierarchicalConnect(dbITerm* source_pin,
36703708 = dbModNet::create (highest_common_module, connection_name);
36713709 top_mod_dest->connect (source_db_mod_net);
36723710
3673- dbNet* source_pin_flat_net = flatNet ((Pin*) source_pin);
3674- disconnectPin ((Pin*) source_pin);
3675- connectPin ((Pin*) source_pin,
3711+ Pin* sta_source_pin = dbToSta (source_pin);
3712+ dbNet* source_pin_flat_net = flatNet (sta_source_pin);
3713+ disconnectPin (sta_source_pin);
3714+ connectPin (sta_source_pin,
36763715 (Net*) source_pin_flat_net,
36773716 (Net*) source_db_mod_net);
36783717 // source_pin->connect(source_db_mod_net);
@@ -3693,20 +3732,22 @@ void dbNetwork::hierarchicalConnect(dbITerm* source_pin,
36933732
36943733 // reassociate the dest pin
36953734
3696- dbModNet* dest_pin_mod_net = hierNet ((Pin*) dest_pin);
3735+ Pin* sta_dest_pin = dbToSta (dest_pin);
3736+ dbModNet* dest_pin_mod_net = hierNet (sta_dest_pin);
36973737 if (dest_pin_mod_net) {
3698- dbNet* dest_pin_flat_net = flatNet ((Pin*) dest_pin );
3738+ dbNet* dest_pin_flat_net = flatNet (sta_dest_pin );
36993739 dest_pin->disconnect ();
37003740 connectPin (
3701- (Pin*) dest_pin , (Net*) dest_pin_flat_net, (Net*) dest_pin_mod_net);
3741+ sta_dest_pin , (Net*) dest_pin_flat_net, (Net*) dest_pin_mod_net);
37023742 }
37033743
37043744 // reassociate the source pin
3705- dbModNet* source_pin_mod_net = hierNet ((Pin*) source_pin);
3745+ Pin* sta_source_pin = dbToSta (source_pin);
3746+ dbModNet* source_pin_mod_net = hierNet (sta_source_pin);
37063747 if (source_pin_mod_net) {
3707- dbNet* source_pin_flat_net = flatNet ((Pin*) source_pin );
3748+ dbNet* source_pin_flat_net = flatNet (sta_source_pin );
37083749 source_pin->disconnect ();
3709- connectPin ((Pin*) source_pin ,
3750+ connectPin (sta_source_pin ,
37103751 (Net*) source_pin_flat_net,
37113752 (Net*) source_pin_mod_net);
37123753 }
0 commit comments