Skip to content

Commit 5728732

Browse files
committed
Optimize various IdString methods to avoid allocating storage for NEW_IDs
1 parent f1a3f6a commit 5728732

File tree

3 files changed

+69
-13
lines changed

3 files changed

+69
-13
lines changed

kernel/rtlil.h

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,26 @@ struct RTLIL::IdString
270270
*out += std::to_string(-index_);
271271
}
272272

273+
inline bool lt_by_name(const IdString &rhs) const {
274+
std::string lhs_str;
275+
std::string rhs_str;
276+
const char* lhs_cstr;
277+
const char* rhs_cstr;
278+
if (index_ >= 0)
279+
lhs_cstr = global_id_storage_.at(index_);
280+
else {
281+
append_to(&lhs_str);
282+
lhs_cstr = lhs_str.c_str();
283+
}
284+
if (rhs.index_ >= 0)
285+
rhs_cstr = global_id_storage_.at(rhs.index_);
286+
else {
287+
rhs.append_to(&rhs_str);
288+
rhs_cstr = rhs_str.c_str();
289+
}
290+
return strcmp(lhs_cstr, rhs_cstr) < 0;
291+
}
292+
273293
inline bool operator<(const IdString &rhs) const {
274294
return index_ < rhs.index_;
275295
}
@@ -288,14 +308,20 @@ struct RTLIL::IdString
288308
bool operator!=(const char *rhs) const { return strcmp(c_str(), rhs) != 0; }
289309

290310
char operator[](size_t i) const {
291-
const char *p = c_str();
311+
if (index_ >= 0) {
312+
const char *p = global_id_storage_.at(index_);
292313
#ifndef NDEBUG
293-
for (; i != 0; i--, p++)
294-
log_assert(*p != 0);
295-
return *p;
314+
for (; i != 0; i--, p++)
315+
log_assert(*p != 0);
316+
return *p;
296317
#else
297-
return *(p + i);
318+
return *(p + i);
298319
#endif
320+
}
321+
const std::string &id_start = *global_negative_id_prefix_storage_.at(index_);
322+
if (i < id_start.size())
323+
return id_start[i];
324+
return std::to_string(-index_)[i - id_start.size()];
299325
}
300326

301327
std::string substr(size_t pos = 0, size_t len = std::string::npos) const {
@@ -310,23 +336,43 @@ struct RTLIL::IdString
310336
}
311337

312338
bool begins_with(const char* prefix) const {
313-
size_t len = strlen(prefix);
314-
if (size() < len) return false;
315-
return compare(0, len, prefix) == 0;
339+
size_t prefix_len = strlen(prefix);
340+
if (index_ >= 0) {
341+
const char *id = global_id_storage_.at(index_);
342+
if (strlen(id) < prefix_len)
343+
return false;
344+
return strncmp(id, prefix, prefix_len) == 0;
345+
}
346+
347+
const std::string &id_start = *global_negative_id_prefix_storage_.at(index_);
348+
if (prefix_len <= id_start.size())
349+
return strncmp(id_start.c_str(), prefix, prefix_len) == 0;
350+
if (strncmp(id_start.c_str(), prefix, id_start.size()) != 0)
351+
return false;
352+
353+
prefix += id_start.size();
354+
prefix_len -= id_start.size();
355+
std::string v = std::to_string(-index_);
356+
if (v.size() < prefix_len)
357+
return false;
358+
return strncmp(v.c_str(), prefix, prefix_len) == 0;
316359
}
317360

318361
bool ends_with(const char* suffix) const {
319362
size_t len = strlen(suffix);
320-
if (size() < len) return false;
321-
return compare(size()-len, len, suffix) == 0;
363+
size_t id_len = size();
364+
if (id_len < len) return false;
365+
return compare(id_len, len, suffix) == 0;
322366
}
323367

324368
bool contains(const char* str) const {
325369
return strstr(c_str(), str);
326370
}
327371

328372
size_t size() const {
329-
return strlen(c_str());
373+
if (index_ >= 0)
374+
return strlen(global_id_storage_.at(index_));
375+
return global_negative_id_prefix_storage_.at(index_)->size() + std::to_string(-index_).size();
330376
}
331377

332378
bool empty() const {
@@ -624,7 +670,7 @@ namespace RTLIL {
624670

625671
struct sort_by_id_str {
626672
bool operator()(const RTLIL::IdString &a, const RTLIL::IdString &b) const {
627-
return strcmp(a.c_str(), b.c_str()) < 0;
673+
return a.lt_by_name(b);
628674
}
629675
};
630676

passes/opt/opt_clean.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ bool compare_signals(RTLIL::SigBit &s1, RTLIL::SigBit &s2, SigPool &regs, SigPoo
283283
if (attrs1 != attrs2)
284284
return attrs2 > attrs1;
285285

286-
return strcmp(w2->name.c_str(), w1->name.c_str()) < 0;
286+
return w2->name.lt_by_name(w1->name);
287287
}
288288

289289
bool check_public_name(RTLIL::IdString id)

tests/unit/kernel/rtlilTest.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,16 @@ namespace RTLIL {
373373
EXPECT_EQ(id, id2);
374374
}
375375

376+
TEST_F(KernelRtlilTest, NewIdBeginsWith) {
377+
IdString id = NEW_ID;
378+
EXPECT_TRUE(id.begins_with("$auto"));
379+
EXPECT_FALSE(id.begins_with("xyz"));
380+
EXPECT_TRUE(id.begins_with("$auto$"));
381+
EXPECT_FALSE(id.begins_with("abcdefghijklmn"));
382+
EXPECT_TRUE(id.begins_with("$auto$rtlilTest"));
383+
EXPECT_FALSE(id.begins_with("$auto$rtlilX"));
384+
}
385+
376386
class WireRtlVsHdlIndexConversionTest :
377387
public KernelRtlilTest,
378388
public testing::WithParamInterface<std::tuple<bool, int, int>>

0 commit comments

Comments
 (0)