mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-06-28 16:41:01 +03:00
Rose: assign DRs in allocateFinalLiteralId
Previously, direct reports were allocated earlier; now all final IDs are assigned in the same place.
This commit is contained in:
parent
d77ee0839d
commit
6294b8a89b
@ -247,6 +247,44 @@ bool isUsedLiteral(const RoseBuildImpl &build, u32 lit_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
void makeDirectReport(RoseBuildImpl &build, u32 i) {
|
||||
if (build.literals.right.at(i).table == ROSE_FLOATING) {
|
||||
build.floating_direct_report = true;
|
||||
}
|
||||
|
||||
rose_literal_info &info = build.literal_info[i];
|
||||
assert(!info.vertices.empty());
|
||||
|
||||
vector<ReportID> reports;
|
||||
for (const auto &v : info.vertices) {
|
||||
const auto &r = build.g[v].reports;
|
||||
reports.insert(end(reports), begin(r), end(r));
|
||||
}
|
||||
sort(begin(reports), end(reports));
|
||||
reports.erase(unique(begin(reports), end(reports)), end(reports));
|
||||
|
||||
if (reports.size() == 1) {
|
||||
// A single direct report. We set the high bit to indicate it's a
|
||||
// direct report and encode the ReportID itself in the final_id
|
||||
// field.
|
||||
ReportID report = reports.front();
|
||||
assert(!(report & LITERAL_DR_FLAG));
|
||||
info.final_id = LITERAL_DR_FLAG | report;
|
||||
DEBUG_PRINTF("direct report %u -> %u\n", info.final_id, report);
|
||||
} else {
|
||||
// A multi-direct report. Here we write the report set into a list
|
||||
// to be triggered when we see this literal.
|
||||
u32 mdr_index = verify_u32(build.mdr_reports.size());
|
||||
info.final_id = LITERAL_MDR_FLAG | mdr_index;
|
||||
DEBUG_PRINTF("multi direct report %u -> [%s]\n", info.final_id,
|
||||
as_string_list(reports).c_str());
|
||||
build.mdr_reports.insert(end(build.mdr_reports), begin(reports),
|
||||
end(reports));
|
||||
build.mdr_reports.push_back(MO_INVALID_IDX);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void allocateFinalLiteralId(RoseBuildImpl &tbi) {
|
||||
/* allocate final literal ids - these are the literal ids used in the
|
||||
@ -264,15 +302,18 @@ void allocateFinalLiteralId(RoseBuildImpl &tbi) {
|
||||
assert(tbi.final_id_to_literal.empty());
|
||||
u32 next_final_id = 0;
|
||||
for (u32 i = 0; i < tbi.literal_info.size(); i++) {
|
||||
if (tbi.hasFinalId(i)) {
|
||||
continue;
|
||||
}
|
||||
assert(!tbi.hasFinalId(i));
|
||||
|
||||
if (!isUsedLiteral(tbi, i)) {
|
||||
/* what is this literal good for? absolutely nothing */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tbi.isDirectReport(i)) {
|
||||
makeDirectReport(tbi, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
// The special EOD event literal has its own program and does not need
|
||||
// a real literal ID.
|
||||
if (i == tbi.eod_event_literal_id) {
|
||||
@ -305,51 +346,6 @@ void allocateFinalLiteralId(RoseBuildImpl &tbi) {
|
||||
&next_final_id);
|
||||
}
|
||||
|
||||
static
|
||||
void findDirectReports(RoseBuildImpl &tbi) {
|
||||
const RoseGraph &g = tbi.g;
|
||||
|
||||
for (u32 i = 0; i < tbi.literal_info.size(); i++) {
|
||||
if (!tbi.isDirectReport(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tbi.literals.right.at(i).table == ROSE_FLOATING) {
|
||||
tbi.floating_direct_report = true;
|
||||
}
|
||||
|
||||
rose_literal_info &info = tbi.literal_info[i];
|
||||
const auto &verts = info.vertices;
|
||||
|
||||
assert(!verts.empty());
|
||||
if (verts.size() == 1 && g[*verts.begin()].reports.size() == 1) {
|
||||
// A single direct report. We set the high bit to indicate it's a
|
||||
// direct report and encode the ReportID itself in the final_id
|
||||
// field.
|
||||
ReportID report = *(g[*verts.begin()].reports.begin());
|
||||
assert(!(report & LITERAL_DR_FLAG));
|
||||
info.final_id = LITERAL_DR_FLAG | report;
|
||||
} else {
|
||||
// A multi-direct report. Here we write the report set into a list
|
||||
// to be triggered when we see this literal.
|
||||
u32 mdr_index = verify_u32(tbi.mdr_reports.size());
|
||||
info.final_id = LITERAL_MDR_FLAG | mdr_index;
|
||||
|
||||
// Temporary set for deduplication and determinism.
|
||||
flat_set<ReportID> reports;
|
||||
|
||||
for (auto v : verts) {
|
||||
insert(&reports, g[v].reports);
|
||||
}
|
||||
tbi.mdr_reports.insert(tbi.mdr_reports.end(), reports.begin(),
|
||||
reports.end());
|
||||
tbi.mdr_reports.push_back(MO_INVALID_IDX);
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("allocating final id %u to %u\n", info.final_id, i);
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_EXPLOSION_NC 3
|
||||
static
|
||||
bool limited_explosion(const ue2_literal &s) {
|
||||
@ -2172,9 +2168,8 @@ aligned_unique_ptr<RoseEngine> RoseBuildImpl::buildRose(u32 minWidth) {
|
||||
|
||||
// If we've got a very small number of EOD-anchored literals, consider
|
||||
// moving them into the floating table so that we only have one literal
|
||||
// matcher to run. Note that this should happen before findDirectReports as
|
||||
// it modifies the literal/vertex set. Note also that this needs to happen
|
||||
// before addAnchoredSmallBlockLiterals as it may create anchored literals.
|
||||
// matcher to run. Note that this needs to happen before
|
||||
// addAnchoredSmallBlockLiterals as it may create anchored literals.
|
||||
assert(roleOffsetsAreValid(g));
|
||||
stealEodVertices(*this);
|
||||
|
||||
@ -2190,8 +2185,6 @@ aligned_unique_ptr<RoseEngine> RoseBuildImpl::buildRose(u32 minWidth) {
|
||||
assert(roleOffsetsAreValid(g));
|
||||
handleMixedSensitivity();
|
||||
|
||||
findDirectReports(*this);
|
||||
|
||||
assignHistories(*this);
|
||||
|
||||
convertAnchPrefixToBounds(*this);
|
||||
|
Loading…
x
Reference in New Issue
Block a user