diff --git a/src/compiler/compiler.cpp b/src/compiler/compiler.cpp index ce5f8723..d56aff88 100644 --- a/src/compiler/compiler.cpp +++ b/src/compiler/compiler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Intel Corporation + * Copyright (c) 2015-2016, Intel Corporation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -52,7 +52,6 @@ #include "parser/shortcut_literal.h" #include "parser/unsupported.h" #include "parser/utf8_validate.h" -#include "smallwrite/smallwrite_build.h" #include "rose/rose_build.h" #include "rose/rose_build_dump.h" #include "som/slot_manager_dump.h" @@ -304,15 +303,6 @@ aligned_unique_ptr generateRoseEngine(NG &ng) { return nullptr; } - /* avoid building a smwr if just a pure floating case. */ - if (!roseIsPureLiteral(rose.get())) { - u32 qual = roseQuality(rose.get()); - auto smwr = ng.smwr->build(qual); - if (smwr) { - rose = roseAddSmallWrite(rose.get(), smwr.get()); - } - } - dumpRose(*ng.rose, rose.get(), ng.cc.grey); dumpReportManager(ng.rm, ng.cc.grey); dumpSomSlotManager(ng.ssm, ng.cc.grey); diff --git a/src/nfagraph/ng.cpp b/src/nfagraph/ng.cpp index 5d4f1b97..5023cbef 100644 --- a/src/nfagraph/ng.cpp +++ b/src/nfagraph/ng.cpp @@ -62,8 +62,8 @@ #include "ng_width.h" #include "ue2common.h" #include "nfa/goughcompile.h" -#include "smallwrite/smallwrite_build.h" #include "rose/rose_build.h" +#include "smallwrite/smallwrite_build.h" #include "util/compile_error.h" #include "util/container.h" #include "util/depth.h" @@ -82,8 +82,8 @@ NG::NG(const CompileContext &in_cc, size_t num_patterns, rm(in_cc.grey), ssm(in_somPrecision), cc(in_cc), - rose(makeRoseBuilder(rm, ssm, cc, boundary)), - smwr(makeSmallWriteBuilder(num_patterns, rm, cc)) { + smwr(makeSmallWriteBuilder(num_patterns, rm, cc)), + rose(makeRoseBuilder(rm, ssm, *smwr, cc, boundary)) { } NG::~NG() { @@ -580,7 +580,8 @@ bool NG::addLiteral(const ue2_literal &literal, u32 expr_index, minWidth = min(minWidth, depth(literal.length())); - smwr->add(literal, id); /* inform small write handler about this literal */ + /* inform small write handler about this literal */ + smwr->add(literal, id); return true; } diff --git a/src/nfagraph/ng.h b/src/nfagraph/ng.h index 95936fcc..4aa6a7dc 100644 --- a/src/nfagraph/ng.h +++ b/src/nfagraph/ng.h @@ -119,8 +119,8 @@ public: BoundaryReports boundary; const CompileContext cc; - const std::unique_ptr rose; //!< Rose builder. const std::unique_ptr smwr; //!< SmallWrite builder. + const std::unique_ptr rose; //!< Rose builder. }; /** \brief Run graph reduction passes. diff --git a/src/rose/rose_build.h b/src/rose/rose_build.h index bef2114f..c71671fa 100644 --- a/src/rose/rose_build.h +++ b/src/rose/rose_build.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Intel Corporation + * Copyright (c) 2015-2016, Intel Corporation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -65,6 +65,7 @@ struct raw_som_dfa; class CharReach; class NGHolder; class ReportManager; +class SmallWriteBuild; class SomSlotManager; class RoseDedupeAux { @@ -128,6 +129,7 @@ public: // Construct a usable Rose builder. std::unique_ptr makeRoseBuilder(ReportManager &rm, SomSlotManager &ssm, + SmallWriteBuild &smwr, const CompileContext &cc, const BoundaryReports &boundary); @@ -140,9 +142,6 @@ size_t roseSize(const RoseEngine *t); * intended to indicate a lightweight rose. */ u32 roseQuality(const RoseEngine *t); -ue2::aligned_unique_ptr -roseAddSmallWrite(const RoseEngine *t, const SmallWriteEngine *smwr); - bool roseIsPureLiteral(const RoseEngine *t); size_t maxOverlap(const ue2_literal &a, const ue2_literal &b, u32 b_delay); diff --git a/src/rose/rose_build_bytecode.cpp b/src/rose/rose_build_bytecode.cpp index f451b8ea..a8440916 100644 --- a/src/rose/rose_build_bytecode.cpp +++ b/src/rose/rose_build_bytecode.cpp @@ -64,6 +64,7 @@ #include "nfagraph/ng_stop.h" #include "nfagraph/ng_util.h" #include "nfagraph/ng_width.h" +#include "smallwrite/smallwrite_build.h" #include "som/slot_manager.h" #include "util/alloc.h" #include "util/bitutils.h" @@ -5114,6 +5115,41 @@ u32 buildEagerQueueIter(const set &eager, u32 leftfixBeginQueue, return addIteratorToTable(bc, iter); } +static +aligned_unique_ptr addSmallWriteEngine(RoseBuildImpl &build, + aligned_unique_ptr rose) { + assert(rose); + + if (roseIsPureLiteral(rose.get())) { + DEBUG_PRINTF("pure literal case, not adding smwr\n"); + return rose; + } + + u32 qual = roseQuality(rose.get()); + auto smwr_engine = build.smwr.build(qual); + if (!smwr_engine) { + DEBUG_PRINTF("no smwr built\n"); + return rose; + } + + const size_t mainSize = roseSize(rose.get()); + const size_t smallWriteSize = smwrSize(smwr_engine.get()); + DEBUG_PRINTF("adding smwr engine, size=%zu\n", smallWriteSize); + + const size_t smwrOffset = ROUNDUP_CL(mainSize); + const size_t newSize = smwrOffset + smallWriteSize; + + auto rose2 = aligned_zmalloc_unique(newSize); + char *ptr = (char *)rose2.get(); + memcpy(ptr, rose.get(), mainSize); + memcpy(ptr + smwrOffset, smwr_engine.get(), smallWriteSize); + + rose2->smallWriteOffset = verify_u32(smwrOffset); + rose2->size = verify_u32(newSize); + + return rose2; +} + aligned_unique_ptr RoseBuildImpl::buildFinalEngine(u32 minWidth) { DerivedBoundaryReports dboundary(boundary); @@ -5467,6 +5503,9 @@ aligned_unique_ptr RoseBuildImpl::buildFinalEngine(u32 minWidth) { // after we copied it into the engine bytecode. assert(byte_length(bc.engine_blob) == engineBlobSize); + // Add a small write engine if appropriate. + engine = addSmallWriteEngine(*this, move(engine)); + DEBUG_PRINTF("rose done %p\n", engine.get()); return engine; } diff --git a/src/rose/rose_build_impl.h b/src/rose/rose_build_impl.h index a00bc4ea..19f803b2 100644 --- a/src/rose/rose_build_impl.h +++ b/src/rose/rose_build_impl.h @@ -60,6 +60,7 @@ struct BoundaryReports; struct CastleProto; struct CompileContext; class ReportManager; +class SmallWriteBuild; class SomSlotManager; struct suffix_id { @@ -415,7 +416,7 @@ std::set all_reports(const OutfixInfo &outfix); // Concrete impl class class RoseBuildImpl : public RoseBuild { public: - RoseBuildImpl(ReportManager &rm, SomSlotManager &ssm, + RoseBuildImpl(ReportManager &rm, SomSlotManager &ssm, SmallWriteBuild &smwr, const CompileContext &cc, const BoundaryReports &boundary); ~RoseBuildImpl() override; @@ -584,6 +585,7 @@ public: QueueIndexFactory qif; ReportManager &rm; SomSlotManager &ssm; + SmallWriteBuild &smwr; const BoundaryReports &boundary; private: diff --git a/src/rose/rose_build_misc.cpp b/src/rose/rose_build_misc.cpp index f7d49cbe..c2f9f580 100644 --- a/src/rose/rose_build_misc.cpp +++ b/src/rose/rose_build_misc.cpp @@ -67,7 +67,9 @@ namespace ue2 { // just to get it out of the header RoseBuild::~RoseBuild() { } -RoseBuildImpl::RoseBuildImpl(ReportManager &rm_in, SomSlotManager &ssm_in, +RoseBuildImpl::RoseBuildImpl(ReportManager &rm_in, + SomSlotManager &ssm_in, + SmallWriteBuild &smwr_in, const CompileContext &cc_in, const BoundaryReports &boundary_in) : cc(cc_in), @@ -83,6 +85,7 @@ RoseBuildImpl::RoseBuildImpl(ReportManager &rm_in, SomSlotManager &ssm_in, max_rose_anchored_floating_overlap(0), rm(rm_in), ssm(ssm_in), + smwr(smwr_in), boundary(boundary_in), next_nfa_report(0) { // add root vertices to graph @@ -233,10 +236,12 @@ size_t RoseBuildImpl::minLiteralLen(RoseVertex v) const { } // RoseBuild factory -unique_ptr makeRoseBuilder(ReportManager &rm, SomSlotManager &ssm, +unique_ptr makeRoseBuilder(ReportManager &rm, + SomSlotManager &ssm, + SmallWriteBuild &smwr, const CompileContext &cc, const BoundaryReports &boundary) { - return ue2::make_unique(rm, ssm, cc, boundary); + return ue2::make_unique(rm, ssm, smwr, cc, boundary); } size_t roseSize(const RoseEngine *t) { @@ -1279,30 +1284,6 @@ u32 roseQuality(const RoseEngine *t) { return 1; } -/** \brief Add a SMWR engine to the given RoseEngine. */ -aligned_unique_ptr roseAddSmallWrite(const RoseEngine *t, - const SmallWriteEngine *smwr) { - assert(t); - assert(smwr); - - const u32 mainSize = roseSize(t); - const u32 smallWriteSize = smwrSize(smwr); - - u32 smwrOffset = ROUNDUP_CL(mainSize); - u32 newSize = smwrOffset + smallWriteSize; - - aligned_unique_ptr t2 = - aligned_zmalloc_unique(newSize); - char *ptr = (char *)t2.get(); - memcpy(ptr, t, mainSize); - memcpy(ptr + smwrOffset, smwr, smallWriteSize); - - t2->smallWriteOffset = smwrOffset; - t2->size = newSize; - - return t2; -} - #ifndef NDEBUG /** \brief Returns true if all the graphs (NFA, DFA, Haig, etc) in this Rose * graph are implementable. */ diff --git a/unit/internal/rose_build_merge.cpp b/unit/internal/rose_build_merge.cpp index ad6b0176..3f5a8382 100644 --- a/unit/internal/rose_build_merge.cpp +++ b/unit/internal/rose_build_merge.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Intel Corporation + * Copyright (c) 2015-2016, Intel Corporation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -39,20 +39,12 @@ #include "util/compile_context.h" #include "util/graph_range.h" #include "util/make_unique.h" +#include "smallwrite/smallwrite_build.h" #include "som/slot_manager.h" using std::vector; using namespace ue2; -static -std::unique_ptr constructBuilder(const Grey &grey) { - CompileContext cc(true, false, get_current_target(), grey); - ReportManager rm(cc.grey); - SomSlotManager ssm(8); // som precision - BoundaryReports boundary; - return makeRoseBuilder(rm, ssm, cc, boundary); -} - static std::unique_ptr makeSuffixGraph(ReportID report) { auto h = ue2::make_unique(NFA_SUFFIX); @@ -100,7 +92,12 @@ size_t numUniqueSuffixGraphs(const RoseGraph &g) { TEST(RoseMerge, uncalcLeaves_nonleaf) { Grey grey; - auto build_base = constructBuilder(grey); + CompileContext cc(true, false, get_current_target(), grey); + ReportManager rm(cc.grey); + SomSlotManager ssm(8); // som precision + auto smwr = makeSmallWriteBuilder(1, rm, cc); + BoundaryReports boundary; + auto build_base = makeRoseBuilder(rm, ssm, *smwr, cc, boundary); ASSERT_NE(nullptr, build_base); RoseBuildImpl &build = static_cast(*build_base);