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;
}
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
map<u32, LitFragment> groupByFragment(const RoseBuildImpl &build) {
u32 frag_id = 0;
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) {
u32 final_id = m.first;
const auto &lit_ids = m.second;
assert(!lit_ids.empty());
auto groups = getGroups(build, lit_ids);
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;
}
const auto lit_id = *lit_ids.begin();
const auto &lit = build.literals.right.at(lit_id);
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;
}
// Combining fragments that squash their groups is unsafe.
const auto &info = build.literal_info[lit_id];
if (info.squash_group) {
final_to_frag.emplace(final_id, LitFragment(frag_id++));
final_to_frag.emplace(final_id, LitFragment(frag_id++, groups));
continue;
}
DEBUG_PRINTF("fragment candidate: final_id=%u %s\n", final_id,
dumpString(lit.s).c_str());
auto frag = getFragment(lit);
frag_lits[frag].push_back(final_id);
auto &fi = frag_info[getFragment(lit)];
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(),
as_string_list(m.second).c_str());
for (const auto final_id : m.second) {
as_string_list(fi.final_ids).c_str());
for (const auto final_id : fi.final_ids) {
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++;
}

View File

@ -437,8 +437,10 @@ private:
std::set<ReportID> all_reports(const OutfixInfo &outfix);
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;
rose_group groups;
u32 lit_program_offset = 0;
u32 delay_program_offset = 0;
};

View File

@ -635,24 +635,6 @@ u64a literalMinReportOffset(const RoseBuildImpl &build,
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>
void trim_to_suffix(Container &c, size_t len) {
if (c.size() <= len) {
@ -751,16 +733,13 @@ MatcherProto makeMatcherProto(const RoseBuildImpl &build,
cmp);
}
auto frag_group_map = makeFragGroupMap(build);
for (auto &lit : mp.lits) {
u32 final_id = lit.id;
assert(contains(build.final_to_frag_map, final_id));
const auto &frag = build.final_to_frag_map.at(final_id);
lit.id = delay_rebuild ? frag.delay_program_offset
: frag.lit_program_offset;
assert(contains(frag_group_map, frag.fragment_id));
lit.groups = frag_group_map.at(frag.fragment_id);
lit.groups = frag.groups;
}
sort_and_unique(mp.lits);