106 lines
2.8 KiB
C++
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;
|
|
}
|