rose: do fragment group assignment earlier

This commit is contained in:
Justin Viiret 2017-01-31 12:49:43 +11:00 committed by Matthew Barr
parent 6bf35cb637
commit a0260c0362
3 changed files with 34 additions and 33 deletions

View File

@ -4649,48 +4649,68 @@ rose_literal_id getFragment(const rose_literal_id &lit) {
return frag; return frag;
} }
static
rose_group getGroups(const RoseBuildImpl &build, const set<u32> &lit_ids) {
rose_group groups = 0;
for (auto lit_id : lit_ids) {
auto &info = build.literal_info.at(lit_id);
groups |= info.group_mask;
}
return groups;
}
static static
map<u32, LitFragment> groupByFragment(const RoseBuildImpl &build) { map<u32, LitFragment> groupByFragment(const RoseBuildImpl &build) {
u32 frag_id = 0; u32 frag_id = 0;
map<u32, LitFragment> final_to_frag; map<u32, LitFragment> final_to_frag;
map<rose_literal_id, vector<u32>> frag_lits; struct FragmentInfo {
vector<u32> final_ids;
rose_group groups = 0;
};
map<rose_literal_id, FragmentInfo> frag_info;
for (const auto &m : build.final_id_to_literal) { for (const auto &m : build.final_id_to_literal) {
u32 final_id = m.first; u32 final_id = m.first;
const auto &lit_ids = m.second; const auto &lit_ids = m.second;
assert(!lit_ids.empty()); assert(!lit_ids.empty());
auto groups = getGroups(build, lit_ids);
if (lit_ids.size() > 1) { if (lit_ids.size() > 1) {
final_to_frag.emplace(final_id, LitFragment(frag_id++)); final_to_frag.emplace(final_id, LitFragment(frag_id++, groups));
continue; continue;
} }
const auto lit_id = *lit_ids.begin(); const auto lit_id = *lit_ids.begin();
const auto &lit = build.literals.right.at(lit_id); const auto &lit = build.literals.right.at(lit_id);
if (lit.s.length() < ROSE_SHORT_LITERAL_LEN_MAX) { if (lit.s.length() < ROSE_SHORT_LITERAL_LEN_MAX) {
final_to_frag.emplace(final_id, LitFragment(frag_id++)); final_to_frag.emplace(final_id, LitFragment(frag_id++, groups));
continue; continue;
} }
// Combining fragments that squash their groups is unsafe. // Combining fragments that squash their groups is unsafe.
const auto &info = build.literal_info[lit_id]; const auto &info = build.literal_info[lit_id];
if (info.squash_group) { if (info.squash_group) {
final_to_frag.emplace(final_id, LitFragment(frag_id++)); final_to_frag.emplace(final_id, LitFragment(frag_id++, groups));
continue; continue;
} }
DEBUG_PRINTF("fragment candidate: final_id=%u %s\n", final_id, DEBUG_PRINTF("fragment candidate: final_id=%u %s\n", final_id,
dumpString(lit.s).c_str()); dumpString(lit.s).c_str());
auto frag = getFragment(lit); auto &fi = frag_info[getFragment(lit)];
frag_lits[frag].push_back(final_id); fi.final_ids.push_back(final_id);
fi.groups |= groups;
} }
for (const auto &m : frag_lits) { for (const auto &m : frag_info) {
const auto &fi = m.second;
DEBUG_PRINTF("frag %s -> ids: %s\n", dumpString(m.first.s).c_str(), DEBUG_PRINTF("frag %s -> ids: %s\n", dumpString(m.first.s).c_str(),
as_string_list(m.second).c_str()); as_string_list(fi.final_ids).c_str());
for (const auto final_id : m.second) { for (const auto final_id : fi.final_ids) {
assert(!contains(final_to_frag, final_id)); assert(!contains(final_to_frag, final_id));
final_to_frag.emplace(final_id, LitFragment(frag_id)); final_to_frag.emplace(final_id, LitFragment(frag_id, fi.groups));
} }
frag_id++; frag_id++;
} }

View File

@ -437,8 +437,10 @@ private:
std::set<ReportID> all_reports(const OutfixInfo &outfix); std::set<ReportID> all_reports(const OutfixInfo &outfix);
struct LitFragment { struct LitFragment {
explicit LitFragment(u32 fragment_id_in) : fragment_id(fragment_id_in) {} LitFragment(u32 fragment_id_in, rose_group groups_in)
: fragment_id(fragment_id_in), groups(groups_in) {}
u32 fragment_id; u32 fragment_id;
rose_group groups;
u32 lit_program_offset = 0; u32 lit_program_offset = 0;
u32 delay_program_offset = 0; u32 delay_program_offset = 0;
}; };

View File

@ -635,24 +635,6 @@ u64a literalMinReportOffset(const RoseBuildImpl &build,
return lit_min_offset; return lit_min_offset;
} }
static
map<u32, hwlm_group_t> makeFragGroupMap(const RoseBuildImpl &build) {
map<u32, hwlm_group_t> frag_to_group;
for (const auto &m : build.final_to_frag_map) {
u32 final_id = m.first;
u32 frag_id = m.second.fragment_id;
hwlm_group_t groups = 0;
const auto &lits = build.final_id_to_literal.at(final_id);
for (auto lit_id : lits) {
groups |= build.literal_info[lit_id].group_mask;
}
frag_to_group[frag_id] |= groups;
}
return frag_to_group;
}
template<class Container> template<class Container>
void trim_to_suffix(Container &c, size_t len) { void trim_to_suffix(Container &c, size_t len) {
if (c.size() <= len) { if (c.size() <= len) {
@ -751,16 +733,13 @@ MatcherProto makeMatcherProto(const RoseBuildImpl &build,
cmp); cmp);
} }
auto frag_group_map = makeFragGroupMap(build);
for (auto &lit : mp.lits) { for (auto &lit : mp.lits) {
u32 final_id = lit.id; u32 final_id = lit.id;
assert(contains(build.final_to_frag_map, final_id)); assert(contains(build.final_to_frag_map, final_id));
const auto &frag = build.final_to_frag_map.at(final_id); const auto &frag = build.final_to_frag_map.at(final_id);
lit.id = delay_rebuild ? frag.delay_program_offset lit.id = delay_rebuild ? frag.delay_program_offset
: frag.lit_program_offset; : frag.lit_program_offset;
assert(contains(frag_group_map, frag.fragment_id)); lit.groups = frag.groups;
lit.groups = frag_group_map.at(frag.fragment_id);
} }
sort_and_unique(mp.lits); sort_and_unique(mp.lits);