From 5cb4acf590ef134c84e3cd629c13ac2492ecf197 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 23 Sep 2008 22:00:47 -0700 Subject: [PATCH] Added some notion of def-use to unfold copy propagation across registers and the eval stack. At some point we will need to walk the expr tree to fold this back where appropriate, i.e. single use for calls. --- sourcepawn/decompiler/code_analyzer.cpp | 30 +++++++++++++++++++++++++ sourcepawn/decompiler/code_analyzer.h | 26 ++++++++++++++------- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/sourcepawn/decompiler/code_analyzer.cpp b/sourcepawn/decompiler/code_analyzer.cpp index 24f2eeaa4..6e41d1594 100644 --- a/sourcepawn/decompiler/code_analyzer.cpp +++ b/sourcepawn/decompiler/code_analyzer.cpp @@ -43,6 +43,15 @@ struct ControlFlowGraph FunctionInfo *func; }; +DefineNode::DefineNode(BaseNode *o, const char *fmt, ...) : BaseNode(_OP_DEFINE), other(o) +{ + va_list ap; + + va_start(ap, fmt); + Sp_FormatArgs(name, sizeof(name), fmt, ap); + va_end(ap); +} + static FunctionInfo *sp_InferFuncPrototype(sp_decomp_t *dc, uint32_t code_addr, bool is_public) { sp_tag_t *pTag; @@ -333,6 +342,14 @@ void sp_DebugExprTree(PrintBuffer *buffer, BaseNode *node, bool is_stmt=false) { switch (node->op) { + case _OP_DEFINE: + { + DefineNode *def = (DefineNode *)node; + + buffer->Append("new %s = ", def->name); + sp_DebugExprTree(buffer, def->other, is_stmt); + break; + } case OP_CALL: { CallNode *call = (CallNode *)node; @@ -345,6 +362,13 @@ void sp_DebugExprTree(PrintBuffer *buffer, BaseNode *node, bool is_stmt=false) buffer->Append(")"); break; } + case _OP_USE: + { + UseNode *unode = (UseNode *)node; + + buffer->Append("%s", unode->def->name); + break; + } case _OP_VAR: { VarNode *var_node = (VarNode *)node; @@ -577,6 +601,7 @@ int sp_AnalyzeGraph(sp_decomp_t *dc, ControlFlowGraph *graph) FunctionInfo *func, *tfunc; cell_t p1, p2, op; FuncVar *v1, *v2; + unsigned int callnumber = 0; unsigned int stack_entries = 0; StackEntry eval_stack[MAX_STACK_ENTRIES]; @@ -637,6 +662,11 @@ int sp_AnalyzeGraph(sp_decomp_t *dc, ControlFlowGraph *graph) assert(sp <= 0); pri = new (graph) CallNode(tfunc, nodes, cnode->val); + pri = new (graph) DefineNode(pri, "call%03x", ++callnumber); + rtemp = new (graph) StmtNode(_OP_STMT, pri, NULL); + root_tail->next = rtemp; + root_tail = rtemp; + pri = new (graph) UseNode((DefineNode *)pri); break; } diff --git a/sourcepawn/decompiler/code_analyzer.h b/sourcepawn/decompiler/code_analyzer.h index 7182338b7..ebec22e41 100644 --- a/sourcepawn/decompiler/code_analyzer.h +++ b/sourcepawn/decompiler/code_analyzer.h @@ -5,13 +5,14 @@ enum Opcode { - _OP_VAR = -1, - _OP_STMT = -2, - _OP_CONST = -3, - _OP_STORE = -4, - _OP_NEW = -5, - _OP_MODULO = -6, - _OP_EMPTY = -7, + _OP_VAR = -1, /* Variable container */ + _OP_STMT = -2, /* Statement contained */ + _OP_CONST = -3, /* Constant value */ + _OP_STORE = -4, /* Store operation (binary assignment) */ + _OP_NEW = -5, /* Variable declaration */ + _OP_MODULO = -6, /* Binary modulo operator */ + _OP_DEFINE = -7, /* "define" node for SSA */ + _OP_USE = -8, /* "use" node for SSA */ #define OPDEF(num,name,str,params) \ OP_##name = num, #include "opcodes.tbl" @@ -70,8 +71,17 @@ struct CallNode : public BaseNode struct DefineNode : public BaseNode { - TempNode(const char *name + DefineNode(BaseNode *o, const char *fmt, ...); char name[32]; + BaseNode *other; +}; + +struct UseNode : public BaseNode +{ + UseNode(DefineNode *n) : BaseNode(_OP_USE), def(n) + { + } + DefineNode *def; }; struct UnaryNode : public BaseNode