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.
This commit is contained in:
David Anderson 2008-09-23 22:00:47 -07:00
parent e83526aa63
commit 5cb4acf590
2 changed files with 48 additions and 8 deletions

View File

@ -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;
}

View File

@ -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