mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-06-28 16:41:01 +03:00
rose: make buildLiteralProgram take one lit_id
This commit is contained in:
parent
b525d7786c
commit
78875614c8
@ -4138,24 +4138,18 @@ void addPredBlocks(build_context &bc, map<u32, RoseProgram> &pred_blocks,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void makePushDelayedInstructions(const RoseBuildImpl &build,
|
void makePushDelayedInstructions(const RoseBuildImpl &build, build_context &bc,
|
||||||
build_context &bc,
|
u32 lit_id, RoseProgram &program) {
|
||||||
const flat_set<u32> &lit_ids,
|
const auto &info = build.literal_info.at(lit_id);
|
||||||
RoseProgram &program) {
|
|
||||||
assert(!lit_ids.empty());
|
|
||||||
|
|
||||||
vector<RoseInstrPushDelayed> delay_instructions;
|
vector<RoseInstrPushDelayed> delay_instructions;
|
||||||
|
|
||||||
for (const auto &lit_id : lit_ids) {
|
|
||||||
const auto &info = build.literal_info.at(lit_id);
|
|
||||||
for (const auto &delayed_lit_id : info.delayed_ids) {
|
for (const auto &delayed_lit_id : info.delayed_ids) {
|
||||||
DEBUG_PRINTF("delayed lit id %u\n", delayed_lit_id);
|
DEBUG_PRINTF("delayed lit id %u\n", delayed_lit_id);
|
||||||
assert(contains(bc.delay_programs, delayed_lit_id));
|
assert(contains(bc.delay_programs, delayed_lit_id));
|
||||||
u32 delay_id = bc.delay_programs.at(delayed_lit_id);
|
u32 delay_id = bc.delay_programs.at(delayed_lit_id);
|
||||||
const auto &delay_lit = build.literals.right.at(delayed_lit_id);
|
const auto &delay_lit = build.literals.right.at(delayed_lit_id);
|
||||||
delay_instructions.emplace_back(verify_u8(delay_lit.delay),
|
delay_instructions.emplace_back(verify_u8(delay_lit.delay), delay_id);
|
||||||
delay_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sort_and_unique(delay_instructions, [](const RoseInstrPushDelayed &a,
|
sort_and_unique(delay_instructions, [](const RoseInstrPushDelayed &a,
|
||||||
@ -4169,21 +4163,10 @@ void makePushDelayedInstructions(const RoseBuildImpl &build,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
rose_group getLitGroupsUnion(const RoseBuildImpl &build,
|
void makeGroupCheckInstruction(const RoseBuildImpl &build, u32 lit_id,
|
||||||
const flat_set<u32> &lit_ids) {
|
|
||||||
rose_group groups = 0;
|
|
||||||
for (auto lit_id : lit_ids) {
|
|
||||||
const auto &info = build.literal_info.at(lit_id);
|
|
||||||
groups |= info.group_mask;
|
|
||||||
}
|
|
||||||
return groups;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
void makeGroupCheckInstruction(const RoseBuildImpl &build,
|
|
||||||
const flat_set<u32> &lit_ids,
|
|
||||||
RoseProgram &program) {
|
RoseProgram &program) {
|
||||||
rose_group groups = getLitGroupsUnion(build, lit_ids);
|
const auto &info = build.literal_info.at(lit_id);
|
||||||
|
rose_group groups = info.group_mask;
|
||||||
if (!groups) {
|
if (!groups) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -4192,17 +4175,14 @@ void makeGroupCheckInstruction(const RoseBuildImpl &build,
|
|||||||
|
|
||||||
static
|
static
|
||||||
void makeCheckLitMaskInstruction(const RoseBuildImpl &build, build_context &bc,
|
void makeCheckLitMaskInstruction(const RoseBuildImpl &build, build_context &bc,
|
||||||
const flat_set<u32> &lit_ids,
|
u32 lit_id, RoseProgram &program) {
|
||||||
RoseProgram &program) {
|
const auto &info = build.literal_info.at(lit_id);
|
||||||
const auto &lit_info = build.literal_info.at(*lit_ids.begin());
|
if (!info.requires_benefits) {
|
||||||
if (!lit_info.requires_benefits) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<LookEntry> look;
|
vector<LookEntry> look;
|
||||||
|
|
||||||
assert(lit_ids.size() == 1);
|
|
||||||
u32 lit_id = *lit_ids.begin();
|
|
||||||
const ue2_literal &s = build.literals.right.at(lit_id).s;
|
const ue2_literal &s = build.literals.right.at(lit_id).s;
|
||||||
DEBUG_PRINTF("building mask for lit %u: %s\n", lit_id,
|
DEBUG_PRINTF("building mask for lit %u: %s\n", lit_id,
|
||||||
dumpString(s).c_str());
|
dumpString(s).c_str());
|
||||||
@ -4221,16 +4201,14 @@ void makeCheckLitMaskInstruction(const RoseBuildImpl &build, build_context &bc,
|
|||||||
|
|
||||||
static
|
static
|
||||||
void makeGroupSquashInstruction(const RoseBuildImpl &build,
|
void makeGroupSquashInstruction(const RoseBuildImpl &build,
|
||||||
const flat_set<u32> &lit_ids,
|
u32 lit_id,
|
||||||
RoseProgram &program) {
|
RoseProgram &program) {
|
||||||
assert(!lit_ids.empty());
|
const auto &info = build.literal_info.at(lit_id);
|
||||||
const u32 lit_id = *lit_ids.begin();
|
|
||||||
const auto &info = build.literal_info[lit_id];
|
|
||||||
if (!info.squash_group) {
|
if (!info.squash_group) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rose_group groups = getLitGroupsUnion(build, lit_ids);
|
rose_group groups = info.group_mask;
|
||||||
if (!groups) {
|
if (!groups) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -4255,32 +4233,17 @@ u32 findMaxOffset(const RoseBuildImpl &build, u32 lit_id) {
|
|||||||
|
|
||||||
static
|
static
|
||||||
void makeRecordAnchoredInstruction(const RoseBuildImpl &build,
|
void makeRecordAnchoredInstruction(const RoseBuildImpl &build,
|
||||||
build_context &bc,
|
build_context &bc, u32 lit_id,
|
||||||
const flat_set<u32> &lit_ids,
|
|
||||||
RoseProgram &program) {
|
RoseProgram &program) {
|
||||||
assert(!lit_ids.empty());
|
if (build.literals.right.at(lit_id).table != ROSE_ANCHORED) {
|
||||||
u32 first_lit_id = *begin(lit_ids);
|
|
||||||
|
|
||||||
// Must be anchored.
|
|
||||||
if (build.literals.right.at(first_lit_id).table != ROSE_ANCHORED) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dedupe anch_ids to fire.
|
|
||||||
flat_set<u32> anch_ids;
|
|
||||||
|
|
||||||
for (const auto &lit_id : lit_ids) {
|
|
||||||
assert(build.literals.right.at(lit_id).table == ROSE_ANCHORED);
|
|
||||||
if (!contains(bc.anchored_programs, lit_id)) {
|
if (!contains(bc.anchored_programs, lit_id)) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
anch_ids.insert(bc.anchored_programs.at(lit_id));
|
auto anch_id = bc.anchored_programs.at(lit_id);
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &anch_id : anch_ids) {
|
|
||||||
DEBUG_PRINTF("adding RECORD_ANCHORED for anch_id=%u\n", anch_id);
|
DEBUG_PRINTF("adding RECORD_ANCHORED for anch_id=%u\n", anch_id);
|
||||||
program.add_before_end(make_unique<RoseInstrRecordAnchored>(anch_id));
|
program.add_before_end(make_unique<RoseInstrRecordAnchored>(anch_id));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -4298,8 +4261,7 @@ u32 findMinOffset(const RoseBuildImpl &build, u32 lit_id) {
|
|||||||
|
|
||||||
static
|
static
|
||||||
void makeCheckLitEarlyInstruction(const RoseBuildImpl &build, build_context &bc,
|
void makeCheckLitEarlyInstruction(const RoseBuildImpl &build, build_context &bc,
|
||||||
const flat_set<u32> &lit_ids,
|
u32 lit_id, const vector<RoseEdge> &lit_edges,
|
||||||
const vector<RoseEdge> &lit_edges,
|
|
||||||
RoseProgram &program) {
|
RoseProgram &program) {
|
||||||
if (lit_edges.empty()) {
|
if (lit_edges.empty()) {
|
||||||
return;
|
return;
|
||||||
@ -4314,22 +4276,9 @@ void makeCheckLitEarlyInstruction(const RoseBuildImpl &build, build_context &bc,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lit_ids.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t min_len = SIZE_MAX;
|
|
||||||
u32 min_offset = UINT32_MAX;
|
|
||||||
for (u32 lit_id : lit_ids) {
|
|
||||||
const auto &lit = build.literals.right.at(lit_id);
|
const auto &lit = build.literals.right.at(lit_id);
|
||||||
size_t lit_min_len = lit.elength();
|
size_t min_len = lit.elength();
|
||||||
u32 lit_min_offset = findMinOffset(build, lit_id);
|
u32 min_offset = findMinOffset(build, lit_id);
|
||||||
DEBUG_PRINTF("lit_id=%u has min_len=%zu, min_offset=%u\n", lit_id,
|
|
||||||
lit_min_len, lit_min_offset);
|
|
||||||
min_len = min(min_len, lit_min_len);
|
|
||||||
min_offset = min(min_offset, lit_min_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_PRINTF("has min_len=%zu, min_offset=%u, "
|
DEBUG_PRINTF("has min_len=%zu, min_offset=%u, "
|
||||||
"global min is %u\n", min_len, min_offset,
|
"global min is %u\n", min_len, min_offset,
|
||||||
bc.floatingMinLiteralMatchOffset);
|
bc.floatingMinLiteralMatchOffset);
|
||||||
@ -4352,25 +4301,13 @@ void makeCheckLitEarlyInstruction(const RoseBuildImpl &build, build_context &bc,
|
|||||||
|
|
||||||
static
|
static
|
||||||
void makeCheckLiteralInstruction(const RoseBuildImpl &build,
|
void makeCheckLiteralInstruction(const RoseBuildImpl &build,
|
||||||
const build_context &bc,
|
const build_context &bc, u32 lit_id,
|
||||||
const flat_set<u32> &lits,
|
|
||||||
RoseProgram &program) {
|
RoseProgram &program) {
|
||||||
assert(bc.longLitLengthThreshold > 0);
|
assert(bc.longLitLengthThreshold > 0);
|
||||||
|
|
||||||
DEBUG_PRINTF("lits [%s], long lit threshold %zu\n",
|
DEBUG_PRINTF("lit_id=%u, long lit threshold %zu\n", lit_id,
|
||||||
as_string_list(lits).c_str(), bc.longLitLengthThreshold);
|
bc.longLitLengthThreshold);
|
||||||
|
|
||||||
if (lits.size() != 1) {
|
|
||||||
// final_id sharing is only allowed for literals that are short enough
|
|
||||||
// to not require any additional confirm work.
|
|
||||||
assert(all_of(begin(lits), end(lits), [&](u32 lit_id) {
|
|
||||||
const rose_literal_id &lit = build.literals.right.at(lit_id);
|
|
||||||
return lit.s.length() <= ROSE_SHORT_LITERAL_LEN_MAX;
|
|
||||||
}));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 lit_id = *lits.begin();
|
|
||||||
if (build.isDelayed(lit_id)) {
|
if (build.isDelayed(lit_id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -4435,41 +4372,39 @@ bool hasDelayedLiteral(RoseBuildImpl &build,
|
|||||||
|
|
||||||
static
|
static
|
||||||
RoseProgram buildLitInitialProgram(RoseBuildImpl &build, build_context &bc,
|
RoseProgram buildLitInitialProgram(RoseBuildImpl &build, build_context &bc,
|
||||||
const flat_set<u32> &lit_ids,
|
u32 lit_id,
|
||||||
const vector<RoseEdge> &lit_edges) {
|
const vector<RoseEdge> &lit_edges) {
|
||||||
RoseProgram program;
|
RoseProgram program;
|
||||||
|
|
||||||
// Check long literal info.
|
// Check long literal info.
|
||||||
makeCheckLiteralInstruction(build, bc, lit_ids, program);
|
makeCheckLiteralInstruction(build, bc, lit_id, program);
|
||||||
|
|
||||||
// Check lit mask.
|
// Check lit mask.
|
||||||
makeCheckLitMaskInstruction(build, bc, lit_ids, program);
|
makeCheckLitMaskInstruction(build, bc, lit_id, program);
|
||||||
|
|
||||||
// Check literal groups. This is an optimisation that we only perform for
|
// Check literal groups. This is an optimisation that we only perform for
|
||||||
// delayed literals, as their groups may be switched off; ordinarily, we
|
// delayed literals, as their groups may be switched off; ordinarily, we
|
||||||
// can trust the HWLM matcher.
|
// can trust the HWLM matcher.
|
||||||
if (hasDelayedLiteral(build, lit_edges)) {
|
if (hasDelayedLiteral(build, lit_edges)) {
|
||||||
makeGroupCheckInstruction(build, lit_ids, program);
|
makeGroupCheckInstruction(build, lit_id, program);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add instructions for pushing delayed matches, if there are any.
|
// Add instructions for pushing delayed matches, if there are any.
|
||||||
makePushDelayedInstructions(build, bc, lit_ids, program);
|
makePushDelayedInstructions(build, bc, lit_id, program);
|
||||||
|
|
||||||
// Add pre-check for early literals in the floating table.
|
// Add pre-check for early literals in the floating table.
|
||||||
makeCheckLitEarlyInstruction(build, bc, lit_ids, lit_edges, program);
|
makeCheckLitEarlyInstruction(build, bc, lit_id, lit_edges, program);
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
RoseProgram buildLiteralProgram(RoseBuildImpl &build, build_context &bc,
|
RoseProgram buildLiteralProgram(RoseBuildImpl &build, build_context &bc,
|
||||||
const flat_set<u32> &lit_ids,
|
u32 lit_id, const vector<RoseEdge> &lit_edges,
|
||||||
const vector<RoseEdge> &lit_edges,
|
|
||||||
bool is_anchored_program) {
|
bool is_anchored_program) {
|
||||||
const auto &g = build.g;
|
const auto &g = build.g;
|
||||||
|
|
||||||
DEBUG_PRINTF("lit ids {%s}, %zu lit edges\n",
|
DEBUG_PRINTF("lit id=%u, %zu lit edges\n", lit_id, lit_edges.size());
|
||||||
as_string_list(lit_ids).c_str(), lit_edges.size());
|
|
||||||
|
|
||||||
RoseProgram program;
|
RoseProgram program;
|
||||||
|
|
||||||
@ -4504,25 +4439,26 @@ RoseProgram buildLiteralProgram(RoseBuildImpl &build, build_context &bc,
|
|||||||
program.add_block(makeProgram(build, bc, e));
|
program.add_block(makeProgram(build, bc, e));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lit_ids.empty()) {
|
if (lit_id == build.eod_event_literal_id) {
|
||||||
|
assert(build.eod_event_literal_id != MO_INVALID_IDX);
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
RoseProgram root_block;
|
RoseProgram root_block;
|
||||||
|
|
||||||
// Literal may squash groups.
|
// Literal may squash groups.
|
||||||
makeGroupSquashInstruction(build, lit_ids, root_block);
|
makeGroupSquashInstruction(build, lit_id, root_block);
|
||||||
|
|
||||||
// Literal may be anchored and need to be recorded.
|
// Literal may be anchored and need to be recorded.
|
||||||
if (!is_anchored_program) {
|
if (!is_anchored_program) {
|
||||||
makeRecordAnchoredInstruction(build, bc, lit_ids, root_block);
|
makeRecordAnchoredInstruction(build, bc, lit_id, root_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
program.add_block(move(root_block));
|
program.add_block(move(root_block));
|
||||||
|
|
||||||
// Construct initial program up front, as its early checks must be able
|
// Construct initial program up front, as its early checks must be able
|
||||||
// to jump to end and terminate processing for this literal.
|
// to jump to end and terminate processing for this literal.
|
||||||
auto lit_program = buildLitInitialProgram(build, bc, lit_ids, lit_edges);
|
auto lit_program = buildLitInitialProgram(build, bc, lit_id, lit_edges);
|
||||||
lit_program.add_before_end(move(program));
|
lit_program.add_before_end(move(program));
|
||||||
|
|
||||||
return lit_program;
|
return lit_program;
|
||||||
@ -4575,7 +4511,7 @@ u32 writeLiteralProgram(RoseBuildImpl &build, build_context &bc,
|
|||||||
} else {
|
} else {
|
||||||
edges_ptr = &no_edges;
|
edges_ptr = &no_edges;
|
||||||
}
|
}
|
||||||
auto prog = buildLiteralProgram(build, bc, {lit_id}, *edges_ptr,
|
auto prog = buildLiteralProgram(build, bc, lit_id, *edges_ptr,
|
||||||
is_anchored_program);
|
is_anchored_program);
|
||||||
blocks.push_back(move(prog));
|
blocks.push_back(move(prog));
|
||||||
}
|
}
|
||||||
@ -4608,9 +4544,9 @@ u32 writeDelayRebuildProgram(RoseBuildImpl &build, build_context &bc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
RoseProgram prog;
|
RoseProgram prog;
|
||||||
makeCheckLiteralInstruction(build, bc, {lit_id}, prog);
|
makeCheckLiteralInstruction(build, bc, lit_id, prog);
|
||||||
makeCheckLitMaskInstruction(build, bc, {lit_id}, prog);
|
makeCheckLitMaskInstruction(build, bc, lit_id, prog);
|
||||||
makePushDelayedInstructions(build, bc, {lit_id}, prog);
|
makePushDelayedInstructions(build, bc, lit_id, prog);
|
||||||
blocks.push_back(move(prog));
|
blocks.push_back(move(prog));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5074,7 +5010,8 @@ void addEodEventProgram(RoseBuildImpl &build, build_context &bc,
|
|||||||
tie(g[source(b, g)].index, g[target(b, g)].index);
|
tie(g[source(b, g)].index, g[target(b, g)].index);
|
||||||
});
|
});
|
||||||
|
|
||||||
program.add_block(buildLiteralProgram(build, bc, {}, edge_list, false));
|
program.add_block(buildLiteralProgram(build, bc, build.eod_event_literal_id,
|
||||||
|
edge_list, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
Loading…
x
Reference in New Issue
Block a user