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:
parent
e83526aa63
commit
5cb4acf590
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user