MWCC/compiler_and_linker/unsorted/IroDump.c

661 lines
22 KiB
C

#include "compiler/IroDump.h"
#include "compiler/IroFlowgraph.h"
#include "compiler/IroLinearForm.h"
#include "compiler/IroPropagate.h"
#include "compiler/IroUtil.h"
#include "compiler/CFunc.h"
#include "compiler/CInt64.h"
#include "compiler/CParser.h"
#include "compiler/objects.h"
#include "compiler/IroVars.h"
#include "compiler/IroCSE.h"
static FILE *DumpFile;
static char *nodenames[MAXEXPR];
char *IRO_NodeName(ENodeType nodetype) {
return nodenames[nodetype];
}
void IRO_InitializeNodeNamesArray(void) {
int i;
for (i = 0; i < MAXEXPR; i++)
nodenames[i] = "";
nodenames[EPOSTINC] = "EPOSTINC";
nodenames[EPOSTDEC] = "EPOSTDEC";
nodenames[EPREINC] = "EPREINC";
nodenames[EPREDEC] = "EPREDEC";
nodenames[EINDIRECT] = "EINDIRECT";
nodenames[EMONMIN] = "EMONMIN";
nodenames[EBINNOT] = "EBINNOT";
nodenames[ELOGNOT] = "ELOGNOT";
nodenames[EFORCELOAD] = "EFORCELOAD";
nodenames[EMUL] = "EMUL";
nodenames[EMULV] = "EMULV";
nodenames[EDIV] = "EDIV";
nodenames[EMODULO] = "EMODULO";
nodenames[EADDV] = "EADDV";
nodenames[ESUBV] = "ESUBV";
nodenames[EADD] = "EADD";
nodenames[ESUB] = "ESUB";
nodenames[ESHL] = "ESHL";
nodenames[ESHR] = "ESHR";
nodenames[ELESS] = "ELESS";
nodenames[EGREATER] = "EGREATER";
nodenames[ELESSEQU] = "ELESSEQU";
nodenames[EGREATEREQU] = "EGREATEREQU";
nodenames[EEQU] = "EEQU";
nodenames[ENOTEQU] = "ENOTEQU";
nodenames[EAND] = "EAND";
nodenames[EXOR] = "EXOR";
nodenames[EOR] = "EOR";
nodenames[ELAND] = "ELAND";
nodenames[ELOR] = "ELOR";
nodenames[EASS] = "EASS";
nodenames[EMULASS] = "EMULASS";
nodenames[EDIVASS] = "EDIVASS";
nodenames[EMODASS] = "EMODASS";
nodenames[EADDASS] = "EADDASS";
nodenames[ESUBASS] = "ESUBASS";
nodenames[ESHLASS] = "ESHLASS";
nodenames[ESHRASS] = "ESHRASS";
nodenames[EANDASS] = "EANDASS";
nodenames[EXORASS] = "EXORASS";
nodenames[EORASS] = "EORASS";
nodenames[ECOMMA] = "ECOMMA";
nodenames[EPMODULO] = "EPMODULO";
nodenames[EROTL] = "EROTL";
nodenames[EROTR] = "EROTR";
nodenames[EBCLR] = "EBCLR";
nodenames[EBTST] = "EBTST";
nodenames[EBSET] = "EBSET";
nodenames[ETYPCON] = "ETYPCON";
nodenames[EBITFIELD] = "EBITFIELD";
nodenames[EINTCONST] = "EINTCONST";
nodenames[EFLOATCONST] = "EFLOATCONST";
nodenames[ESTRINGCONST] = "ESTRINGCONST";
nodenames[ECOND] = "ECOND";
nodenames[EFUNCCALL] = "EFUNCCALL";
nodenames[EFUNCCALLP] = "EFUNCCALLP";
nodenames[EOBJREF] = "EOBJREF";
nodenames[EMFPOINTER] = "EMFPOINTER";
nodenames[ENULLCHECK] = "ENULLCHECK";
nodenames[EPRECOMP] = "EPRECOMP";
nodenames[ETEMP] = "ETEMP";
nodenames[EARGOBJ] = "EARGOBJ";
nodenames[ELOCOBJ] = "ELOCOBJ";
nodenames[ELABEL] = "ELABEL";
nodenames[ESETCONST] = "ESETCONST";
nodenames[ENEWEXCEPTION] = "ENEWEXCEPTION";
nodenames[ENEWEXCEPTIONARRAY] = "ENEWEXCEPTIONARRAY";
nodenames[EOBJLIST] = "EOBJLIST";
nodenames[EMEMBER] = "EMEMBER";
nodenames[ETEMPLDEP] = "ETEMPLDEP";
nodenames[EINSTRUCTION] = "EINSTRUCTION";
nodenames[EDEFINE] = "EDEFINE";
nodenames[EREUSE] = "EREUSE";
nodenames[EASSBLK] = "EASSBLK";
nodenames[EVECTOR128CONST] = "EVECTOR128CONST";
nodenames[ECONDASS] = "ECONDASS";
}
static void DumpENode(ENode *enode) {
char buf[64];
if (IRO_Log) {
switch (enode->type) {
case EOBJREF:
fprintf(DumpFile, "%s", enode->data.objref->name->name);
break;
case EINTCONST:
CInt64_PrintDec(buf, enode->data.intval);
fprintf(DumpFile, "%s", buf);
break;
case EFLOATCONST:
fprintf(DumpFile, "%g", enode->data.floatval.value);
break;
case EVECTOR128CONST:
fprintf(DumpFile, "%.8lX%.8lX%.8lX%.8lX",
enode->data.vector128val.ul[0],
enode->data.vector128val.ul[1],
enode->data.vector128val.ul[2],
enode->data.vector128val.ul[3]
);
break;
}
}
}
static void DumpLinearNode(IROLinear *linear) {
int i;
if (IRO_Log) {
fprintf(DumpFile, "%4d: ", linear->index);
switch (linear->type) {
case IROLinearNop:
fprintf(DumpFile, "Nop");
break;
case IROLinearOperand:
fprintf(DumpFile, "Operand ");
DumpENode(linear->u.node);
break;
case IROLinearOp1Arg:
fprintf(DumpFile, "%s %d", nodenames[linear->nodetype], linear->u.monadic->index);
break;
case IROLinearOp2Arg:
fprintf(DumpFile, "%s %d %d", nodenames[linear->nodetype], linear->u.diadic.left->index, linear->u.diadic.right->index);
break;
case IROLinearGoto:
fprintf(DumpFile, "Goto %s", linear->u.label.label->name->name);
break;
case IROLinearIf:
fprintf(DumpFile, "If %d %s", linear->u.label.x4->index, linear->u.label.label->name->name);
break;
case IROLinearIfNot:
fprintf(DumpFile, "IfNot %d %s", linear->u.label.x4->index, linear->u.label.label->name->name);
break;
case IROLinearReturn:
fprintf(DumpFile, "Return ");
if (linear->u.monadic)
fprintf(DumpFile, "%d", linear->u.monadic->index);
break;
case IROLinearLabel:
fprintf(DumpFile, "Label %s", linear->u.label.label->name->name);
break;
case IROLinearSwitch:
fprintf(DumpFile, "Switch %d", linear->u.swtch.x4->index);
break;
case IROLinearOp3Arg:
fprintf(DumpFile, "%s %d %d %d",
nodenames[linear->nodetype],
linear->u.args3.a->index,
linear->u.args3.b->index,
linear->u.args3.c->index);
break;
case IROLinearFunccall:
fprintf(DumpFile, "Funccall %d(", linear->u.funccall.linear8->index);
for (i = 0; i < linear->u.funccall.argCount; i++) {
fprintf(DumpFile, "%d", linear->u.funccall.args[i]->index);
if (i < (linear->u.funccall.argCount - 1))
fprintf(DumpFile, ",");
}
fprintf(DumpFile, ")");
break;
case IROLinearBeginCatch:
fprintf(DumpFile, "BeginCatch %d", linear->u.ctch.linear->index);
break;
case IROLinearEndCatch:
fprintf(DumpFile, "EndCatch %d", linear->u.monadic->index);
break;
case IROLinearEndCatchDtor:
fprintf(DumpFile, "EndCatchDtor %d", linear->u.monadic->index);
break;
case IROLinearEnd:
fprintf(DumpFile, "End");
break;
}
if (linear->flags & IROLF_Assigned) fprintf(DumpFile, " <assigned>");
if (linear->flags & IROLF_Used) fprintf(DumpFile, " <used>");
if (linear->flags & IROLF_Ind) fprintf(DumpFile, " <ind>");
if (linear->flags & IROLF_Subs) fprintf(DumpFile, " <subs>");
if (linear->flags & IROLF_LoopInvariant) fprintf(DumpFile, " <loop invariant>");
if (linear->flags & IROLF_BeginLoop) fprintf(DumpFile, " <begin loop>");
if (linear->flags & IROLF_EndLoop) fprintf(DumpFile, " <end loop>");
if (linear->flags & IROLF_Ris) fprintf(DumpFile, " <ris>");
if (linear->flags & IROLF_Immind) fprintf(DumpFile, " <immind>");
if (linear->flags & IROLF_Reffed) fprintf(DumpFile, " <reffed>");
if (linear->flags & IROLF_VecOp) fprintf(DumpFile, " <vec op>");
if (linear->flags & IROLF_VecOpBase) fprintf(DumpFile, " <vec op_base>");
if (linear->flags & IROLF_CounterLoop) fprintf(DumpFile, " <counter loop>");
if (linear->flags & IROLF_BitfieldIndirect) fprintf(DumpFile, " <bitfield_indirect>");
if (linear->flags & IROLF_CouldError) fprintf(DumpFile, " <could_error>");
if (linear->rtype && CParser_IsVolatile(linear->rtype, linear->nodeflags & ENODE_FLAG_QUALS))
fprintf(DumpFile, " <volatile>");
if (IS_LINEAR_ENODE(linear, EOBJREF)) {
VarRecord *var = IRO_FindVar(linear->u.node->data.objref, 0, 1);
if (var && is_volatile_object(var->object))
fprintf(DumpFile, " <volatile obj>");
}
fprintf(DumpFile, "\n");
}
}
static void DumpAct(IROLinear *linear, Boolean isFirst) {
if (!isFirst)
DumpLinearNode(linear);
}
void IRO_DumpIntTree(IROLinear *linear) {
IRO_WalkTree(linear, DumpAct);
}
void IRO_DumpLinearList(IROLinear *linear) {
if (!IRO_Log)
return;
while (linear) {
DumpLinearNode(linear);
linear = linear->next;
}
fprintf(DumpFile, "\n");
}
static void DumpList(int num, UInt16 *list) {
int i;
if (IRO_Log) {
for (i = 0; i < num; i++)
fprintf(DumpFile, "%d ", list[i]);
fprintf(DumpFile, "\n");
}
}
void IRO_DumpBits(char *name, BitVector *bv) {
SInt32 i;
SInt32 rangeStart;
Boolean inRange = 0;
Boolean isFirst = 1;
if (!IRO_Log)
return;
fprintf(DumpFile, name);
if (!bv) {
fprintf(DumpFile, "NULL");
} else {
for (i = 0; i < (bv->size * 32); i++) {
if (Bv_IsBitSet(i, bv)) {
if (!inRange) {
if (!isFirst)
fputc(',', DumpFile);
isFirst = 0;
fprintf(DumpFile, "%d", i);
inRange = 1;
rangeStart = i;
}
} else {
if (inRange) {
inRange = 0;
if (i != (rangeStart + 1))
fprintf(DumpFile, "-%d", i - 1);
}
}
}
if (inRange && i != (rangeStart + 1))
fprintf(DumpFile, "-%d", i - 1);
}
fprintf(DumpFile, "\n");
}
void IRO_DumpAfterPhase(char *str, Boolean flag) {
#ifdef CW_PATCH_DEBUG
if (copts.debuglisting)
flag = 1;
#endif
if (flag) {
IRO_Dump("Dumping function %s after %s \n", FunctionName ? FunctionName->name->name : "Init-code", str);
IRO_Dump("--------------------------------------------------------------------------------\n");
IRO_DumpFlowgraph();
}
}
void IRO_LogForFunction(char *name) {
if (FunctionName) {
if (!strcmp(FunctionName->name->name, name))
IRO_Log = 1;
else
IRO_Log = 0;
}
}
void IRO_DumpFlowgraph(void) {
IRONode *node;
IROLinear *linear;
if (IRO_Log && DumpFile) {
fprintf(DumpFile, "\nFlowgraph\n");
for (node = IRO_FirstNode; node; node = node->nextnode) {
fprintf(DumpFile, "Flowgraph node %d First=%d, Last=%d\n", node->index, node->first->index, node->last->index);
fprintf(DumpFile, "Succ = ");
DumpList(node->numsucc, node->succ);
fprintf(DumpFile, "Pred = ");
DumpList(node->numpred, node->pred);
fprintf(DumpFile, "MustReach = %d, MustReach1=%d\n", node->mustreach, node->mustreach1);
fprintf(DumpFile, "LoopDepth = %d\n", node->loopdepth);
IRO_DumpBits("Dom: ", node->dom);
if ((linear = node->first)) {
while (1) {
DumpLinearNode(linear);
if (linear == node->last)
break;
linear = linear->next;
}
}
fprintf(DumpFile, "\n\n");
}
fprintf(DumpFile, "\n");
fflush(DumpFile);
}
}
void IRO_DumpNode(IRONode *node) {
IROLinear *linear;
if (IRO_Log) {
if (!DumpFile)
return;
while (node) {
fprintf(DumpFile, "Flowgraph node %d First=%d, Last=%d\n", node->index, node->first->index,
node->last->index);
fprintf(DumpFile, "Succ = ");
DumpList(node->numsucc, node->succ);
fprintf(DumpFile, "Pred = ");
DumpList(node->numpred, node->pred);
fprintf(DumpFile, "MustReach = %d MustReach1 = %d\n", node->mustreach, node->mustreach1);
fprintf(DumpFile, "LoopDepth = %d\n", node->loopdepth);
IRO_DumpBits("Dom: ", node->dom);
if ((linear = node->first)) {
while (1) {
DumpLinearNode(linear);
if (linear == node->last)
break;
linear = linear->next;
}
}
fprintf(DumpFile, "\n\n");
node = node->nextnode;
}
fprintf(DumpFile, "\n");
fflush(DumpFile);
}
}
void IRO_DumpAssignments(void) {
IROAssign *assign;
if (IRO_Log) {
fprintf(DumpFile, "\nAssignments\n\n");
for (assign = IRO_FirstAssign; assign; assign = assign->next) {
fprintf(DumpFile, "%5d ", assign->index);
DumpLinearNode(assign->linear);
fprintf(DumpFile, "\n");
}
fprintf(DumpFile, "\n");
}
}
void IRO_DumpVars(void) {
VarRecord *var;
if (IRO_Log) {
fprintf(DumpFile, "\nVariables\n");
for (var = IRO_FirstVar; var; var = var->next) {
fprintf(DumpFile, "%5d %s %s\n", var->index, var->object->name->name, var->xB ? "<addressed>" : "");
}
fprintf(DumpFile, "\n");
}
}
void IRO_DumpDf(void) {
IRONode *node;
if (IRO_Log) {
for (node = IRO_FirstNode; node; node = node->nextnode) {
fprintf(DumpFile, "Node %d\n", node->index);
if (node->x16) IRO_DumpBits("In: ", node->x16);
if (node->x1E) IRO_DumpBits("Gen: ", node->x1E);
if (node->x22) IRO_DumpBits("Kill: ", node->x22);
if (node->x1A) IRO_DumpBits("Out: ", node->x1A);
if (node->x2A) IRO_DumpBits("AA: ", node->x2A);
fprintf(DumpFile, "\n");
}
fprintf(DumpFile, "\n");
}
}
void IRO_DumpExprs(void) {
IROExpr *expr;
if (IRO_Log) {
fprintf(DumpFile, "Expressions\n\n");
for (expr = IRO_FirstExpr; expr; expr = expr->next) {
fprintf(DumpFile, "%4d: %d FN:%d CE:%d NS:%d ", expr->index, expr->linear->index, expr->node->index, expr->couldError, expr->notSubable);
IRO_DumpBits("Depends: ", expr->depends);
fprintf(DumpFile, "\n");
}
fprintf(DumpFile, "\n");
}
}
void IRO_SetupDump(void) {
#ifdef CW_PATCH_DEBUG
IRO_Log = 1;
#endif
if (IRO_Log) {
if ((DumpFile = fopen("OPT.LOG", "wt")) == NULL)
IRO_Log = 0;
}
}
void IRO_CleanupDump(void) {
if (DumpFile)
fclose(DumpFile);
}
void IRO_Dump(char *format, ...) {
va_list va;
if (IRO_Log) {
va_start(va, format);
vfprintf(DumpFile, format, va);
va_end(va);
}
}
void IRO_DumpAddr(IROAddrRecord *rec) {
IROElmList *list;
if (IRO_Log && DumpFile) {
fprintf(DumpFile, "\n");
fprintf(DumpFile, "Address :\n");
IRO_DumpIntTree(rec->linear);
fprintf(DumpFile, "\n");
fprintf(DumpFile, "BaseTerms:\n");
for (list = rec->objRefs; list; list = list->next) {
IRO_DumpIntTree(list->element);
fprintf(DumpFile, "\n");
}
fprintf(DumpFile, "VarTerms:\n");
for (list = rec->misc; list; list = list->next) {
IRO_DumpIntTree(list->element);
fprintf(DumpFile, "\n");
}
fprintf(DumpFile, "ConstTerms:\n");
for (list = rec->ints; list; list = list->next) {
IRO_DumpIntTree(list->element);
fprintf(DumpFile, "\n");
}
}
}
static void IRO_DumpType(Type *type) {
char buf[256];
IRO_SpellType(type, buf);
fprintf(DumpFile, " (%s)", buf);
}
void IRO_SpellType(Type *type, char *buf) {
char mybuf[256];
char mybuf2[256];
switch (type->type) {
case TYPEVOID:
strcpy(buf, "void");
break;
case TYPEINT:
switch (TYPE_INTEGRAL(type)->integral) {
case IT_BOOL:
strcpy(buf, "bool");
break;
case IT_CHAR:
strcpy(buf, "char");
break;
case IT_WCHAR_T:
strcpy(buf, "wchar_t");
break;
case IT_SCHAR:
strcpy(buf, "signed char");
break;
case IT_UCHAR:
strcpy(buf, "unsigned char");
break;
case IT_SHORT:
strcpy(buf, "short");
break;
case IT_USHORT:
strcpy(buf, "unsigned short");
break;
case IT_INT:
strcpy(buf, "int");
break;
case IT_UINT:
strcpy(buf, "unsigned int");
break;
case IT_LONG:
strcpy(buf, "long");
break;
case IT_ULONG:
strcpy(buf, "unsigned long");
break;
case IT_LONGLONG:
strcpy(buf, "long long");
break;
case IT_ULONGLONG:
strcpy(buf, "unsigned long long");
break;
}
break;
case TYPEFLOAT:
switch (TYPE_INTEGRAL(type)->integral) {
case IT_FLOAT:
strcpy(buf, "float");
break;
case IT_SHORTDOUBLE:
strcpy(buf, "short double");
break;
case IT_DOUBLE:
strcpy(buf, "double");
break;
case IT_LONGDOUBLE:
strcpy(buf, "long double");
break;
}
break;
case TYPEENUM:
strcpy(buf, "enum ");
if (TYPE_ENUM(type)->enumname)
strcat(buf, TYPE_ENUM(type)->enumname->name);
break;
case TYPESTRUCT:
if (IS_TYPESTRUCT_VECTOR(TYPE_STRUCT(type))) {
switch (TYPE_STRUCT(type)->stype) {
case STRUCT_TYPE_4:
strcpy(buf, "vector unsigned char ");
break;
case STRUCT_TYPE_5:
strcpy(buf, "vector signed char ");
break;
case STRUCT_TYPE_6:
strcpy(buf, "vector bool char ");
break;
case STRUCT_TYPE_7:
strcpy(buf, "vector unsigned short ");
break;
case STRUCT_TYPE_8:
strcpy(buf, "vector signed short ");
break;
case STRUCT_TYPE_9:
strcpy(buf, "vector bool short ");
break;
case STRUCT_TYPE_A:
strcpy(buf, "vector unsigned long ");
break;
case STRUCT_TYPE_B:
strcpy(buf, "vector signed long ");
break;
case STRUCT_TYPE_C:
strcpy(buf, "vector bool long ");
break;
case STRUCT_TYPE_D:
strcpy(buf, "vector float ");
break;
case STRUCT_TYPE_E:
strcpy(buf, "vector pixel ");
break;
}
} else {
strcpy(buf, "struct ");
}
if (TYPE_STRUCT(type)->name)
strcat(buf, TYPE_STRUCT(type)->name->name);
break;
case TYPECLASS:
strcpy(buf, "class ");
if (TYPE_CLASS(type)->classname)
strcat(buf, TYPE_CLASS(type)->classname->name);
break;
case TYPEFUNC:
IRO_SpellType(TYPE_FUNC(type)->functype, mybuf);
strcpy(buf, "freturns(");
strcat(buf, mybuf);
strcat(buf, ")");
break;
case TYPEBITFIELD:
IRO_SpellType(TYPE_BITFIELD(type)->bitfieldtype, mybuf);
sprintf(buf, "bitfield(%s){%d:%d}", mybuf, TYPE_BITFIELD(type)->unkA, TYPE_BITFIELD(type)->unkB);
break;
case TYPELABEL:
strcpy(buf, "label");
break;
case TYPEPOINTER:
IRO_SpellType(TPTR_TARGET(type), mybuf);
strcpy(buf, "pointer(");
strcat(buf, mybuf);
strcat(buf, ")");
break;
case TYPEARRAY:
IRO_SpellType(TPTR_TARGET(type), mybuf);
strcpy(buf, "array(");
strcat(buf, mybuf);
strcat(buf, ")");
break;
case TYPEMEMBERPOINTER:
IRO_SpellType(TYPE_MEMBER_POINTER(type)->ty2, mybuf);
IRO_SpellType(TYPE_MEMBER_POINTER(type)->ty1, mybuf2);
strcpy(buf, "memberpointer(");
strcat(buf, mybuf);
strcat(buf, ",");
strcat(buf, mybuf2);
strcat(buf, ")");
break;
}
}