Skip to content

Commit a16b965

Browse files
committed
dbSta: Use pointer tagging instead of getObjectType()
This cuts about 5% of the runtime off OpenROAD. Just a word of warning not using dbToSta is now disallowed. I changed all occurences of this raw casts. Any use of them will now result in an error. Signed-off-by: Ethan Mahintorabi <[email protected]>
1 parent f4afc5f commit a16b965

File tree

4 files changed

+83
-37
lines changed

4 files changed

+83
-37
lines changed

src/dbSta/src/dbNetwork.cc

Lines changed: 77 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
168186
class 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

29392967
Pin* 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

29442975
Net* dbNetwork::dbToSta(dbModNet* net) const
@@ -2983,12 +3014,16 @@ const Net* dbNetwork::dbToSta(const dbModNet* net) const
29833014

29843015
Pin* 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

29893022
Pin* 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

29943029
Term* 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
}

src/odb/src/db/dbBTerm.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ template class dbTable<_dbBTerm>;
3737

3838
_dbBTerm::_dbBTerm(_dbDatabase*)
3939
{
40+
// For pointer tagging the bottom 3 bits.
41+
static_assert(alignof(_dbBTerm) % 8 == 0);
4042
_flags._io_type = dbIoType::INPUT;
4143
_flags._sig_type = dbSigType::SIGNAL;
4244
_flags._orient = 0;

src/odb/src/db/dbITerm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ class _dbITerm : public _dbObject
7272

7373
inline _dbITerm::_dbITerm(_dbDatabase*)
7474
{
75+
// For pointer tagging the bottom 3 bits.
76+
static_assert(alignof(_dbITerm) % 8 == 0);
7577
_flags._mterm_idx = 0;
7678
_flags._spare_bits = 0;
7779
_flags._clocked = 0;

src/rsz/src/Rebuffer.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1932,8 +1932,9 @@ int Rebuffer::exportBufferTree(const BufferedNetPtr& choice,
19321932
return 0;
19331933
}
19341934

1935+
Pin* mod_net_drvr_pin = db_network_->dbToSta(mod_net_drvr);
19351936
dbNet* db_load_net = db_network_->flatNet(load_pin);
1936-
odb::dbNet* db_net = db_network_->flatNet((Pin*) mod_net_drvr);
1937+
odb::dbNet* db_net = db_network_->flatNet(mod_net_drvr_pin);
19371938
if ((Net*) db_load_net != net) {
19381939
odb::dbITerm* load_iterm = nullptr;
19391940
odb::dbBTerm* load_bterm = nullptr;

0 commit comments

Comments
 (0)