@@ -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}
@@ -2768,17 +2790,32 @@ void dbNetwork::staToDb(const Pin* pin,
27682790 iterm = nullptr ;
27692791 bterm = nullptr ;
27702792 moditerm = nullptr ;
2771- if (pin) {
2772- dbObject* obj = reinterpret_cast <dbObject*>(const_cast <Pin*>(pin));
2773- dbObjectType type = obj->getObjectType ();
2774- if (type == dbITermObj) {
2775- iterm = static_cast <dbITerm*>(obj);
2776- } else if (type == dbBTermObj) {
2777- bterm = static_cast <dbBTerm*>(obj);
2778- } else if (type == dbModITermObj) {
2779- moditerm = static_cast <dbModITerm*>(obj);
2780- } else {
2781- logger_->error (ORD, 2018 , " Pin is not ITerm or BTerm or modITerm." );
2793+
2794+ // Get the value of the tag
2795+ std::uintptr_t pointer_with_tag = reinterpret_cast <std::uintptr_t >(pin);
2796+ PinPointerTags tag_value
2797+ = static_cast <PinPointerTags>(pointer_with_tag & kPointerTagMask );
2798+
2799+ // Cast to char* and avoid casting an integral type to pointer type
2800+ // by doing pointer arithmetic. Compiler apparently prefer this sytle.
2801+ const char * char_pointer_pin = reinterpret_cast <const char *>(pin);
2802+ char * pointer_without_tag = const_cast <char *>(
2803+ char_pointer_pin - static_cast <std::uintptr_t >(tag_value));
2804+
2805+ if (pointer_without_tag) {
2806+ switch (tag_value) {
2807+ case PinPointerTags::kDbIterm :
2808+ iterm = reinterpret_cast <dbITerm*>(pointer_without_tag);
2809+ break ;
2810+ case PinPointerTags::kDbBterm :
2811+ bterm = reinterpret_cast <dbBTerm*>(pointer_without_tag);
2812+ break ;
2813+ case PinPointerTags::kDbModIterm :
2814+ moditerm = reinterpret_cast <dbModITerm*>(pointer_without_tag);
2815+ break ;
2816+ case PinPointerTags::kNone :
2817+ logger_->error (ORD, 2018 , " Pin is not ITerm or BTerm or modITerm." );
2818+ break ;
27822819 }
27832820 }
27842821}
@@ -2941,7 +2978,10 @@ Instance* dbNetwork::dbToSta(dbModInst* inst) const
29412978
29422979Pin* dbNetwork::dbToSta (dbModITerm* mod_iterm) const
29432980{
2944- return reinterpret_cast <Pin*>(mod_iterm);
2981+ char * unaligned_pointer = reinterpret_cast <char *>(mod_iterm);
2982+ return reinterpret_cast <Pin*>(
2983+ unaligned_pointer
2984+ + static_cast <std::uintptr_t >(PinPointerTags::kDbModIterm ));
29452985}
29462986
29472987Net* dbNetwork::dbToSta (dbModNet* net) const
@@ -2986,12 +3026,18 @@ const Net* dbNetwork::dbToSta(const dbModNet* net) const
29863026
29873027Pin* dbNetwork::dbToSta (dbBTerm* bterm) const
29883028{
2989- return reinterpret_cast <Pin*>(bterm);
3029+ char * unaligned_pointer = reinterpret_cast <char *>(bterm);
3030+ return reinterpret_cast <Pin*>(
3031+ unaligned_pointer
3032+ + static_cast <std::uintptr_t >(PinPointerTags::kDbBterm ));
29903033}
29913034
29923035Pin* dbNetwork::dbToSta (dbITerm* iterm) const
29933036{
2994- return reinterpret_cast <Pin*>(iterm);
3037+ char * unaligned_pointer = reinterpret_cast <char *>(iterm);
3038+ return reinterpret_cast <Pin*>(
3039+ unaligned_pointer
3040+ + static_cast <std::uintptr_t >(PinPointerTags::kDbIterm ));
29953041}
29963042
29973043Term* dbNetwork::dbToStaTerm (dbBTerm* bterm) const
@@ -3687,9 +3733,12 @@ void dbNetwork::hierarchicalConnect(dbITerm* source_pin,
36873733 }
36883734 if (dest_mod_net) {
36893735 dlogHierConnReusingConnection (dest_db_module, dest_mod_net);
3690- dbNet* dest_flat_net = flatNet ((Pin*) dest_pin);
3691- disconnectPin ((Pin*) dest_pin);
3692- connectPin ((Pin*) dest_pin, (Net*) dest_flat_net, (Net*) dest_mod_net);
3736+ Pin* sta_dest_pin = dbToSta (dest_pin);
3737+ dbNet* dest_flat_net = flatNet (sta_dest_pin);
3738+ disconnectPin (sta_dest_pin);
3739+ connectPin (sta_dest_pin,
3740+ (Net*) dest_flat_net,
3741+ (Net*) dest_mod_net); // jk: check
36933742 return ;
36943743 }
36953744 }
@@ -3746,14 +3795,15 @@ void dbNetwork::hierarchicalConnect(dbITerm* source_pin,
37463795 dlogHierConnCreatingTopNet (connection_name, highest_common_module);
37473796
37483797 // Get base name of source_pin_flat_net
3749- dbNet* source_pin_flat_net = flatNet ((Pin*) source_pin);
3798+ Pin* sta_source_pin = dbToSta (source_pin);
3799+ dbNet* source_pin_flat_net = flatNet (sta_source_pin);
37503800 const char * base_name = name (dbToSta (source_pin_flat_net));
37513801
37523802 // Create and connect dbModNet
37533803 source_db_mod_net = dbModNet::create (highest_common_module, base_name);
37543804 top_mod_dest->connect (source_db_mod_net);
3755- disconnectPin ((Pin*) source_pin );
3756- connectPin ((Pin*) source_pin ,
3805+ disconnectPin (sta_source_pin );
3806+ connectPin (sta_source_pin ,
37573807 (Net*) source_pin_flat_net,
37583808 (Net*) source_db_mod_net);
37593809 top_net = source_db_mod_net;
@@ -3775,22 +3825,25 @@ void dbNetwork::hierarchicalConnect(dbITerm* source_pin,
37753825 // the hiearchy tree
37763826
37773827 // reassociate the dest pin
3778- dbModNet* dest_pin_mod_net = hierNet ((Pin*) dest_pin);
3828+
3829+ Pin* sta_dest_pin = dbToSta (dest_pin);
3830+ dbModNet* dest_pin_mod_net = hierNet (sta_dest_pin);
37793831 if (dest_pin_mod_net) {
3780- dbNet* dest_pin_flat_net = flatNet ((Pin*) dest_pin );
3832+ dbNet* dest_pin_flat_net = flatNet (sta_dest_pin );
37813833 dlogHierConnReassociatingDstPin (dest_pin_flat_net, dest_pin_mod_net);
37823834 dest_pin->disconnect ();
37833835 connectPin (
3784- (Pin*) dest_pin , (Net*) dest_pin_flat_net, (Net*) dest_pin_mod_net);
3836+ sta_dest_pin , (Net*) dest_pin_flat_net, (Net*) dest_pin_mod_net);
37853837 }
37863838
37873839 // reassociate the source pin
3788- dbModNet* source_pin_mod_net = hierNet ((Pin*) source_pin);
3840+ Pin* sta_source_pin = dbToSta (source_pin);
3841+ dbModNet* source_pin_mod_net = hierNet (sta_source_pin);
37893842 if (source_pin_mod_net) {
3790- dbNet* source_pin_flat_net = flatNet ((Pin*) source_pin );
3843+ dbNet* source_pin_flat_net = flatNet (sta_source_pin );
37913844 dlogHierConnReassociatingSrcPin (source_pin_flat_net, source_pin_mod_net);
37923845 source_pin->disconnect ();
3793- connectPin ((Pin*) source_pin ,
3846+ connectPin (sta_source_pin ,
37943847 (Net*) source_pin_flat_net,
37953848 (Net*) source_pin_mod_net);
37963849 }
0 commit comments