Skip to content

Commit

Permalink
Add option to dump switch keys in ReduceSparseSwitches
Browse files Browse the repository at this point in the history
Summary:
As title. Add an option to write all sparse switches with at least a given number of keys to CSV files.

NOTE: This does not currently filter on hotness.

Reviewed By: NTillmann

Differential Revision: D68778450

fbshipit-source-id: f67a4e6141d04a663f7ed39985e4f643f2b5a8d0
  • Loading branch information
agampe authored and facebook-github-bot committed Jan 31, 2025
1 parent fee4c0f commit 836ed0d
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 0 deletions.
62 changes: 62 additions & 0 deletions opt/reduce-sparse-switches/ReduceSparseSwitchesPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@

#include "ReduceSparseSwitchesPass.h"

#include <filesystem>
#include <system_error>

#include "ConfigFiles.h"
#include "DexInstruction.h"
#include "InstructionLowering.h"
#include "ScopedCFG.h"
#include "Show.h"
#include "SourceBlocks.h"
#include "Trace.h"
Expand Down Expand Up @@ -205,6 +210,56 @@ static void multiplex_sparse_switch_into_packed_and_sparse(
(new IRInstruction(OPCODE_SWITCH))->set_src(0, tmp_reg),
goto_block, packed_cases);
}

void write_sparse_switches(DexStoresVector& stores,
ConfigFiles& conf,
uint64_t threshold) {
std::filesystem::path dirpath(conf.metafile("sparse_switches"));
std::error_code ec;
std::filesystem::create_directories(dirpath, ec);
always_assert(ec.value() == 0);

walk::parallel::methods(build_class_scope(stores), [&](DexMethod* method) {
if (method->get_code() == nullptr) {
return;
}
cfg::ScopedCFG cfg(method->get_code());
size_t running_index = 0;
for (auto* block : cfg->blocks()) {
auto last_insn_it = block->get_last_insn();
if (last_insn_it == block->end()) {
continue;
}
if (!opcode::is_switch(last_insn_it->insn->opcode())) {
continue;
}
if (block->succs().size() - 1 < threshold) {
continue;
}

if (!is_sufficiently_sparse(block)) {
continue;
}

auto method_name = show_deobfuscated(method);
std::replace(method_name.begin(), method_name.end(), '/', '.');
method_name.append(".");
method_name.append(std::to_string(running_index));
method_name.append(".csv");
++running_index;

auto name = dirpath / method_name;

std::ofstream file(name);
for (auto* e : block->succs()) {
if (e->type() == cfg::EDGE_BRANCH) {
file << *e->case_key() << "\n";
}
}
}
});
}

} // namespace

// Find switches which can be split into packed and sparse switches, and apply
Expand Down Expand Up @@ -370,11 +425,18 @@ void ReduceSparseSwitchesPass::bind_config() {
bind("min_multiplexing_switch_cases",
m_config.min_multiplexing_switch_cases,
m_config.min_multiplexing_switch_cases);

bind("write_sparse_switches", m_config.write_sparse_switches,
m_config.write_sparse_switches);
};

void ReduceSparseSwitchesPass::run_pass(DexStoresVector& stores,
ConfigFiles& conf,
PassManager& mgr) {
if (m_config.write_sparse_switches < std::numeric_limits<uint64_t>::max()) {
write_sparse_switches(stores, conf, m_config.write_sparse_switches);
}

// Don't run under instrumentation.
if (mgr.get_redex_options().instrument_pass_enabled) {
return;
Expand Down
4 changes: 4 additions & 0 deletions opt/reduce-sparse-switches/ReduceSparseSwitchesPass.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#pragma once

#include <limits>

#include "Pass.h"
#include "PassManager.h"

Expand Down Expand Up @@ -42,6 +44,8 @@ class ReduceSparseSwitchesPass : public Pass {
uint64_t min_splitting_switch_cases{10};

uint64_t min_multiplexing_switch_cases{64};

uint64_t write_sparse_switches{std::numeric_limits<uint64_t>::max()};
};

ReduceSparseSwitchesPass() : Pass("ReduceSparseSwitchesPass") {}
Expand Down
10 changes: 10 additions & 0 deletions redex.py
Original file line number Diff line number Diff line change
Expand Up @@ -1417,6 +1417,16 @@ def get_compression_list() -> typing.List[CompressionEntry]:
None,
CompressionLevel.DEFAULT, # Bit larger.
),
CompressionEntry(
"Redex Sparse Switches Data",
lambda args: True,
True,
[],
["sparse_switches"],
"redex-sparse-switches.tar.xz",
None,
CompressionLevel.DEFAULT, # Bit larger.
),
]


Expand Down

0 comments on commit 836ed0d

Please sign in to comment.