/*
- * 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:
#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"
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);
#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"
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() {
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;
}
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.
/*
- * 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:
class CharReach;
class NGHolder;
class ReportManager;
+class SmallWriteBuild;
class SomSlotManager;
class RoseDedupeAux {
// Construct a usable Rose builder.
std::unique_ptr<RoseBuild> makeRoseBuilder(ReportManager &rm,
SomSlotManager &ssm,
+ SmallWriteBuild &smwr,
const CompileContext &cc,
const BoundaryReports &boundary);
* 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);
#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"
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);
// 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;
}
struct CastleProto;
struct CompileContext;
class ReportManager;
+class SmallWriteBuild;
class SomSlotManager;
struct suffix_id {
// 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;
QueueIndexFactory qif;
ReportManager &rm;
SomSlotManager &ssm;
+ SmallWriteBuild &smwr;
const BoundaryReports &boundary;
private:
// 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),
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
}
// 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) {
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. */
/*
- * 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:
#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);
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);