rose: expose smwr builder, tidy up engine build

This commit is contained in:
Justin Viiret 2016-07-15 09:50:08 +10:00 committed by Matthew Barr
parent a427a2843b
commit 9eb349a343
8 changed files with 68 additions and 59 deletions

View File

@ -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<RoseEngine> 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);

View File

@ -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;
}

View File

@ -119,8 +119,8 @@ public:
BoundaryReports boundary;
const CompileContext cc;
const std::unique_ptr<RoseBuild> rose; //!< Rose builder.
const std::unique_ptr<SmallWriteBuild> smwr; //!< SmallWrite builder.
const std::unique_ptr<RoseBuild> rose; //!< Rose builder.
};
/** \brief Run graph reduction passes.

View File

@ -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<RoseBuild> 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<RoseEngine>
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);

View File

@ -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<u32> &eager, u32 leftfixBeginQueue,
return addIteratorToTable(bc, iter);
}
static
aligned_unique_ptr<RoseEngine> addSmallWriteEngine(RoseBuildImpl &build,
aligned_unique_ptr<RoseEngine> 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<RoseEngine>(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<RoseEngine> RoseBuildImpl::buildFinalEngine(u32 minWidth) {
DerivedBoundaryReports dboundary(boundary);
@ -5467,6 +5503,9 @@ aligned_unique_ptr<RoseEngine> 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;
}

View File

@ -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<ReportID> 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:

View File

@ -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<RoseBuild> makeRoseBuilder(ReportManager &rm, SomSlotManager &ssm,
unique_ptr<RoseBuild> makeRoseBuilder(ReportManager &rm,
SomSlotManager &ssm,
SmallWriteBuild &smwr,
const CompileContext &cc,
const BoundaryReports &boundary) {
return ue2::make_unique<RoseBuildImpl>(rm, ssm, cc, boundary);
return ue2::make_unique<RoseBuildImpl>(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<RoseEngine> 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<RoseEngine> t2 =
aligned_zmalloc_unique<RoseEngine>(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. */

View File

@ -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<RoseBuild> 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<NGHolder> makeSuffixGraph(ReportID report) {
auto h = ue2::make_unique<NGHolder>(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<RoseBuildImpl &>(*build_base);