Skip to content

Commit

Permalink
Move group iterating logic int InterDexGrouping
Browse files Browse the repository at this point in the history
Summary:
- Abstract group iterating logic into `InterDexGrouping`
- No behavioral change

Reviewed By: beicy, ssj933

Differential Revision: D49081127

fbshipit-source-id: fb748e28abe7d2beae0e18e1a76f13ea5768be1f
  • Loading branch information
Wei Zhang (Devinfra) authored and facebook-github-bot committed Sep 13, 2023
1 parent 8a9db6c commit e4235a5
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 41 deletions.
38 changes: 28 additions & 10 deletions service/class-merging/InterDexGrouping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "InterDexGrouping.h"

#include "Model.h"
#include "ScopedCFG.h"
#include "Show.h"
#include "SourceBlocks.h"
Expand Down Expand Up @@ -177,8 +178,8 @@ namespace class_merging {
* Split the types into groups according to the interdex grouping information.
* Note that types may be dropped if they are not allowed be merged.
*/
std::vector<ConstTypeHashSet>& InterDexGrouping::group_by_interdex_set(
const Scope& scope, const ConstTypeHashSet& types) {
void InterDexGrouping::build_interdex_grouping(
const Scope& scope, const ConstTypeHashSet& merging_targets) {
const auto& cls_to_interdex_groups = m_conf.get_cls_interdex_groups();
auto num_interdex_groups = m_conf.get_num_interdex_groups();
TRACE(CLMG, 5, "num_interdex_groups %zu; cls_to_interdex_groups %zu",
Expand All @@ -189,11 +190,12 @@ std::vector<ConstTypeHashSet>& InterDexGrouping::group_by_interdex_set(
}
m_all_interdexing_groups = std::vector<ConstTypeHashSet>(num_group);
if (num_group == 1) {
m_all_interdexing_groups[0].insert(types.begin(), types.end());
return m_all_interdexing_groups;
m_all_interdexing_groups[0].insert(merging_targets.begin(),
merging_targets.end());
return;
}
const auto& type_to_usages =
get_type_usages(types, scope, m_config.inferring_mode);
get_type_usages(merging_targets, scope, m_config.inferring_mode);
for (const auto& pair : type_to_usages) {
auto index = get_interdex_group(pair.second, cls_to_interdex_groups,
num_interdex_groups);
Expand All @@ -211,21 +213,37 @@ std::vector<ConstTypeHashSet>& InterDexGrouping::group_by_interdex_set(
}
m_all_interdexing_groups[index].emplace(pair.first);
}

return m_all_interdexing_groups;
}

TypeSet InterDexGrouping::get_types_in_current_interdex_group(
const TypeSet& types, const ConstTypeHashSet& interdex_group_types) {
TypeSet InterDexGrouping::get_types_in_group(const InterdexSubgroupIdx id,
const TypeSet& types) const {
auto& interdex_group = m_all_interdexing_groups.at(id);
TypeSet group;
for (auto* type : types) {
if (interdex_group_types.count(type)) {
if (interdex_group.count(type)) {
group.insert(type);
}
}
return group;
}

void InterDexGrouping::visit_groups(
const ModelSpec& spec,
const TypeSet& current_group,
const std::function<void(const InterdexSubgroupIdx, const TypeSet&)>&
visit_fn) const {
for (InterdexSubgroupIdx id = 0; id < m_all_interdexing_groups.size(); id++) {
if (m_all_interdexing_groups.at(id).empty()) {
continue;
}
auto new_group = this->get_types_in_group(id, current_group);
if (new_group.size() < spec.min_count) {
continue;
}
visit_fn(id, new_group);
}
}

void InterDexGroupingConfig::init_type(const std::string& interdex_grouping) {

const static std::unordered_map<std::string, InterDexGroupingType>
Expand Down
28 changes: 22 additions & 6 deletions service/class-merging/InterDexGrouping.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,34 @@ struct InterDexGroupingConfig {
void init_inferring_mode(const std::string& mode);
};

struct ModelSpec;

class InterDexGrouping final {
public:
explicit InterDexGrouping(ConfigFiles& conf, InterDexGroupingConfig config)
: m_conf(conf), m_config(config) {}
explicit InterDexGrouping(const Scope& scope,
ConfigFiles& conf,
const InterDexGroupingConfig& config,
const ConstTypeHashSet& merging_targets)
: m_conf(conf), m_config(config) {
build_interdex_grouping(scope, merging_targets);
}

std::vector<ConstTypeHashSet>& group_by_interdex_set(
const Scope& scope, const ConstTypeHashSet& types);
size_t num_groups() const { return m_all_interdexing_groups.size(); }

TypeSet get_types_in_current_interdex_group(
const TypeSet& types, const ConstTypeHashSet& interdex_group_types);
void visit_groups(const ModelSpec& spec,
const TypeSet& current_group,
const std::function<void(const InterdexSubgroupIdx,
const TypeSet&)>& visit_fn) const;

private:
// Divide all types in the merging_targets into different interdex subgroups
// This grouping should be applied at the entire model level.
void build_interdex_grouping(const Scope& scope,
const ConstTypeHashSet& merging_targets);

TypeSet get_types_in_group(const InterdexSubgroupIdx id,
const TypeSet& types) const;

ConfigFiles& m_conf;
const InterDexGroupingConfig m_config;
std::vector<ConstTypeHashSet> m_all_interdexing_groups;
Expand Down
43 changes: 18 additions & 25 deletions service/class-merging/Model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,9 +593,9 @@ void Model::flatten_shapes(const MergerType& merger,
MergerType::ShapeCollector& shapes) {
size_t num_trimmed_types = trim_groups(shapes, m_spec.min_count);
m_stats.m_dropped += num_trimmed_types;
InterDexGrouping interdex_grouping(m_conf, m_spec.interdex_config);
const auto& all_interdex_groups =
interdex_grouping.group_by_interdex_set(m_scope, m_spec.merging_targets);
InterDexGrouping interdex_grouping(m_scope, m_conf, m_spec.interdex_config,
m_spec.merging_targets);
// Shape based grouping layer
// sort shapes by mergeables count
std::vector<const MergerType::Shape*> keys;
for (auto& shape_it : shapes) {
Expand Down Expand Up @@ -632,34 +632,27 @@ void Model::flatten_shapes(const MergerType& merger,

return left_group.size() > right_group.size();
});

// Type identity grouping layer (interface impl set)
for (const TypeSet* intf_set : intf_sets) {
const TypeSet& implementors = shape_hierarchy.groups.at(*intf_set);
// Per dex grouping layer
for (auto& pair : group_per_dex(implementors, m_spec)) {
auto dex_id = pair.first;
auto group_values = pair.second;
if (all_interdex_groups.size() > 1) {
for (InterdexSubgroupIdx interdex_gid = 0;
interdex_gid < all_interdex_groups.size();
interdex_gid++) {
if (all_interdex_groups[interdex_gid].empty()) {
continue;
}
auto new_group =
interdex_grouping.get_types_in_current_interdex_group(
group_values, all_interdex_groups[interdex_gid]);
if (new_group.size() < m_spec.min_count) {
continue;
}
create_mergers_helper(merger.type, *shape, *intf_set, dex_id,
new_group, m_spec.strategy, interdex_gid,
m_spec.max_count, m_spec.min_count);
m_stats.m_interdex_groups[interdex_gid] += new_group.size();
}
} else {
auto group = pair.second;
const auto interdex_visitor = [&](const InterdexSubgroupIdx gid,
const TypeSet& itd_group) {
create_mergers_helper(merger.type, *shape, *intf_set, dex_id,
group_values, m_spec.strategy, boost::none,
itd_group, m_spec.strategy, gid,
m_spec.max_count, m_spec.min_count);
m_stats.m_interdex_groups[gid] += itd_group.size();
};
// InterDex grouping layer
if (interdex_grouping.num_groups() > 1) {
interdex_grouping.visit_groups(m_spec, group, interdex_visitor);
} else {
create_mergers_helper(merger.type, *shape, *intf_set, dex_id, group,
m_spec.strategy, boost::none, m_spec.max_count,
m_spec.min_count);
}
}
}
Expand Down

0 comments on commit e4235a5

Please sign in to comment.