Skip to content

Commit bba6193

Browse files
authored
Merge pull request #8784 from gadfort/pdn-unique
pdn: use unique ptr during shape manipulations to avoid mem-leak
2 parents d9dc0c8 + 5393a7e commit bba6193

File tree

8 files changed

+103
-73
lines changed

8 files changed

+103
-73
lines changed

src/pdn/src/PdnGen.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ void PdnGen::trimShapes()
195195
const bool is_pin_layer
196196
= pin_layers.find(shape->getLayer()) != pin_layers.end();
197197

198-
Shape* new_shape = nullptr;
198+
std::unique_ptr<Shape> new_shape = nullptr;
199199
const odb::Rect new_rect = shape->getMinimumRect();
200200
if (new_rect == shape->getRect()) { // no change to shape
201201
continue;
@@ -221,7 +221,7 @@ void PdnGen::trimShapes()
221221
}
222222
} else {
223223
if (!is_pin_layer) {
224-
component->replaceShape(shape.get(), {new_shape});
224+
component->replaceShape(shape.get(), std::move(new_shape));
225225
}
226226
}
227227
}

src/pdn/src/grid.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ bool Grid::repairVias(const Shape::ShapeTreeMap& global_shapes,
292292
return !shape->belongsTo(this);
293293
};
294294

295-
std::map<Shape*, Shape*> replace_shapes;
295+
std::map<Shape*, std::unique_ptr<Shape>> replace_shapes;
296296
for (const auto& via : vias_) {
297297
// ensure shapes belong to something
298298
const auto& lower_shape = via->getLowerShape();
@@ -313,28 +313,28 @@ bool Grid::repairVias(const Shape::ShapeTreeMap& global_shapes,
313313
}
314314

315315
if (lower_belongs_to_grid && lower_shape->isModifiable()) {
316-
auto* new_lower
316+
auto new_lower
317317
= lower_shape->extendTo(upper_shape->getRect(),
318318
obstructions[lower_shape->getLayer()],
319319
obs_filter);
320320
if (new_lower != nullptr) {
321-
replace_shapes[lower_shape.get()] = new_lower;
321+
replace_shapes[lower_shape.get()] = std::move(new_lower);
322322
}
323323
}
324324
if (upper_belongs_to_grid && upper_shape->isModifiable()) {
325-
auto* new_upper
325+
auto new_upper
326326
= upper_shape->extendTo(lower_shape->getRect(),
327327
obstructions[upper_shape->getLayer()],
328328
obs_filter);
329329
if (new_upper != nullptr) {
330-
replace_shapes[upper_shape.get()] = new_upper;
330+
replace_shapes[upper_shape.get()] = std::move(new_upper);
331331
}
332332
}
333333
}
334334

335-
for (const auto& [old_shape, new_shape] : replace_shapes) {
335+
for (auto& [old_shape, new_shape] : replace_shapes) {
336336
auto* component = old_shape->getGridComponent();
337-
component->replaceShape(old_shape, {new_shape});
337+
component->replaceShape(old_shape, std::move(new_shape));
338338
}
339339

340340
debugPrint(getLogger(),

src/pdn/src/grid_component.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "odb/db.h"
1818
#include "odb/dbTypes.h"
1919
#include "odb/geom.h"
20+
#include "shape.h"
2021
#include "techlayer.h"
2122
#include "utl/Logger.h"
2223
#include "via.h"
@@ -61,20 +62,20 @@ std::string GridComponent::typeToString(Type type)
6162
return "Unknown";
6263
}
6364

64-
ShapePtr GridComponent::addShape(Shape* shape)
65+
ShapePtr GridComponent::addShape(std::unique_ptr<Shape> shape)
6566
{
6667
debugPrint(getLogger(),
6768
utl::PDN,
6869
"Shape",
6970
3,
7071
"Adding shape {}.",
7172
shape->getReportText());
72-
auto shape_ptr = std::shared_ptr<Shape>(shape);
73-
if (!shape_ptr->isValid()) {
73+
if (!shape->isValid()) {
7474
// do not add invalid shapes
7575
return nullptr;
7676
}
7777

78+
auto shape_ptr = std::shared_ptr<Shape>(shape.release());
7879
shape_ptr->setGridComponent(this);
7980
const odb::Rect& shape_rect = shape_ptr->getRect();
8081

@@ -193,14 +194,23 @@ void GridComponent::removeShape(Shape* shape)
193194
}
194195

195196
void GridComponent::replaceShape(Shape* shape,
196-
const std::vector<Shape*>& replacements)
197+
std::unique_ptr<Shape> replacement)
198+
{
199+
std::vector<std::unique_ptr<Shape>> replacements;
200+
replacements.push_back(std::move(replacement));
201+
replaceShape(shape, replacements);
202+
}
203+
204+
void GridComponent::replaceShape(
205+
Shape* shape,
206+
std::vector<std::unique_ptr<Shape>>& replacements)
197207
{
198208
auto vias = shape->getVias();
199209

200210
removeShape(shape);
201211

202-
for (auto* new_shape : replacements) {
203-
const auto& new_shape_ptr = addShape(new_shape);
212+
for (auto& new_shape : replacements) {
213+
const auto& new_shape_ptr = addShape(std::move(new_shape));
204214

205215
if (new_shape_ptr == nullptr) {
206216
continue;
@@ -217,6 +227,8 @@ void GridComponent::replaceShape(Shape* shape,
217227
}
218228
}
219229
}
230+
231+
replacements.clear();
220232
}
221233

222234
void GridComponent::getObstructions(
@@ -283,17 +295,17 @@ void GridComponent::cutShapes(const Shape::ObstructionTreeMap& obstructions)
283295
continue;
284296
}
285297
const auto& obs = obstructions.at(layer);
286-
std::map<Shape*, std::vector<Shape*>> replacement_shapes;
298+
std::map<Shape*, std::vector<std::unique_ptr<Shape>>> replacement_shapes;
287299
for (const auto& shape : shapes) {
288-
std::vector<Shape*> replacements;
300+
std::vector<std::unique_ptr<Shape>> replacements;
289301
if (!shape->cut(obs, getGrid(), replacements)) {
290302
continue;
291303
}
292304

293305
replacement_shapes[shape.get()] = std::move(replacements);
294306
}
295307

296-
for (const auto& [shape, replacement] : replacement_shapes) {
308+
for (auto& [shape, replacement] : replacement_shapes) {
297309
replaceShape(shape, replacement);
298310
}
299311
}

src/pdn/src/grid_component.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#pragma once
55

66
#include <map>
7+
#include <memory>
78
#include <set>
89
#include <string>
910
#include <vector>
@@ -56,7 +57,9 @@ class GridComponent
5657
void getShapes(Shape::ShapeTreeMap& shapes) const;
5758
void removeShapes(Shape::ShapeTreeMap& shapes) const;
5859
void removeShape(Shape* shape);
59-
void replaceShape(Shape* shape, const std::vector<Shape*>& replacements);
60+
void replaceShape(Shape* shape, std::unique_ptr<Shape> replacement);
61+
void replaceShape(Shape* shape,
62+
std::vector<std::unique_ptr<Shape>>& replacements);
6063
void clearShapes() { shapes_.clear(); }
6164
int getShapeCount() const;
6265

@@ -100,7 +103,7 @@ class GridComponent
100103
int width,
101104
int spacing,
102105
const odb::dbTechLayerDir& direction) const;
103-
ShapePtr addShape(Shape* shape);
106+
ShapePtr addShape(std::unique_ptr<Shape> shape);
104107

105108
virtual bool areIntersectionsAllowed() const { return false; }
106109

src/pdn/src/rings.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <algorithm>
77
#include <array>
8+
#include <memory>
89
#include <utility>
910
#include <vector>
1011

@@ -249,10 +250,11 @@ void Rings::makeShapes(const Shape::ShapeTreeMap& other_shapes)
249250
int y_start = core.yMin() - width;
250251
int y_end = core.yMin();
251252
for (auto net : nets) {
252-
addShape(new Shape(layer,
253-
net,
254-
odb::Rect(x_start, y_start, x_end, y_end),
255-
odb::dbWireShapeType::RING));
253+
addShape(
254+
std::make_unique<Shape>(layer,
255+
net,
256+
odb::Rect(x_start, y_start, x_end, y_end),
257+
odb::dbWireShapeType::RING));
256258
if (!extend_to_boundary_) {
257259
x_start -= other_pitch;
258260
x_end += other_pitch;
@@ -268,10 +270,11 @@ void Rings::makeShapes(const Shape::ShapeTreeMap& other_shapes)
268270
y_start = core.yMax();
269271
y_end = y_start + width;
270272
for (auto net : nets) {
271-
addShape(new Shape(layer,
272-
net,
273-
odb::Rect(x_start, y_start, x_end, y_end),
274-
odb::dbWireShapeType::RING));
273+
addShape(
274+
std::make_unique<Shape>(layer,
275+
net,
276+
odb::Rect(x_start, y_start, x_end, y_end),
277+
odb::dbWireShapeType::RING));
275278
if (!extend_to_boundary_) {
276279
x_start -= other_pitch;
277280
x_end += other_pitch;
@@ -290,10 +293,11 @@ void Rings::makeShapes(const Shape::ShapeTreeMap& other_shapes)
290293
y_end = boundary.yMax();
291294
}
292295
for (auto net : nets) {
293-
addShape(new Shape(layer,
294-
net,
295-
odb::Rect(x_start, y_start, x_end, y_end),
296-
odb::dbWireShapeType::RING));
296+
addShape(
297+
std::make_unique<Shape>(layer,
298+
net,
299+
odb::Rect(x_start, y_start, x_end, y_end),
300+
odb::dbWireShapeType::RING));
297301
x_start -= pitch;
298302
x_end -= pitch;
299303
if (!extend_to_boundary_) {
@@ -309,10 +313,11 @@ void Rings::makeShapes(const Shape::ShapeTreeMap& other_shapes)
309313
y_end = core.yMax() + other_width;
310314
}
311315
for (auto net : nets) {
312-
addShape(new Shape(layer,
313-
net,
314-
odb::Rect(x_start, y_start, x_end, y_end),
315-
odb::dbWireShapeType::RING));
316+
addShape(
317+
std::make_unique<Shape>(layer,
318+
net,
319+
odb::Rect(x_start, y_start, x_end, y_end),
320+
odb::dbWireShapeType::RING));
316321
x_start += pitch;
317322
x_end += pitch;
318323
if (!extend_to_boundary_) {

src/pdn/src/shape.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ utl::Logger* Shape::getLogger() const
6262
return grid_component_->getLogger();
6363
}
6464

65-
Shape* Shape::copy() const
65+
std::unique_ptr<Shape> Shape::copy() const
6666
{
67-
auto* shape = new Shape(layer_, net_, rect_, type_);
67+
auto shape = std::make_unique<Shape>(layer_, net_, rect_, type_);
6868
shape->shape_type_ = shape_type_;
6969
shape->obs_ = obs_;
7070
shape->iterm_connections_ = iterm_connections_;
@@ -204,7 +204,7 @@ odb::Rect Shape::getMinimumRect() const
204204

205205
bool Shape::cut(const ObstructionTree& obstructions,
206206
const Grid* ignore_grid,
207-
std::vector<Shape*>& replacements) const
207+
std::vector<std::unique_ptr<Shape>>& replacements) const
208208
{
209209
return cut(
210210
obstructions, replacements, [ignore_grid](const ShapePtr& other) -> bool {
@@ -217,7 +217,7 @@ bool Shape::cut(const ObstructionTree& obstructions,
217217
}
218218

219219
bool Shape::cut(const ObstructionTree& obstructions,
220-
std::vector<Shape*>& replacements,
220+
std::vector<std::unique_ptr<Shape>>& replacements,
221221
const std::function<bool(const ShapePtr&)>& obs_filter) const
222222
{
223223
using namespace boost::polygon::operators;
@@ -306,11 +306,11 @@ bool Shape::cut(const ObstructionTree& obstructions,
306306
}
307307

308308
if (accept) {
309-
auto* new_shape = copy();
309+
auto new_shape = copy();
310310
new_shape->setRect(new_rect);
311311
new_shape->updateTermConnections();
312312

313-
replacements.push_back(new_shape);
313+
replacements.push_back(std::move(new_shape));
314314
}
315315
}
316316
return true;
@@ -593,12 +593,12 @@ std::string Shape::getRectText(const odb::Rect& rect, double dbu_to_micron)
593593
rect.yMax() / dbu_to_micron);
594594
}
595595

596-
Shape* Shape::extendTo(
596+
std::unique_ptr<Shape> Shape::extendTo(
597597
const odb::Rect& rect,
598598
const ObstructionTree& obstructions,
599599
const std::function<bool(const ShapePtr&)>& obs_filter) const
600600
{
601-
std::unique_ptr<Shape> new_shape(copy());
601+
std::unique_ptr<Shape> new_shape = copy();
602602

603603
if (isHorizontal()) {
604604
new_shape->rect_.set_xlo(std::min(rect_.xMin(), rect.xMin()));
@@ -626,7 +626,7 @@ Shape* Shape::extendTo(
626626
return nullptr;
627627
}
628628

629-
return new_shape.release();
629+
return new_shape;
630630
}
631631

632632
Shape::ShapeTreeMap Shape::convertVectorToTree(ShapeVectorMap& vec)
@@ -672,9 +672,10 @@ FollowPinShape::FollowPinShape(odb::dbTechLayer* layer,
672672
{
673673
}
674674

675-
Shape* FollowPinShape::copy() const
675+
std::unique_ptr<Shape> FollowPinShape::copy() const
676676
{
677-
auto* shape = new FollowPinShape(getLayer(), getNet(), getRect());
677+
auto shape
678+
= std::make_unique<FollowPinShape>(getLayer(), getNet(), getRect());
678679
shape->generateObstruction();
679680
shape->rows_ = rows_;
680681
return shape;
@@ -741,9 +742,10 @@ odb::Rect FollowPinShape::getMinimumRect() const
741742
return min_shape;
742743
}
743744

744-
bool FollowPinShape::cut(const ObstructionTree& obstructions,
745-
const Grid* ignore_grid,
746-
std::vector<Shape*>& replacements) const
745+
bool FollowPinShape::cut(
746+
const ObstructionTree& obstructions,
747+
const Grid* ignore_grid,
748+
std::vector<std::unique_ptr<Shape>>& replacements) const
747749
{
748750
return Shape::cut(
749751
obstructions, replacements, [](const ShapePtr& other) -> bool {

src/pdn/src/shape.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -175,18 +175,18 @@ class Shape
175175
int getNumberOfConnectionsBelow() const;
176176
int getNumberOfConnectionsAbove() const;
177177

178-
Shape* extendTo(
178+
std::unique_ptr<Shape> extendTo(
179179
const odb::Rect& rect,
180180
const ObstructionTree& obstructions,
181181
const std::function<bool(const ShapePtr&)>& obs_filter
182182
= [](const ShapePtr&) { return true; }) const;
183183

184184
virtual bool cut(const ObstructionTree& obstructions,
185185
const Grid* ignore_grid,
186-
std::vector<Shape*>& replacements) const;
186+
std::vector<std::unique_ptr<Shape>>& replacements) const;
187187

188188
// return a copy of the shape
189-
virtual Shape* copy() const;
189+
virtual std::unique_ptr<Shape> copy() const;
190190
// merge this shape with another
191191
virtual void merge(Shape* shape);
192192

@@ -223,7 +223,7 @@ class Shape
223223

224224
protected:
225225
bool cut(const ObstructionTree& obstructions,
226-
std::vector<Shape*>& replacements,
226+
std::vector<std::unique_ptr<Shape>>& replacements,
227227
const std::function<bool(const ShapePtr&)>& obs_filter) const;
228228

229229
private:
@@ -261,7 +261,7 @@ class FollowPinShape : public Shape
261261
void addRow(odb::dbRow* row) { rows_.insert(row); }
262262

263263
odb::Rect getMinimumRect() const override;
264-
Shape* copy() const override;
264+
std::unique_ptr<Shape> copy() const override;
265265
void merge(Shape* shape) override;
266266
void updateTermConnections() override;
267267

@@ -274,7 +274,7 @@ class FollowPinShape : public Shape
274274

275275
bool cut(const ObstructionTree& obstructions,
276276
const Grid* ignore_grid,
277-
std::vector<Shape*>& replacements) const override;
277+
std::vector<std::unique_ptr<Shape>>& replacements) const override;
278278

279279
private:
280280
std::set<odb::dbRow*> rows_;

0 commit comments

Comments
 (0)