]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
Rose: assign DRs in allocateFinalLiteralId
authorJustin Viiret <justin.viiret@intel.com>
Mon, 15 Feb 2016 22:25:18 +0000 (09:25 +1100)
committerMatthew Barr <matthew.barr@intel.com>
Tue, 1 Mar 2016 00:36:09 +0000 (11:36 +1100)
Previously, direct reports were allocated earlier; now all final IDs are
assigned in the same place.

src/rose/rose_build_compile.cpp

index 6202299baaf8b0db8a90d71bd69ae93f6e32a30b..c71743bfea28cff20ec990ba0f671844b98105ea 100644 (file)
@@ -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);