[Decompiler] WIP Expression Stacking (#178)

* wip

* fix the stupid if thing

* update

* fix

* fix some ordering issues
This commit is contained in:
water111
2021-01-02 18:24:45 -05:00
committed by GitHub
parent feead303aa
commit 7af6dce1b2
14 changed files with 693 additions and 140 deletions
+42 -12
View File
@@ -2,7 +2,9 @@
#include "ExpressionStack.h"
std::string ExpressionStack::StackEntry::print(LinkedObjectFile& file) {
return fmt::format("d: {} {} <- {}", display, destination.to_charp(), source->print(file));
return fmt::format("d: {} s: {} | {} <- {}", display, sequence_point,
destination.has_value() ? destination.value().to_charp() : "N/A",
source->print(file));
}
std::string ExpressionStack::print(LinkedObjectFile& file) {
@@ -14,9 +16,10 @@ std::string ExpressionStack::print(LinkedObjectFile& file) {
return result;
}
void ExpressionStack::set(Register reg, std::shared_ptr<IR> value) {
void ExpressionStack::set(Register reg, std::shared_ptr<IR> value, bool sequence_point) {
StackEntry entry;
entry.display = true; // by default, we should display everything!
entry.sequence_point = sequence_point;
entry.destination = reg;
entry.source = std::move(value);
m_stack.push_back(entry);
@@ -32,19 +35,42 @@ bool ExpressionStack::is_single_expression() {
return count == 1;
}
void ExpressionStack::add_no_set(std::shared_ptr<IR> value, bool sequence_point) {
StackEntry entry;
entry.display = true;
entry.destination = std::nullopt;
entry.source = value;
entry.sequence_point = sequence_point;
m_stack.push_back(entry);
}
/*!
* "Remove" an entry from the stack. Cannot cross a sequence point.
* Internally, the entry is still stored. It is just flagged with display=false.
*/
std::shared_ptr<IR> ExpressionStack::get(Register reg) {
// see if the stack top is this register...
if (!display_stack_empty()) {
auto& top = get_display_stack_top();
if (top.destination == reg) {
// yep. We can compact!
top.display = false;
return top.source;
for (size_t i = m_stack.size(); i-- > 0;) {
auto& entry = m_stack.at(i);
if (entry.display) {
if (entry.destination == reg) {
entry.display = false;
return entry.source;
} else {
// we didn't match
if (entry.sequence_point) {
// and it's a sequence point! can't look any more back than this.
return std::make_shared<IR_Register>(reg, -1);
}
}
}
}
return std::make_shared<IR_Register>(reg, -1);
}
/*!
* Convert the stack into a sequence of compacted expressions.
* This is final result of the expression compaction algorithm.
*/
std::vector<std::shared_ptr<IR>> ExpressionStack::get_result() {
std::vector<std::shared_ptr<IR>> result;
@@ -52,9 +78,13 @@ std::vector<std::shared_ptr<IR>> ExpressionStack::get_result() {
if (!e.display) {
continue;
}
auto dst_reg = std::make_shared<IR_Register>(e.destination, -1);
auto op = std::make_shared<IR_Set>(IR_Set::EXPR, dst_reg, e.source);
result.push_back(op);
if (e.destination.has_value()) {
auto dst_reg = std::make_shared<IR_Register>(e.destination.value(), -1);
auto op = std::make_shared<IR_Set>(IR_Set::EXPR, dst_reg, e.source);
result.push_back(op);
} else {
result.push_back(e.source);
}
}
return result;