mirror of
https://github.com/The-OpenROAD-Project/OpenSTA.git
synced 2026-05-30 00:24:12 +08:00
commit 98fa3639bd0e07f4e315578b50266972bbb7ac7d Author: James Cherry <cherry@parallaxsw.com> Date: Sat Feb 8 14:17:29 2025 -0800 Edge::setArcDelayAnnotated Signed-off-by: James Cherry <cherry@parallaxsw.com> commit d4628351d788c68ed948751374adee1bba6ca6ea Author: James Cherry <cherry@parallaxsw.com> Date: Sat Feb 8 09:27:33 2025 -0800 leaks Signed-off-by: James Cherry <cherry@parallaxsw.com> commit cee843b81df89c0f7bc51a76a34422009f49b046 Author: James Cherry <cherry@parallaxsw.com> Date: Fri Feb 7 10:22:00 2025 -0800 arcDelayAnnotated Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 2a080cb4a3425e9b0a98d90315d23b87c755ebaa Author: James Cherry <cherry@parallaxsw.com> Date: Fri Feb 7 09:34:16 2025 -0800 leak Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 6b85cebe290cb9f1c7fabe06fcec42dd7c060550 Author: James Cherry <cherry@parallaxsw.com> Date: Thu Feb 6 16:12:42 2025 -0800 readme Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 01d4481280b08e98cc311dc37a3eeb1cfc928902 Author: James Cherry <cherry@parallaxsw.com> Date: Thu Feb 6 16:12:33 2025 -0800 comment Signed-off-by: James Cherry <cherry@parallaxsw.com> commit e7c62097f948450ed46c0ac577bd3636cf5be625 Author: James Cherry <cherry@parallaxsw.com> Date: Thu Feb 6 16:12:19 2025 -0800 Search no virtuals Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 761212fc0a593d47422dc7716b7e28f593647a64 Author: James Cherry <cherry@parallaxsw.com> Date: Thu Feb 6 15:13:36 2025 -0800 leak Signed-off-by: James Cherry <cherry@parallaxsw.com> commit dd64f685c7fe2b3e85e3194008fae67a23650110 Author: James Cherry <cherry@parallaxsw.com> Date: Thu Feb 6 12:31:38 2025 -0800 Graph::removeDelayAnnotated Signed-off-by: James Cherry <cherry@parallaxsw.com> commit a1b79b09178ba8bdf0ec9486d84fcff68c2a1f2e Author: James Cherry <cherry@parallaxsw.com> Date: Thu Feb 6 12:19:32 2025 -0800 Edge::arc_annotated_delays_ Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 6b8b44ebd1e3a483ccfaa08f08c5fa8b60c72f90 Author: James Cherry <cherry@parallaxsw.com> Date: Thu Feb 6 08:48:49 2025 -0800 leak Signed-off-by: James Cherry <cherry@parallaxsw.com> commit ee939bf4015fe3d78860b3e615ec7defa395b2bf Author: James Cherry <cherry@parallaxsw.com> Date: Wed Feb 5 18:14:04 2025 -0800 pass fast regressions Signed-off-by: James Cherry <cherry@parallaxsw.com> commit f25b505d8507046638dbb30772d721547b3f8941 Author: James Cherry <cherry@parallaxsw.com> Date: Wed Feb 5 15:54:39 2025 -0800 pass all but 1 regression Signed-off-by: James Cherry <cherry@parallaxsw.com> commit acd3abf0512f5ecbe83025eb5facfa5a594ca9fa Author: James Cherry <cherry@parallaxsw.com> Date: Wed Feb 5 12:23:02 2025 -0800 rm ArrayTable compiles Signed-off-by: James Cherry <cherry@parallaxsw.com> commit 1a65f9da1814b8664062fe7ecf684acc42ee6933 Author: James Cherry <cherry@parallaxsw.com> Date: Tue Feb 4 16:26:34 2025 -0800 keep prev tag arrays until search is finsihed Signed-off-by: James Cherry <cherry@parallaxsw.com> Signed-off-by: James Cherry <cherry@parallaxsw.com>
215 lines
5.4 KiB
C++
215 lines
5.4 KiB
C++
// OpenSTA, Static Timing Analyzer
|
|
// Copyright (c) 2025, Parallax Software, Inc.
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
//
|
|
// The origin of this software must not be misrepresented; you must not
|
|
// claim that you wrote the original software.
|
|
//
|
|
// Altered source versions must be plainly marked as such, and must not be
|
|
// misrepresented as being the original software.
|
|
//
|
|
// This notice may not be removed or altered from any source distribution.
|
|
|
|
#pragma once
|
|
|
|
#include "Vector.hh"
|
|
#include "Error.hh"
|
|
#include "ObjectId.hh"
|
|
|
|
namespace sta {
|
|
|
|
template <class OBJECT>
|
|
class TableBlock;
|
|
|
|
// Object tables allocate objects in blocks and use 32 bit IDs to
|
|
// reference an object. Paging performance is improved by allocating
|
|
// blocks instead of individual objects, and object sizes are reduced
|
|
// by using 32 bit references instead of 64 bit pointers.
|
|
//
|
|
// Class TYPE must define member functions
|
|
// ObjectIdx objectIdx() const
|
|
// void setObjectIdx(ObjectIdx idx)
|
|
// to get/set the index of the object in a block, which can be a bit
|
|
// field ObjectTable::idx_bits (7 bits) wide.
|
|
|
|
template <class TYPE>
|
|
class ObjectTable
|
|
{
|
|
public:
|
|
ObjectTable();
|
|
~ObjectTable();
|
|
TYPE *make();
|
|
void destroy(TYPE *object);
|
|
TYPE *pointer(ObjectId id) const;
|
|
TYPE &ref(ObjectId id) const;
|
|
ObjectId objectId(const TYPE *object);
|
|
size_t size() const { return size_; }
|
|
void clear();
|
|
|
|
// Objects are allocated in blocks of 128.
|
|
static constexpr int idx_bits = 7;
|
|
static constexpr int block_object_count = (1 << idx_bits);
|
|
static constexpr int block_id_max = 1 << (object_id_bits - idx_bits);
|
|
|
|
private:
|
|
void makeBlock();
|
|
void freePush(TYPE *object,
|
|
ObjectId id);
|
|
|
|
size_t size_;
|
|
// Object ID of next free object.
|
|
ObjectId free_;
|
|
Vector<TableBlock<TYPE>*> blocks_;
|
|
static constexpr ObjectId idx_mask_ = block_object_count - 1;
|
|
};
|
|
|
|
template <class TYPE>
|
|
ObjectTable<TYPE>::ObjectTable() :
|
|
size_(0),
|
|
free_(object_id_null)
|
|
{
|
|
}
|
|
|
|
template <class TYPE>
|
|
ObjectTable<TYPE>::~ObjectTable()
|
|
{
|
|
blocks_.deleteContents();
|
|
}
|
|
|
|
template <class TYPE>
|
|
TYPE *
|
|
ObjectTable<TYPE>::make()
|
|
{
|
|
if (free_ == object_id_null)
|
|
makeBlock();
|
|
TYPE *object = pointer(free_);
|
|
ObjectIdx idx = free_ & idx_mask_;
|
|
object->setObjectIdx(idx);
|
|
ObjectId *free_next = reinterpret_cast<ObjectId*>(object);
|
|
free_ = *free_next;
|
|
size_++;
|
|
return object;
|
|
}
|
|
|
|
template <class TYPE>
|
|
void
|
|
ObjectTable<TYPE>::freePush(TYPE *object,
|
|
ObjectId id)
|
|
{
|
|
// Link free objects into a list linked by Object ID.
|
|
ObjectId *free_next = reinterpret_cast<ObjectId*>(object);
|
|
*free_next = free_;
|
|
free_ = id;
|
|
}
|
|
|
|
template <class TYPE>
|
|
void
|
|
ObjectTable<TYPE>::makeBlock()
|
|
{
|
|
BlockIdx block_index = blocks_.size();
|
|
TableBlock<TYPE> *block = new TableBlock<TYPE>(block_index, this);
|
|
blocks_.push_back(block);
|
|
if (blocks_.size() >= block_id_max)
|
|
criticalError(224, "max object table block count exceeded.");
|
|
// ObjectId zero is reserved for object_id_null.
|
|
int last = (block_index > 0) ? 0 : 1;
|
|
for (int i = block_object_count - 1; i >= last; i--) {
|
|
TYPE *obj = block->pointer(i);
|
|
ObjectId id = (block_index << idx_bits) + i;
|
|
freePush(obj, id);
|
|
}
|
|
}
|
|
|
|
template <class TYPE>
|
|
TYPE *
|
|
ObjectTable<TYPE>::pointer(ObjectId id) const
|
|
{
|
|
if (id == object_id_null)
|
|
return nullptr;
|
|
else {
|
|
BlockIdx blk_idx = id >> idx_bits;
|
|
ObjectIdx obj_idx = id & idx_mask_;
|
|
return blocks_[blk_idx]->pointer(obj_idx);
|
|
}
|
|
}
|
|
|
|
template <class TYPE>
|
|
TYPE &
|
|
ObjectTable<TYPE>::ref(ObjectId id) const
|
|
{
|
|
if (id == object_id_null)
|
|
criticalError(225, "null ObjectId reference is undefined.");
|
|
else {
|
|
BlockIdx blk_idx = id >> idx_bits;
|
|
ObjectIdx obj_idx = id & idx_mask_;
|
|
return blocks_[blk_idx]->ptr(obj_idx);
|
|
}
|
|
}
|
|
|
|
template <class TYPE>
|
|
ObjectId
|
|
ObjectTable<TYPE>::objectId(const TYPE *object)
|
|
{
|
|
ObjectIdx idx = object->objectIdx();
|
|
const TableBlock<TYPE> *blk =
|
|
reinterpret_cast<const TableBlock<TYPE>*>(object - idx);
|
|
return (blk->index() << idx_bits) + idx;
|
|
}
|
|
|
|
template <class TYPE>
|
|
void
|
|
ObjectTable<TYPE>::destroy(TYPE *object)
|
|
{
|
|
ObjectId object_id = objectId(object);
|
|
size_--;
|
|
freePush(object, object_id);
|
|
}
|
|
|
|
template <class TYPE>
|
|
void
|
|
ObjectTable<TYPE>::clear()
|
|
{
|
|
blocks_.deleteContentsClear();
|
|
size_ = 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
template <class TYPE>
|
|
class TableBlock
|
|
{
|
|
public:
|
|
TableBlock(BlockIdx block_idx,
|
|
ObjectTable<TYPE> *table);
|
|
BlockIdx index() const { return block_idx_; }
|
|
TYPE &ref(ObjectIdx idx) { return objects_[idx]; }
|
|
TYPE *pointer(ObjectIdx idx) { return &objects_[idx]; }
|
|
|
|
private:
|
|
TYPE objects_[ObjectTable<TYPE>::block_object_count];
|
|
BlockIdx block_idx_;
|
|
ObjectTable<TYPE> *table_;
|
|
};
|
|
|
|
template <class TYPE>
|
|
TableBlock<TYPE>::TableBlock(BlockIdx block_idx,
|
|
ObjectTable<TYPE> *table) :
|
|
block_idx_(block_idx),
|
|
table_(table)
|
|
{
|
|
}
|
|
|
|
} // Namespace
|