Skip to content

Commit

Permalink
Add option to inline reused subexpressions
Browse files Browse the repository at this point in the history
  • Loading branch information
frabert committed Aug 26, 2022
1 parent 706c7da commit 36acd97
Show file tree
Hide file tree
Showing 11 changed files with 40 additions and 8 deletions.
2 changes: 2 additions & 0 deletions include/rellic/AST/Util.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ struct DecompilationContext {

size_t num_literal_structs = 0;
size_t num_declared_structs = 0;

bool inline_reused_expressions = false;
};

template <typename TKey1, typename TKey2, typename TKey3, typename TValue>
Expand Down
1 change: 1 addition & 0 deletions include/rellic/Decompiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace rellic {
struct DecompilationOptions {
bool lower_switches = false;
bool remove_phi_nodes = false;
bool inline_reused_expressions = false;
};

struct DecompilationResult {
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/IRToASTVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1311,7 +1311,7 @@ void IRToASTVisitor::VisitFunctionDecl(llvm::Function &func) {
var = ast.CreateVarDecl(
fdecl, expr_gen.GetQualType(alloca->getAllocatedType()), name);
fdecl->addDecl(var);
} else if (inst.hasNUsesOrMore(2) ||
} else if ((inst.hasNUsesOrMore(2) && !dec_ctx.inline_reused_expressions) ||
(inst.hasNUsesOrMore(1) && llvm::isa<llvm::CallInst>(inst)) ||
llvm::isa<llvm::PHINode>(inst)) {
if (!inst.getType()->isVoidTy()) {
Expand Down
1 change: 1 addition & 0 deletions lib/Decompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Result<DecompilationResult, DecompilationError> Decompile(

ASTBuilder ast{*ast_unit};
rellic::DecompilationContext dec_ctx;
dec_ctx.inline_reused_expressions = options.inline_reused_expressions;
dec_ctx.marker_expr = ast.CreateAdd(ast.CreateFalse(), ast.CreateFalse());
rellic::GenerateAST::run(*module, dec_ctx, *ast_unit);
// TODO(surovic): Add llvm::Value* -> clang::Decl* map
Expand Down
2 changes: 1 addition & 1 deletion scripts/decompile.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def run_cmd(cmd, timeout):
def decompile(self, rellic, input, output, timeout):
cmd = [rellic]
cmd.extend(
["--input", input, "--output", output]
["--input", input, "--output", output, "--inline-expressions"]
)
p = run_cmd(cmd, timeout)

Expand Down
2 changes: 1 addition & 1 deletion scripts/roundtrip.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def compile(self, clang, input, output, timeout, options=None):
def decompile(self, rellic, input, output, timeout):
cmd = [rellic]
cmd.extend(
["--input", input, "--output", output]
["--input", input, "--output", output, "--inline-expressions"]
)
p = run_cmd(cmd, timeout)

Expand Down
8 changes: 4 additions & 4 deletions tests/tools/decomp/diff_outputs.mk
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ LL_DIFFS := $(patsubst %.ll,%.diff,$(wildcard *.ll))
@echo ""
@echo "\`\`\`diff"
-@diff -u \
<( $(OLD_RELLIC) --input $< --output /dev/stdout ) \
<( $(NEW_RELLIC) --input $< --output /dev/stdout ) || true
<( $(OLD_RELLIC) --input $< --output /dev/stdout --inline-expressions) \
<( $(NEW_RELLIC) --input $< --output /dev/stdout --inline-expressions) || true
@echo "\`\`\`"
@echo ""

Expand All @@ -36,8 +36,8 @@ LL_DIFFS := $(patsubst %.ll,%.diff,$(wildcard *.ll))
@echo ""
@echo "\`\`\`diff"
-@diff -u \
<( $(OLD_RELLIC) --input $< --output /dev/stdout ) \
<( $(NEW_RELLIC) --input $< --output /dev/stdout ) || true
<( $(OLD_RELLIC) --input $< --output /dev/stdout --inline-expressions) \
<( $(NEW_RELLIC) --input $< --output /dev/stdout --inline-expressions) || true
@echo "\`\`\`"
@echo ""

Expand Down
4 changes: 4 additions & 0 deletions tools/decomp/Decomp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ DEFINE_bool(remove_phi_nodes, false,
"Remove PHINodes from input bitcode before decompilation.");
DEFINE_bool(lower_switch, false,
"Remove SwitchInst by lowering them to branches.");
DEFINE_bool(inline_expressions, false,
"Inline subexpressions used by multiple expressions instead of "
"creating auxiliary variables.");

DECLARE_bool(version);

Expand Down Expand Up @@ -123,6 +126,7 @@ int main(int argc, char* argv[]) {
rellic::DecompilationOptions opts{};
opts.lower_switches = FLAGS_lower_switch;
opts.remove_phi_nodes = FLAGS_remove_phi_nodes;
opts.inline_reused_expressions = FLAGS_inline_expressions;

auto result{rellic::Decompile(std::move(module), opts)};
if (result.Succeeded()) {
Expand Down
18 changes: 18 additions & 0 deletions tools/xref/Xref.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,26 @@ static void Decompile(const httplib::Request& req, httplib::Response& res) {
return;
}

auto json{llvm::json::parse(req.body)};
if (!json) {
llvm::json::Object msg{{"message", "Invalid request: cannot parse."}};
SendJSON(res, msg);
res.status = 400;
return;
}

auto inline_exprs{json->getAsObject()->getBoolean("inline_exprs")};
if (!inline_exprs) {
llvm::json::Object msg{
{"message", "Invalid request: no key for inline_exprs."}};
SendJSON(res, msg);
res.status = 400;
return;
}

try {
session.DecompContext = std::make_unique<rellic::DecompilationContext>();
session.DecompContext->inline_reused_expressions = *inline_exprs;
std::vector<std::string> args{"-Wno-pointer-to-int-cast",
"-Wno-pointer-sign", "-target",
session.Module->getTargetTriple()};
Expand Down
2 changes: 2 additions & 0 deletions tools/xref/www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@
:disabled="!module"><br>
<input type="button" @click="useDefaultChain" value="Use default chain">
<input type="button" @click="openAngha" value="Open AnghaBench file">
<input type="checkbox" v-model="inline_exprs" name="inline_exprs">
<label for="inline_exprs">Inline expressions</label>
</header>
<main>
<splitpanes class="default-theme">
Expand Down
6 changes: 5 additions & 1 deletion tools/xref/www/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ const app = new Vue({
el: '#app',
components: { Splitpanes, Pane },
data: {
inline_exprs: false,
dragging: false,
ast: null,
module: null,
Expand Down Expand Up @@ -271,7 +272,10 @@ const app = new Vue({
try {
let res = await fetch("/action/decompile", {
credentials: "include",
method: "POST"
method: "POST",
body: JSON.stringify({
inline_exprs: this.inline_exprs
})
})
if (res.status != 200) {
throw (await res.json()).message
Expand Down

0 comments on commit 36acd97

Please sign in to comment.