@@ -165,6 +165,22 @@ ObjectId dbNetwork::getDbNwkObjectId(const dbObject* object) const
165165 return 0 ;
166166}
167167
168+ // We have exactly 8 values available 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 get the value of the pointer tag.
174+ static constexpr std::uintptr_t kPointerTagMask = std::uintptr_t (0b111U );
175+
176+ enum class PinPointerTags : std::uintptr_t
177+ {
178+ kNone = 0U ,
179+ kDbIterm = 1U ,
180+ kDbBterm = 2U ,
181+ kDbModIterm = 3U ,
182+ };
183+
168184class DbLibraryIterator1 : public Iterator <Library*>
169185{
170186 public:
@@ -470,14 +486,14 @@ bool DbNetPinIterator::hasNext()
470486 while (iitr_ != iitr_end_) {
471487 dbITerm* iterm = *iitr_;
472488 if (!iterm->getSigType ().isSupply ()) {
473- next_ = reinterpret_cast <Pin*> (*iitr_);
489+ next_ = network_-> dbToSta (*iitr_);
474490 ++iitr_;
475491 return true ;
476492 }
477493 iitr_++;
478494 }
479495 if ((mitr_ != mitr_end_) && (network_->hasHierarchy ())) {
480- next_ = reinterpret_cast <Pin*> (*mitr_);
496+ next_ = network_-> dbToSta (*mitr_);
481497 ++mitr_;
482498 return true ;
483499 }
@@ -1212,14 +1228,20 @@ ObjectId dbNetwork::id(const Pin* pin) const
12121228
12131229 if (hierarchy_) {
12141230 // get the id for hierarchical objects using dbid.
1215- const dbObject* obj = reinterpret_cast <const dbObject*>(pin);
1231+ std::uintptr_t tag_value
1232+ = reinterpret_cast <std::uintptr_t >(pin) & kPointerTagMask ;
1233+ // Need to cast to char pin to avoid compiler error for pointer
1234+ // arithmetic on incomplete types
1235+ const char * char_pin = reinterpret_cast <const char *>(pin);
1236+ const dbObject* obj
1237+ = reinterpret_cast <const dbObject*>(char_pin - tag_value);
12161238 return getDbNwkObjectId (obj);
12171239 }
12181240 if (iterm != nullptr ) {
12191241 return iterm->getId () << 1 ;
12201242 }
12211243 if (bterm != nullptr ) {
1222- return (bterm->getId () << 1 ) + 1 ;
1244+ return (bterm->getId () << 1 ) | 1U ;
12231245 }
12241246 return 0 ;
12251247}
@@ -2765,17 +2787,32 @@ void dbNetwork::staToDb(const Pin* pin,
27652787 iterm = nullptr ;
27662788 bterm = nullptr ;
27672789 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." );
2790+
2791+ // Get the value of the tag
2792+ std::uintptr_t pointer_with_tag = reinterpret_cast <std::uintptr_t >(pin);
2793+ PinPointerTags tag_value
2794+ = static_cast <PinPointerTags>(pointer_with_tag & kPointerTagMask );
2795+
2796+ // Cast to char* and avoid casting an integral type to pointer type
2797+ // by doing pointer arithmetic. Compiler apparently prefer this sytle.
2798+ const char * char_pointer_pin = reinterpret_cast <const char *>(pin);
2799+ char * pointer_without_tag = const_cast <char *>(
2800+ char_pointer_pin - static_cast <std::uintptr_t >(tag_value));
2801+
2802+ if (pointer_without_tag) {
2803+ switch (tag_value) {
2804+ case PinPointerTags::kDbIterm :
2805+ iterm = reinterpret_cast <dbITerm*>(pointer_without_tag);
2806+ break ;
2807+ case PinPointerTags::kDbBterm :
2808+ bterm = reinterpret_cast <dbBTerm*>(pointer_without_tag);
2809+ break ;
2810+ case PinPointerTags::kDbModIterm :
2811+ moditerm = reinterpret_cast <dbModITerm*>(pointer_without_tag);
2812+ break ;
2813+ case PinPointerTags::kNone :
2814+ logger_->error (ORD, 2018 , " Pin is not ITerm or BTerm or modITerm." );
2815+ break ;
27792816 }
27802817 }
27812818}
@@ -2938,7 +2975,10 @@ Instance* dbNetwork::dbToSta(dbModInst* inst) const
29382975
29392976Pin* dbNetwork::dbToSta (dbModITerm* mod_iterm) const
29402977{
2941- return reinterpret_cast <Pin*>(mod_iterm);
2978+ char * unaligned_pointer = reinterpret_cast <char *>(mod_iterm);
2979+ return reinterpret_cast <Pin*>(
2980+ unaligned_pointer
2981+ + static_cast <std::uintptr_t >(PinPointerTags::kDbModIterm ));
29422982}
29432983
29442984Net* dbNetwork::dbToSta (dbModNet* net) const
@@ -2983,12 +3023,18 @@ const Net* dbNetwork::dbToSta(const dbModNet* net) const
29833023
29843024Pin* dbNetwork::dbToSta (dbBTerm* bterm) const
29853025{
2986- return reinterpret_cast <Pin*>(bterm);
3026+ char * unaligned_pointer = reinterpret_cast <char *>(bterm);
3027+ return reinterpret_cast <Pin*>(
3028+ unaligned_pointer
3029+ + static_cast <std::uintptr_t >(PinPointerTags::kDbBterm ));
29873030}
29883031
29893032Pin* dbNetwork::dbToSta (dbITerm* iterm) const
29903033{
2991- return reinterpret_cast <Pin*>(iterm);
3034+ char * unaligned_pointer = reinterpret_cast <char *>(iterm);
3035+ return reinterpret_cast <Pin*>(
3036+ unaligned_pointer
3037+ + static_cast <std::uintptr_t >(PinPointerTags::kDbIterm ));
29923038}
29933039
29943040Term* dbNetwork::dbToStaTerm (dbBTerm* bterm) const
@@ -3572,9 +3618,10 @@ void dbNetwork::hierarchicalConnect(dbITerm* source_pin,
35723618 dest_mod_net = dest_moditerm->getModNet ();
35733619 }
35743620 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);
3621+ Pin* sta_dest_pin = dbToSta (dest_pin);
3622+ dbNet* dest_flat_net = flatNet (sta_dest_pin);
3623+ disconnectPin (sta_dest_pin);
3624+ connectPin (sta_dest_pin, (Net*) dest_flat_net, (Net*) dest_mod_net);
35783625 return ;
35793626 }
35803627 }
@@ -3610,11 +3657,12 @@ void dbNetwork::hierarchicalConnect(dbITerm* source_pin,
36103657
36113658 // at leaf level make connection
36123659 if (level == 0 ) {
3613- dbModNet* source_pin_mod_net = hierNet ((Pin*) source_pin);
3660+ Pin* sta_source_pin = dbToSta (source_pin);
3661+ dbModNet* source_pin_mod_net = hierNet (sta_source_pin);
36143662 if (source_pin_mod_net) {
3615- disconnectPin ((Pin*) source_pin , (Net*) source_pin_mod_net);
3663+ disconnectPin (sta_source_pin , (Net*) source_pin_mod_net);
36163664 }
3617- connectPin ((Pin*) source_pin , (Net*) source_db_mod_net);
3665+ connectPin (sta_source_pin , (Net*) source_db_mod_net);
36183666 }
36193667
36203668 dbModInst* parent_inst = cur_module->getModInst ();
@@ -3642,11 +3690,12 @@ void dbNetwork::hierarchicalConnect(dbITerm* source_pin,
36423690 mod_bterm->setSigType (dbSigType::SIGNAL);
36433691
36443692 if (level == 0 ) {
3645- dbModNet* dest_pin_mod_net = hierNet ((Pin*) dest_pin);
3693+ Pin* sta_dest_pin = dbToSta (dest_pin);
3694+ dbModNet* dest_pin_mod_net = hierNet (sta_dest_pin);
36463695 if (dest_pin_mod_net) {
3647- disconnectPin ((Pin*) dest_pin , (Net*) dest_pin_mod_net);
3696+ disconnectPin (sta_dest_pin , (Net*) dest_pin_mod_net);
36483697 }
3649- connectPin ((Pin*) dest_pin , (Net*) dest_db_mod_net);
3698+ connectPin (sta_dest_pin , (Net*) dest_db_mod_net);
36503699 }
36513700
36523701 dbModInst* parent_inst = cur_module->getModInst ();
@@ -3670,9 +3719,10 @@ void dbNetwork::hierarchicalConnect(dbITerm* source_pin,
36703719 = dbModNet::create (highest_common_module, connection_name);
36713720 top_mod_dest->connect (source_db_mod_net);
36723721
3673- dbNet* source_pin_flat_net = flatNet ((Pin*) source_pin);
3674- disconnectPin ((Pin*) source_pin);
3675- connectPin ((Pin*) source_pin,
3722+ Pin* sta_source_pin = dbToSta (source_pin);
3723+ dbNet* source_pin_flat_net = flatNet (sta_source_pin);
3724+ disconnectPin (sta_source_pin);
3725+ connectPin (sta_source_pin,
36763726 (Net*) source_pin_flat_net,
36773727 (Net*) source_db_mod_net);
36783728 // source_pin->connect(source_db_mod_net);
@@ -3693,20 +3743,22 @@ void dbNetwork::hierarchicalConnect(dbITerm* source_pin,
36933743
36943744 // reassociate the dest pin
36953745
3696- dbModNet* dest_pin_mod_net = hierNet ((Pin*) dest_pin);
3746+ Pin* sta_dest_pin = dbToSta (dest_pin);
3747+ dbModNet* dest_pin_mod_net = hierNet (sta_dest_pin);
36973748 if (dest_pin_mod_net) {
3698- dbNet* dest_pin_flat_net = flatNet ((Pin*) dest_pin );
3749+ dbNet* dest_pin_flat_net = flatNet (sta_dest_pin );
36993750 dest_pin->disconnect ();
37003751 connectPin (
3701- (Pin*) dest_pin , (Net*) dest_pin_flat_net, (Net*) dest_pin_mod_net);
3752+ sta_dest_pin , (Net*) dest_pin_flat_net, (Net*) dest_pin_mod_net);
37023753 }
37033754
37043755 // reassociate the source pin
3705- dbModNet* source_pin_mod_net = hierNet ((Pin*) source_pin);
3756+ Pin* sta_source_pin = dbToSta (source_pin);
3757+ dbModNet* source_pin_mod_net = hierNet (sta_source_pin);
37063758 if (source_pin_mod_net) {
3707- dbNet* source_pin_flat_net = flatNet ((Pin*) source_pin );
3759+ dbNet* source_pin_flat_net = flatNet (sta_source_pin );
37083760 source_pin->disconnect ();
3709- connectPin ((Pin*) source_pin ,
3761+ connectPin (sta_source_pin ,
37103762 (Net*) source_pin_flat_net,
37113763 (Net*) source_pin_mod_net);
37123764 }
0 commit comments