#include "pattern.h" #include class PatternNode { public: enum OP { NOP /* just move */, ADD, SUB, NEG, CALL, MEMREF }; private: OP m_op; public: // ... }; class PatternEdge { public: enum DATATYPE { VAR, CONST, FIELDOFF /* field offset is specialization of CONST */ }; private: DATATYPE m_datatype; // std::size_t m_datasize; public: // ... }; // TODO -> build pattern tree from output root to input leafs class LocationPattern { // ... public: LocationPattern() {} ~LocationPattern() {} }; static std::unordered_map locations; int register_gimple_statement_pattern(gimple_stmt_iterator* gsi) { gimple* stmt = gsi_stmt(*gsi); enum gimple_code stmt_code = gimple_code(stmt); location_t stmt_location = gimple_location(stmt); auto lp_it = locations.find(stmt_location); if (lp_it == locations.end()) { auto [new_it, success] = locations.emplace(stmt_location, LocationPattern{}); if (!success) return 1; lp_it = new_it; } LocationPattern& pattern = lp_it->second; /* for (unsigned i = 0; i < gimple_num_ops(stmt); ++i) { tree op = gimple_op(stmt, i); scan_tree_for_components(op, funcname, &gsi); } */ 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; } void clean_unnecessary_patterns() { // TODO -> erase all that do not contain a single member offset } int register_rtl_instruction_pattern(rtx_insn* i) { // TODO return 0; } int annotate_rtl() { // TODO return 0; }