selfpatch-slr/plugin/access_discover.cpp
2025-10-13 16:16:28 +02:00

106 lines
2.8 KiB
C++

#include "access_discover.h"
#include <iostream>
static void print_gimple_tree(tree t, int depth, int indent = 2) {
if (!t)
return;
for (int i = 0; i < depth; ++i)
std::cout << " ";
std::cout << get_tree_code_name(TREE_CODE(t));
if (TREE_CODE(t) == FIELD_DECL && DECL_NAME(t))
std::cout << " <" << IDENTIFIER_POINTER(DECL_NAME(t)) << ">";
else if (TREE_CODE(t) == SSA_NAME && SSA_NAME_VAR(t) && DECL_NAME(SSA_NAME_VAR(t)))
std::cout << " <ssa " << IDENTIFIER_POINTER(DECL_NAME(SSA_NAME_VAR(t))) << ">";
std::cout << std::endl;
for (int i = 0; i < TREE_CODE_LENGTH(TREE_CODE(t)); ++i)
print_gimple_tree(TREE_OPERAND(t, i), depth + indent, indent);
}
static void print_gimple_statement(gimple* stmt) {
if (!stmt)
return;
print_gimple_stmt(stdout, stmt, 0, TDF_NONE);
for (unsigned i = 0; i < gimple_num_ops(stmt); ++i) {
tree operand = gimple_op(stmt, i);
print_gimple_tree(operand, 2, 2);
}
}
static int scan_gimple_statement(const char* funcname, gimple_stmt_iterator* gsi) {
/*
gimple *stmt = gsi_stmt(gsi);
scan_stmt_for_offsetof(funcname, &gsi);
for (unsigned i = 0; i < gimple_num_ops(stmt); ++i) {
tree op = gimple_op(stmt, i);
scan_tree_for_components(op, funcname, &gsi);
}
Build map: location->LocationPattern
Build GimpleStatementPattern tree from individual gimple statement
Add GimpleStatementPattern to LocationPattern (attached at matching variable names (potentially unnamed ssa))
Patterns include markers for member offsets (type, member, value)
Later load a set of RTLInstructionPattern to match the patterns
*/
print_gimple_statement(gsi_stmt(*gsi));
gimple* stmt = gsi_stmt(*gsi);
enum gimple_code stmt_code = gimple_code(stmt);
switch (stmt_code) {
case GIMPLE_CALL:
// check for offsetof, then fall through to operand scanning
case GIMPLE_ASSIGN:
case GIMPLE_COND:
case GIMPLE_LABEL:
case GIMPLE_RETURN:
return 0;
default:
return 1;
}
return 0;
}
static void clean_unnecessary_locations() {
// Remove all LocationPatterns that do no do any relevant struct accesses
}
static const pass_data access_discover_pass_data = {
GIMPLE_PASS,
"access_discover",
OPTGROUP_NONE,
TV_NONE,
0,0,0,0,
TODO_update_ssa | TODO_cleanup_cfg | TODO_verify_il
};
access_discover_pass::access_discover_pass(gcc::context *ctxt) : gimple_opt_pass(access_discover_pass_data, ctxt) {}
unsigned int access_discover_pass::execute(function* fun) {
const char* funcname = fun->decl && DECL_NAME(fun->decl)
? IDENTIFIER_POINTER(DECL_NAME(fun->decl))
: "<anonymous>";
basic_block bb;
FOR_EACH_BB_FN(bb, fun) {
for (gimple_stmt_iterator gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
if (scan_gimple_statement(funcname, &gsi) != 0) {
internal_error("fatal error in spslr plugin: %s", "failed to scan gimple statement");
return 0;
}
}
}
clean_unnecessary_locations();
return 0;
}