rose: parameterise CHECK_LIT_EARLY

This commit is contained in:
Justin Viiret 2016-05-03 16:16:20 +10:00 committed by Matthew Barr
parent 7690881f85
commit 1df4da16ad
4 changed files with 40 additions and 10 deletions

View File

@ -880,9 +880,9 @@ hwlmcb_rv_t roseRunProgram(const struct RoseEngine *t,
PROGRAM_NEXT_INSTRUCTION PROGRAM_NEXT_INSTRUCTION
PROGRAM_CASE(CHECK_LIT_EARLY) { PROGRAM_CASE(CHECK_LIT_EARLY) {
if (end < t->floatingMinLiteralMatchOffset) { if (end < ri->min_offset) {
DEBUG_PRINTF("halt: too soon, min offset=%u\n", DEBUG_PRINTF("halt: before min_offset=%u\n",
t->floatingMinLiteralMatchOffset); ri->min_offset);
return HWLM_CONTINUE_MATCHING; return HWLM_CONTINUE_MATCHING;
} }
} }

View File

@ -3568,6 +3568,19 @@ void makeGroupSquashInstruction(const RoseBuildImpl &build, u32 final_id,
program.push_back(move(ri)); program.push_back(move(ri));
} }
static
u32 findMinOffset(const RoseBuildImpl &build, u32 lit_id) {
const auto &lit_vertices = build.literal_info.at(lit_id).vertices;
assert(!lit_vertices.empty());
u32 min_offset = UINT32_MAX;
for (const auto &v : lit_vertices) {
min_offset = min(min_offset, build.g[v].min_offset);
}
return min_offset;
}
static static
void makeCheckLitEarlyInstruction(const RoseBuildImpl &build, build_context &bc, void makeCheckLitEarlyInstruction(const RoseBuildImpl &build, build_context &bc,
u32 final_id, u32 final_id,
@ -3591,22 +3604,36 @@ void makeCheckLitEarlyInstruction(const RoseBuildImpl &build, build_context &bc,
return; return;
} }
size_t min_offset = SIZE_MAX; size_t min_len = SIZE_MAX;
u32 min_offset = UINT32_MAX;
for (u32 lit_id : lit_ids) { for (u32 lit_id : lit_ids) {
const auto &lit = build.literals.right.at(lit_id); const auto &lit = build.literals.right.at(lit_id);
min_offset = min(min_offset, lit.elength()); size_t lit_min_len = lit.elength();
u32 lit_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("%zu lits, min_offset=%zu\n", lit_ids.size(), min_offset); DEBUG_PRINTF("final_id=%u has min_len=%zu, min_offset=%u, "
"global min is %u\n", final_id, min_len, min_offset,
bc.floatingMinLiteralMatchOffset);
// If we can't match before the min offset, we don't need the check. // If we can't match before the min offset, we don't need the check.
if (min_offset >= bc.floatingMinLiteralMatchOffset) { if (min_len >= bc.floatingMinLiteralMatchOffset) {
DEBUG_PRINTF("no need for check, min is %u\n", DEBUG_PRINTF("no need for check, min is %u\n",
bc.floatingMinLiteralMatchOffset); bc.floatingMinLiteralMatchOffset);
return; return;
} }
program.push_back(RoseInstruction(ROSE_INSTR_CHECK_LIT_EARLY)); assert(min_offset >= bc.floatingMinLiteralMatchOffset);
assert(min_offset < UINT32_MAX);
DEBUG_PRINTF("adding lit early check, min_offset=%u\n", min_offset);
auto ri = RoseInstruction(ROSE_INSTR_CHECK_LIT_EARLY);
ri.u.checkLitEarly.min_offset = min_offset;
program.push_back(move(ri));
} }
static static

View File

@ -253,7 +253,9 @@ void dumpProgram(ofstream &os, const RoseEngine *t, const char *pc) {
} }
PROGRAM_NEXT_INSTRUCTION PROGRAM_NEXT_INSTRUCTION
PROGRAM_CASE(CHECK_LIT_EARLY) {} PROGRAM_CASE(CHECK_LIT_EARLY) {
os << " min_offset " << ri->min_offset << endl;
}
PROGRAM_NEXT_INSTRUCTION PROGRAM_NEXT_INSTRUCTION
PROGRAM_CASE(CHECK_GROUPS) { PROGRAM_CASE(CHECK_GROUPS) {

View File

@ -120,6 +120,7 @@ struct ROSE_STRUCT_CHECK_LIT_MASK {
/** Note: check failure will halt program. */ /** Note: check failure will halt program. */
struct ROSE_STRUCT_CHECK_LIT_EARLY { struct ROSE_STRUCT_CHECK_LIT_EARLY {
u8 code; //!< From enum RoseInstructionCode. u8 code; //!< From enum RoseInstructionCode.
u32 min_offset; //!< Minimum offset for this literal.
}; };
/** Note: check failure will halt program. */ /** Note: check failure will halt program. */