diff options
Diffstat (limited to 'compiler_and_linker/unsorted/IroLinearForm.c')
-rw-r--r-- | compiler_and_linker/unsorted/IroLinearForm.c | 1797 |
1 files changed, 0 insertions, 1797 deletions
diff --git a/compiler_and_linker/unsorted/IroLinearForm.c b/compiler_and_linker/unsorted/IroLinearForm.c deleted file mode 100644 index 4941587..0000000 --- a/compiler_and_linker/unsorted/IroLinearForm.c +++ /dev/null @@ -1,1797 +0,0 @@ -#include "compiler/IroLinearForm.h" -#include "compiler/IroDump.h" -#include "compiler/IroFlowgraph.h" -#include "compiler/IroUtil.h" -#include "compiler/IroVars.h" -#include "compiler/CError.h" -#include "compiler/CExpr.h" -#include "compiler/CFunc.h" -#include "compiler/CInt64.h" -#include "compiler/CParser.h" -#include "compiler/CompilerTools.h" -#include "compiler/InlineAsm.h" -#include "compiler/InlineAsmPPC.h" -#include "compiler/types.h" - -typedef struct NullCheckListNode { - SInt32 precompid; - Object *tempobj; - struct NullCheckListNode *next; -} NullCheckListNode; - -IROLinear *IRO_FirstLinear; -IROLinear *IRO_LastLinear; -UInt32 IRO_NumLinear; -Statement *CurStat; -static NullCheckListNode *NullCheckList; -static Statement *CurrStmt; -static Statement *PrevStmt; - -static void LinkLinear(IROLinear *linear) { - linear->index = IRO_NumLinear++; - if (IRO_FirstLinear) - IRO_LastLinear->next = linear; - else - IRO_FirstLinear = linear; - IRO_LastLinear = linear; -} - -IROLinear *IRO_NewLinear(IROLinearType type) { - IROLinear *linear = oalloc(sizeof(IROLinear)); - memset(linear, 0, sizeof(IROLinear)); - linear->stmt = CurStat; - linear->nodetype = EPOSTINC; - linear->next = NULL; - linear->type = type; - linear->rtype = NULL; - linear->flags = 0; - linear->nodeflags = 0; - linear->expr = NULL; - linear->x16 = 0; - return linear; -} - -static void MarkAssigned(IROLinear *linear, Boolean flag) { - IROLinear *inner; - IROAddrRecord *rec; - - if (IS_LINEAR_MONADIC(linear, EINDIRECT) && IS_LINEAR_MONADIC(linear->u.monadic, EBITFIELD)) { - linear->flags |= IROLF_Assigned; - inner = linear->u.monadic->u.monadic; - if (inner->type == IROLinearOperand) { - inner->flags |= IROLF_Assigned; - if (flag) { - linear->flags |= IROLF_Used; - inner->flags |= IROLF_Used; - } - } - - if (IS_LINEAR_DIADIC(inner, EADD)) { - if (IS_LINEAR_ENODE(inner->u.diadic.left, EOBJREF)) { - if (IS_LINEAR_ENODE(inner->u.diadic.right, EINTCONST)) - inner->u.diadic.left->flags |= IROLF_Assigned; - if (flag) { - linear->flags |= IROLF_Used; - inner->u.diadic.left->flags |= IROLF_Used; - } - } - - rec = IRO_InitAddrRecordPointer(inner); - IRO_DecomposeAddressExpression(inner, rec); - if (rec->numObjRefs == 1 && IS_LINEAR_ENODE(inner->u.diadic.left, EOBJREF)) { - ((IROLinear *) rec->objRefs->element)->flags |= IROLF_Assigned; - if (flag) { - linear->flags |= IROLF_Used; - ((IROLinear *) rec->objRefs->element)->flags |= IROLF_Used; - } - } - } - } - - if (IS_LINEAR_MONADIC(linear, EINDIRECT)) { - linear->flags |= IROLF_Assigned; - if (linear->u.monadic->type == IROLinearOperand) { - linear->u.monadic->flags |= IROLF_Assigned; - if (flag) { - linear->flags |= IROLF_Used; - linear->u.monadic->flags |= IROLF_Used; - } - } - } - - if (IS_LINEAR_MONADIC(linear, EINDIRECT)) { - linear->flags |= IROLF_Assigned; - inner = linear->u.monadic; - - if (IS_LINEAR_DIADIC(inner, EADD)) { - if (IS_LINEAR_ENODE(inner->u.diadic.left, EOBJREF)) { - if (IS_LINEAR_ENODE(inner->u.diadic.right, EINTCONST)) - inner->u.diadic.left->flags |= IROLF_Assigned; - if (flag) { - linear->flags |= IROLF_Used; - inner->u.diadic.left->flags |= IROLF_Used; - } - } - - rec = IRO_InitAddrRecordPointer(inner); - IRO_DecomposeAddressExpression(inner, rec); - if (rec->numObjRefs == 1 && IS_LINEAR_ENODE(inner->u.diadic.left, EOBJREF)) { - ((IROLinear *) rec->objRefs->element)->flags |= IROLF_Assigned; - if (flag) { - linear->flags |= IROLF_Used; - ((IROLinear *) rec->objRefs->element)->flags |= IROLF_Used; - } - } - } - } -} - -static void MarkSubscript(IROLinear *linear) { - linear->flags |= IROLF_Subs; - if (IS_LINEAR_DIADIC(linear, EADD)) { - if (IRO_IsAddressMultiply(linear->u.diadic.left) || IS_LINEAR_MONADIC(linear->u.diadic.left, EINDIRECT)) - linear->u.diadic.left->flags |= IROLF_Subs; - if (IRO_IsAddressMultiply(linear->u.diadic.right) || IS_LINEAR_MONADIC(linear->u.diadic.right, EINDIRECT)) - linear->u.diadic.right->flags |= IROLF_Subs; - - if (IS_LINEAR_DIADIC(linear->u.diadic.left, EADD)) - MarkSubscript(linear->u.diadic.left); - if (IS_LINEAR_DIADIC(linear->u.diadic.right, EADD)) - MarkSubscript(linear->u.diadic.right); - } -} - -static void MarkArgs(IROLinear *linear) { - int i; - linear->flags |= IROLF_4000; - - switch (linear->type) { - case IROLinearEnd: - break; - case IROLinearOp1Arg: - case IROLinearBeginCatch: - case IROLinearEndCatch: - case IROLinearEndCatchDtor: - MarkArgs(linear->u.monadic); - break; - case IROLinearOp2Arg: - MarkArgs(linear->u.diadic.left); - MarkArgs(linear->u.diadic.right); - break; - case IROLinearIf: - case IROLinearIfNot: - MarkArgs(linear->u.label.x4); - break; - case IROLinearReturn: - if (linear->u.monadic) - MarkArgs(linear->u.monadic); - break; - case IROLinearSwitch: - MarkArgs(linear->u.swtch.x4); - break; - case IROLinearOp3Arg: - MarkArgs(linear->u.args3.a); - MarkArgs(linear->u.args3.b); - MarkArgs(linear->u.args3.c); - break; - case IROLinearFunccall: - MarkArgs(linear->u.funccall.linear8); - for (i = 0; i < linear->u.funccall.argCount; i++) - MarkArgs(linear->u.funccall.args[i]); - break; - } -} - -// assumed name, position -CW_INLINE void MarkSubExpr(IROLinear *linear) { - int i; - - switch (linear->type) { - case IROLinearNop: - case IROLinearOperand: - case IROLinearGoto: - case IROLinearLabel: - case IROLinearEntry: - case IROLinearExit: - case IROLinearAsm: - case IROLinearEnd: - break; - case IROLinearOp1Arg: - case IROLinearBeginCatch: - case IROLinearEndCatch: - case IROLinearEndCatchDtor: - linear->u.monadic->flags |= IROLF_Reffed; - break; - case IROLinearOp2Arg: - linear->u.diadic.left->flags |= IROLF_Reffed; - linear->u.diadic.right->flags |= IROLF_Reffed; - break; - case IROLinearIf: - case IROLinearIfNot: - linear->u.label.x4->flags |= IROLF_Reffed; - break; - case IROLinearReturn: - if (linear->u.monadic) - linear->u.monadic->flags |= IROLF_Reffed; - break; - case IROLinearSwitch: - linear->u.swtch.x4->flags |= IROLF_Reffed; - break; - case IROLinearOp3Arg: - linear->u.args3.a->flags |= IROLF_Reffed; - linear->u.args3.b->flags |= IROLF_Reffed; - linear->u.args3.c->flags |= IROLF_Reffed; - break; - case IROLinearFunccall: - linear->u.funccall.linear8->flags |= IROLF_Reffed; - for (i = 0; i < linear->u.funccall.argCount; i++) - linear->u.funccall.args[i]->flags |= IROLF_Reffed; - break; - default: - CError_FATAL(368); - } -} - -static void MarkSubs1(IROLinear *linear) { - IROAddrRecord *rec; - - if (IS_LINEAR_MONADIC(linear, EBITFIELD)) { - linear = linear->u.monadic; - if (IS_LINEAR_ENODE(linear, EOBJREF)) - linear->flags |= IROLF_Ind; - } - - if (IS_LINEAR_DIADIC(linear, EADD)) { - if (IS_LINEAR_ENODE(linear->u.diadic.left, EOBJREF) && IS_LINEAR_ENODE(linear->u.diadic.right, EINTCONST)) - linear->u.diadic.left->flags |= IROLF_Ind; - - rec = IRO_InitAddrRecordPointer(linear); - IRO_DecomposeAddressExpression(linear, rec); - if (rec->numObjRefs == 1 && IS_LINEAR_ENODE(linear->u.diadic.left, EOBJREF)) - ((IROLinear *) rec->objRefs->element)->flags |= IROLF_Ind; - } -} - -static void MakeLeftChildAsAssignment(ENode *enode) { - Statement *stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_EXPRESSION; - stmt->expr = enode->data.diadic.left; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; -} - -static void AssignCommaRToTemp(ENode *enode, Boolean flag) { - Statement *stmt; - - if (!IS_TYPE_VOID(enode->rtype) && !flag) { - Object *obj = create_temp_object(enode->rtype); - ENode *indnode = IRO_NewENode(EINDIRECT); - indnode->data.monadic = create_objectrefnode(obj); - - if (!IS_TYPE_VOID(enode->rtype)) - indnode->rtype = enode->rtype; - else - CError_FATAL(548); - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_EXPRESSION; - stmt->expr = IRO_NewENode(EASS); - stmt->expr->data.diadic.left = indnode; - stmt->expr->data.diadic.right = enode->data.diadic.right; - stmt->expr->rtype = enode->rtype; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; - - enode->type = EINDIRECT; - enode->data.monadic = create_objectrefnode(obj); - CError_ASSERT(580, !IS_TYPE_VOID(enode->rtype)); - } else { - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_EXPRESSION; - stmt->expr = enode->data.diadic.right; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; - - enode->type = EINTCONST; - enode->data.intval = cint64_zero; - } -} - -static void AssignDangerousArgumentToTemp(ENode *enode) { - Statement *stmt; - Object *obj; - ENode *indnode; - ENode *rightnode; - - obj = create_temp_object(enode->rtype); - indnode = IRO_NewENode(EINDIRECT); - indnode->data.monadic = create_objectrefnode(obj); - - if (!IS_TYPE_VOID(enode->rtype)) - indnode->rtype = enode->rtype; - else - CError_FATAL(627); - - rightnode = IRO_NewENode(enode->type); - memcpy(rightnode, enode, sizeof(ENode)); - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_EXPRESSION; - stmt->expr = IRO_NewENode(EASS); - stmt->expr->data.diadic.left = indnode; - stmt->expr->data.diadic.right = rightnode; - stmt->expr->rtype = enode->rtype; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; - - enode->type = EINDIRECT; - enode->data.monadic = create_objectrefnode(obj); -} - -static void CreateTempAssignmentToZero(ENode *enode, Object **objptr) { - Statement *stmt; - ENode *indnode; - ENode *rightnode; - - *objptr = create_temp_object(enode->rtype); - indnode = IRO_NewENode(EINDIRECT); - indnode->data.monadic = create_objectrefnode(*objptr); - if (!IS_TYPE_VOID(enode->rtype)) - indnode->rtype = enode->rtype; - else - CError_FATAL(678); - - rightnode = IRO_NewENode(EINTCONST); - rightnode->data.intval = cint64_zero; - rightnode->rtype = enode->rtype; - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_EXPRESSION; - stmt->expr = IRO_NewENode(EASS); - stmt->expr->data.diadic.left = indnode; - stmt->expr->data.diadic.right = rightnode; - stmt->expr->rtype = enode->rtype; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; -} - -static void CreateTempAssignmentToOne(ENode *enode, Object **objptr) { - Statement *stmt; - ENode *indnode; - ENode *rightnode; - - *objptr = create_temp_object(enode->rtype); - indnode = IRO_NewENode(EINDIRECT); - indnode->data.monadic = create_objectrefnode(*objptr); - if (!IS_TYPE_VOID(enode->rtype)) - indnode->rtype = enode->rtype; - else - CError_FATAL(720); - - rightnode = IRO_NewENode(EINTCONST); - rightnode->data.intval = cint64_one; - rightnode->rtype = enode->rtype; - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_EXPRESSION; - stmt->expr = IRO_NewENode(EASS); - stmt->expr->data.diadic.left = indnode; - stmt->expr->data.diadic.right = rightnode; - stmt->expr->rtype = enode->rtype; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; -} - -static void GenerateCondExpression(ENode *enode, CLabel **label) { - Statement *stmt; - - *label = IRO_NewLabel(); - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_IFNGOTO; - stmt->expr = enode->data.cond.cond; - stmt->label = *label; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; -} - -static void GenerateGoToStmt(ENode *enode, CLabel **label) { - Statement *stmt; - - *label = IRO_NewLabel(); - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_GOTO; - stmt->label = *label; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; -} - -static void PutTempOnNullCheckList(ENode *expr, Object *obj) { - NullCheckListNode *n = lalloc(sizeof(NullCheckListNode)); - n->precompid = expr->data.nullcheck.precompid; - n->tempobj = obj; - n->next = NULL; - if (NullCheckList) { - n->next = NullCheckList; - NullCheckList = n; - } else { - NullCheckList = n; - } -} - -static Object *GetTempFromtheList(ENode *expr) { - NullCheckListNode *n; - - for (n = NullCheckList; n; n = n->next) { - if (n->precompid == expr->data.precompid) - break; - } - - CError_ASSERT(839, n); - return n->tempobj; -} - -static void GenerateNullcheckExprTempAssignment(ENode *enode, Object **objptr) { - Statement *stmt; - ENode *indnode; - - if (!IS_TYPE_VOID(enode->rtype)) - *objptr = create_temp_object(enode->rtype); - else - *objptr = create_temp_object(enode->data.nullcheck.nullcheckexpr->rtype); - - PutTempOnNullCheckList(enode, *objptr); - - indnode = IRO_NewENode(EINDIRECT); - indnode->data.monadic = create_objectrefnode(*objptr); - if (!IS_TYPE_VOID(enode->rtype)) - indnode->rtype = enode->rtype; - else - indnode->rtype = enode->data.nullcheck.nullcheckexpr->rtype; - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_EXPRESSION; - stmt->expr = IRO_NewENode(EASS); - stmt->expr->data.diadic.left = indnode; - stmt->expr->data.diadic.right = enode->data.nullcheck.nullcheckexpr; - if (!IS_TYPE_VOID(enode->rtype)) - stmt->expr->rtype = enode->rtype; - else - stmt->expr->rtype = enode->data.nullcheck.nullcheckexpr->rtype; - - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; -} - -static void GenerateExpr1TempAssignment(ENode *enode, Object **objptr) { - Statement *stmt; - ENode *indnode; - - if (!IS_TYPE_VOID(enode->rtype)) { - *objptr = create_temp_object(enode->rtype); - indnode = IRO_NewENode(EINDIRECT); - indnode->data.monadic = create_objectrefnode(*objptr); - indnode->rtype = enode->rtype; - CError_ASSERT(905, !IS_TYPE_VOID(enode->rtype)); - } - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_EXPRESSION; - if (!IS_TYPE_VOID(enode->rtype)) { - stmt->expr = IRO_NewENode(EASS); - stmt->expr->data.diadic.left = indnode; - stmt->expr->data.diadic.right = enode->data.cond.expr1; - stmt->expr->rtype = enode->rtype; - } else { - stmt->expr = enode->data.cond.expr1; - } - - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; -} - -static void GenerateExpr2TempAssignment(ENode *enode, Object **objptr) { - Statement *stmt; - ENode *indnode; - - if (!IS_TYPE_VOID(enode->rtype)) { - indnode = IRO_NewENode(EINDIRECT); - indnode->data.monadic = create_objectrefnode(*objptr); - indnode->rtype = enode->rtype; - CError_ASSERT(953, !IS_TYPE_VOID(enode->rtype)); - } - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_EXPRESSION; - if (!IS_TYPE_VOID(enode->rtype)) { - stmt->expr = IRO_NewENode(EASS); - stmt->expr->data.diadic.left = indnode; - stmt->expr->data.diadic.right = enode->data.cond.expr2; - stmt->expr->rtype = enode->rtype; - } else { - stmt->expr = enode->data.cond.expr2; - } - - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; -} - -static void GenerateForceLoadTempAssignment(ENode *enode, Object **objptr) { - Statement *stmt; - ENode *indnode; - - if (!IS_TYPE_VOID(enode->rtype)) { - *objptr = create_temp_object(enode->rtype); - indnode = IRO_NewENode(EINDIRECT); - indnode->data.monadic = create_objectrefnode(*objptr); - indnode->rtype = enode->rtype; - CError_ASSERT(1003, !IS_TYPE_VOID(enode->rtype)); - } - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_EXPRESSION; - if (!IS_TYPE_VOID(enode->rtype)) { - stmt->expr = IRO_NewENode(EASS); - stmt->expr->data.diadic.left = indnode; - stmt->expr->data.diadic.right = enode->data.monadic; - stmt->expr->rtype = enode->rtype; - } else { - stmt->expr = enode->data.monadic; - } - - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; -} - -static void GenerateLabel(CLabel **labelptr) { - Statement *stmt; - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_LABEL; - stmt->label = *labelptr; - stmt->label->stmt = stmt; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; -} - -static void GenerateIfNotTemp(ENode *enode, Object **objptr, CLabel **labelptr) { - Statement *stmt; - ENode *indnode; - - indnode = IRO_NewENode(EINDIRECT); - indnode->data.monadic = create_objectrefnode(*objptr); - if (!IS_TYPE_VOID(enode->rtype)) - indnode->rtype = enode->rtype; - else - indnode->rtype = enode->data.monadic->rtype; - - *labelptr = IRO_NewLabel(); - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_IFNGOTO; - stmt->expr = indnode; - stmt->label = *labelptr; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; -} - -static void GenerateNullcheckCondExpr(ENode *enode, Object **objptr) { - Statement *stmt; - ENode *indnode; - - indnode = IRO_NewENode(EINDIRECT); - indnode->data.monadic = create_objectrefnode(*objptr); - if (!IS_TYPE_VOID(enode->rtype)) - indnode->rtype = enode->rtype; - else - indnode->rtype = enode->data.nullcheck.nullcheckexpr->rtype; - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_EXPRESSION; - stmt->expr = IRO_NewENode(EASS); - stmt->expr->data.diadic.left = indnode; - stmt->expr->data.diadic.right = enode->data.nullcheck.condexpr; - if (!IS_TYPE_VOID(enode->rtype)) - stmt->expr->rtype = enode->rtype; - else - stmt->expr->rtype = enode->data.nullcheck.nullcheckexpr->rtype; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; -} - -static void TransformLogicalAndLHS(ENode *enode, Object **objptr, CLabel **labelptr) { - Statement *stmt; - - *labelptr = IRO_NewLabel(); - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_IFNGOTO; - stmt->expr = enode->data.diadic.left; - stmt->label = *labelptr; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; -} - -static void TransformLogicalAndRHS(ENode *enode, Object **objptr, CLabel **labelptr) { - Statement *stmt; - ENode *indnode; - ENode *rightnode; - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_IFNGOTO; - stmt->expr = enode->data.diadic.right; - stmt->label = *labelptr; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; - - indnode = IRO_NewENode(EINDIRECT); - indnode->data.monadic = create_objectrefnode(*objptr); - if (!IS_TYPE_VOID(enode->rtype)) - indnode->rtype = enode->rtype; - else - CError_FATAL(1225); - - rightnode = IRO_NewENode(EINTCONST); - rightnode->data.intval = cint64_one; - rightnode->rtype = enode->rtype; - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_EXPRESSION; - stmt->expr = IRO_NewENode(EASS); - stmt->expr->data.diadic.left = indnode; - stmt->expr->data.diadic.right = rightnode; - stmt->expr->rtype = enode->rtype; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_LABEL; - stmt->label = *labelptr; - stmt->label->stmt = stmt; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; - - enode->type = EINDIRECT; - enode->data.monadic = create_objectrefnode(*objptr); - CError_ASSERT(1276, !IS_TYPE_VOID(enode->rtype)); -} - -static void TransformLogicalOrLHS(ENode *enode, Object **objptr, CLabel **labelptr) { - Statement *stmt; - - *labelptr = IRO_NewLabel(); - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_IFGOTO; - stmt->expr = enode->data.diadic.left; - stmt->label = *labelptr; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; -} - -static void TransformLogicalOrRHS(ENode *enode, Object **objptr, CLabel **labelptr) { - Statement *stmt; - ENode *indnode; - ENode *rightnode; - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_IFGOTO; - stmt->expr = enode->data.diadic.right; - stmt->label = *labelptr; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; - - indnode = IRO_NewENode(EINDIRECT); - indnode->data.monadic = create_objectrefnode(*objptr); - if (!IS_TYPE_VOID(enode->rtype)) - indnode->rtype = enode->rtype; - else - CError_FATAL(1354); - - rightnode = IRO_NewENode(EINTCONST); - rightnode->data.intval = cint64_zero; - rightnode->rtype = enode->rtype; - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_EXPRESSION; - stmt->expr = IRO_NewENode(EASS); - stmt->expr->data.diadic.left = indnode; - stmt->expr->data.diadic.right = rightnode; - stmt->expr->rtype = enode->rtype; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; - - stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = ST_LABEL; - stmt->label = *labelptr; - stmt->label->stmt = stmt; - stmt->dobjstack = CurrStmt->dobjstack; - stmt->sourceoffset = CurrStmt->sourceoffset; - stmt->sourcefilepath = CurrStmt->sourcefilepath; - stmt->value = CurrStmt->value; - stmt->flags = CurrStmt->flags; - - if (PrevStmt) { - stmt->next = PrevStmt->next; - PrevStmt->next = stmt; - } else { - stmt->next = NULL; - } - PrevStmt = stmt; - - enode->type = EINDIRECT; - enode->data.monadic = create_objectrefnode(*objptr); - CError_ASSERT(1405, !IS_TYPE_VOID(enode->rtype)); -} - -static void LinearizeExpr1(ENode *a, ENode *b, Boolean flag, Boolean flag2) { - switch (a->type) { - ENODE_CASE_MONADIC: - LinearizeExpr1(a->data.monadic, a, 0, 0); - if (a->type == EFORCELOAD) { - Object *obj; - GenerateForceLoadTempAssignment(a, &obj); - a->type = EINDIRECT; - a->data.monadic = create_objectrefnode(obj); - CError_ASSERT(1428, !IS_TYPE_VOID(a->rtype)); - } - break; - ENODE_CASE_DIADIC_1: - case ECOMMA: - case EPMODULO: - case EROTL: - case EROTR: - case EBTST: - if (a->type == ECOMMA) { - LinearizeExpr1(a->data.diadic.left, a, 1, 0); - MakeLeftChildAsAssignment(a); - LinearizeExpr1(a->data.diadic.right, a, 0, 0); - AssignCommaRToTemp(a, flag); - } else if (a->data.diadic.right->cost >= a->data.diadic.left->cost) { - LinearizeExpr1(a->data.diadic.right, a, 0, 0); - LinearizeExpr1(a->data.diadic.left, a, 0, 0); - } else { - LinearizeExpr1(a->data.diadic.left, a, 0, 0); - LinearizeExpr1(a->data.diadic.right, a, 0, 0); - } - break; - ENODE_CASE_ASSIGN: - LinearizeExpr1(a->data.diadic.right, a, 0, 0); - LinearizeExpr1(a->data.diadic.left, a, 0, 0); - break; - case ELAND: - case ELOR: - if (a->type == ELAND) { - CLabel *label; - Object *obj; - CreateTempAssignmentToZero(a, &obj); - LinearizeExpr1(a->data.diadic.left, a, 0, 0); - TransformLogicalAndLHS(a, &obj, &label); - LinearizeExpr1(a->data.diadic.right, a, 0, 0); - TransformLogicalAndRHS(a, &obj, &label); - } else if (a->type == ELOR) { - CLabel *label; - Object *obj; - CreateTempAssignmentToOne(a, &obj); - LinearizeExpr1(a->data.diadic.left, a, 0, 0); - TransformLogicalOrLHS(a, &obj, &label); - LinearizeExpr1(a->data.diadic.right, a, 0, 0); - TransformLogicalOrRHS(a, &obj, &label); - } - break; - case ECOND: { - CLabel *label1, *label2; - Object *obj; - LinearizeExpr1(a->data.cond.cond, a, 0, 0); - GenerateCondExpression(a, &label1); - LinearizeExpr1(a->data.cond.expr1, a, 0, 0); - GenerateExpr1TempAssignment(a, &obj); - GenerateGoToStmt(a, &label2); - GenerateLabel(&label1); - LinearizeExpr1(a->data.cond.expr2, a, 0, 0); - GenerateExpr2TempAssignment(a, &obj); - GenerateLabel(&label2); - if (!IS_TYPE_VOID(a->rtype)) { - a->type = EINDIRECT; - a->data.monadic = create_objectrefnode(obj); - CError_ASSERT(1596, !IS_TYPE_VOID(a->rtype)); - } else { - a->type = EINTCONST; - a->data.intval = cint64_zero; - } - break; - } - case EPRECOMP: { - Object *temp = GetTempFromtheList(a); - a->type = EINDIRECT; - a->data.monadic = create_objectrefnode(temp); - CError_ASSERT(1614, !IS_TYPE_VOID(a->rtype)); - break; - } - case ENULLCHECK: { - CLabel *label; - Object *obj; - LinearizeExpr1(a->data.nullcheck.nullcheckexpr, a, 0, 0); - GenerateNullcheckExprTempAssignment(a, &obj); - GenerateIfNotTemp(a, &obj, &label); - LinearizeExpr1(a->data.nullcheck.condexpr, a, 0, 0); - GenerateNullcheckCondExpr(a, &obj); - GenerateLabel(&label); - if (!IS_TYPE_VOID(a->rtype)) { - a->type = EINDIRECT; - a->data.monadic = create_objectrefnode(obj); - CError_ASSERT(1639, !IS_TYPE_VOID(a->rtype)); - } else { - a->type = EINTCONST; - a->data.intval = cint64_zero; - } - break; - } - case EFUNCCALL: - case EFUNCCALLP: { - SInt32 count; - SInt32 i; - ENodeList *list; - ENode **arr; - SInt16 *arr2; - - IRO_IsLeafFunction = 0; - - list = a->data.funccall.args; - count = 0; - while (list) { - list = list->next; - count++; - } - - if (count) { - arr = oalloc(sizeof(ENode *) * count); - list = a->data.funccall.args; - count = 0; - while (list) { - arr[count] = list->node; - list = list->next; - count++; - } - - arr2 = oalloc(sizeof(SInt16) * count); - for (i = 0; i < count; i++) - arr2[i] = count - i - 1; - - for (i = 0; i < count; i++) - LinearizeExpr1(arr[arr2[i]], a, 0, 0); - } - - LinearizeExpr1(a->data.funccall.funcref, a, 0, 0); - break; - } - - case EINTCONST: - case EFLOATCONST: - case ESTRINGCONST: - case EOBJREF: - case ESETCONST: - case EVECTOR128CONST: - break; - - default: - CError_FATAL(1723); - } -} - -static IROLinear *LinearizeExpr(ENode *enode) { - IROLinear *linear = NULL; - - switch (enode->type) { - ENODE_CASE_MONADIC: - linear = IRO_NewLinear(IROLinearOp1Arg); - linear->u.monadic = LinearizeExpr(enode->data.monadic); - linear->nodetype = enode->type; - linear->rtype = enode->rtype; - linear->nodeflags = enode->flags; - if (IRO_IsAssignOp[linear->nodetype]) - MarkAssigned(linear->u.monadic, 1); - if (linear->nodetype == EINDIRECT) { - MarkSubs1(linear->u.monadic); - linear->u.monadic->flags |= IROLF_Immind | IROLF_Ind; - if (IS_LINEAR_DIADIC(linear->u.monadic, EADD)) - MarkSubscript(linear->u.monadic); - } - break; - ENODE_CASE_DIADIC_1: - case ECOMMA: - case EPMODULO: - case EROTL: - case EROTR: - case EBTST: - linear = IRO_NewLinear(IROLinearOp2Arg); - linear->nodeflags = enode->flags; - if (!ENODE_IS(enode, ECOMMA) && enode->data.diadic.right->cost >= enode->data.diadic.left->cost) { - linear->u.diadic.right = LinearizeExpr(enode->data.diadic.right); - linear->u.diadic.left = LinearizeExpr(enode->data.diadic.left); - linear->flags |= IROLF_8000; - } else { - linear->u.diadic.left = LinearizeExpr(enode->data.diadic.left); - linear->u.diadic.right = LinearizeExpr(enode->data.diadic.right); - } - linear->nodetype = enode->type; - linear->rtype = enode->rtype; - if (IRO_IsAssignOp[linear->nodetype]) - MarkAssigned(linear->u.diadic.left, IRO_IsModifyOp[linear->nodetype]); - break; - ENODE_CASE_ASSIGN: - linear = IRO_NewLinear(IROLinearOp2Arg); - linear->nodeflags = enode->flags; - linear->u.diadic.right = LinearizeExpr(enode->data.diadic.right); - linear->u.diadic.left = LinearizeExpr(enode->data.diadic.left); - linear->flags |= IROLF_8000; - linear->nodetype = enode->type; - linear->rtype = enode->rtype; - MarkAssigned(linear->u.diadic.left, IRO_IsModifyOp[linear->nodetype]); - break; - case EINTCONST: - case EFLOATCONST: - case ESTRINGCONST: - case EOBJREF: - case EVECTOR128CONST: - linear = IRO_NewLinear(IROLinearOperand); - linear->nodeflags = enode->flags; - linear->u.node = enode; - linear->rtype = enode->rtype; - break; - case EFUNCCALL: - case EFUNCCALLP: { - SInt32 count; - SInt32 i; - ENodeList *list; - ENode **arr; - SInt16 *arr2; - - linear = IRO_NewLinear(IROLinearFunccall); - linear->nodeflags = enode->flags; - linear->u.funccall.ispascal = enode->type == EFUNCCALLP; - - list = enode->data.funccall.args; - count = 0; - while (list) { - list = list->next; - count++; - } - - arr = NULL; - if (count) { - arr = oalloc(sizeof(ENode *) * count); - list = enode->data.funccall.args; - count = 0; - while (list) { - arr[count] = list->node; - list = list->next; - count++; - } - - arr2 = oalloc(sizeof(SInt16) * count); - for (i = 0; i < count; i++) - arr2[i] = count - i - 1; - - for (i = 0; i < count; i++) { - arr[arr2[i]] = (ENode *) LinearizeExpr(arr[arr2[i]]); - MarkArgs((IROLinear *) arr[arr2[i]]); - } - } - - linear->u.funccall.argCount = count; - linear->u.funccall.args = (IROLinear **) arr; - linear->u.funccall.linear8 = LinearizeExpr(enode->data.funccall.funcref); - linear->u.funccall.functype = enode->data.funccall.functype; - linear->rtype = enode->rtype; - break; - } - default: - CError_FATAL(1943); - } - - if (linear) - LinkLinear(linear); - return linear; -} - -void IRO_PreLinearize(Statement *stmt) { - IRO_FirstLinear = IRO_LastLinear = NULL; - IRO_NumLinear = 0; - CurrStmt = PrevStmt = NULL; - - while (stmt) { - CurStat = stmt; - CurrStmt = stmt; - NullCheckList = NULL; - - switch (stmt->type) { - case ST_NOP: - case ST_LABEL: - case ST_GOTO: - break; - case ST_OVF: - CError_FATAL(1989); - case ST_EXPRESSION: - LinearizeExpr1(stmt->expr, NULL, 0, 0); - break; - case ST_SWITCH: - LinearizeExpr1(stmt->expr, NULL, 0, 0); - break; - case ST_IFGOTO: - LinearizeExpr1(stmt->expr, NULL, 0, 0); - break; - case ST_IFNGOTO: - LinearizeExpr1(stmt->expr, NULL, 0, 0); - break; - case ST_RETURN: - if (stmt->expr) - LinearizeExpr1(stmt->expr, NULL, 0, 0); - break; - case ST_BEGINCATCH: - LinearizeExpr1(stmt->expr, NULL, 0, 0); - break; - case ST_ENDCATCH: - LinearizeExpr1(stmt->expr, NULL, 0, 0); - break; - case ST_ENDCATCHDTOR: - LinearizeExpr1(stmt->expr, NULL, 0, 0); - break; - - case ST_EXIT: - case ST_ENTRY: - case ST_ASM: - break; - - default: - CError_FATAL(2038); - } - - PrevStmt = stmt; - stmt = stmt->next; - } - - IRO_CheckForUserBreak(); -} - -static void MarkAllSubExprs(IROLinear *linear) { - IROLinear *scan; - int i; - - for (scan = linear; scan; scan = scan->next) - scan->flags &= ~IROLF_Reffed; - - for (scan = linear; scan; scan = scan->next) - MarkSubExpr(scan); -} - -void IRO_Linearize(Statement *stmt) { - IROLinear *linear; - - IRO_FirstLinear = IRO_LastLinear = NULL; - IRO_NumLinear = 0; - - while (stmt) { - CurStat = stmt; - linear = NULL; - - switch (stmt->type) { - case ST_NOP: - linear = IRO_NewLinear(IROLinearNop); - break; - case ST_LABEL: - linear = IRO_NewLinear(IROLinearLabel); - linear->u.label.label = stmt->label; - linear->flags |= IROLF_1; - break; - case ST_GOTO: - linear = IRO_NewLinear(IROLinearGoto); - linear->u.label.label = stmt->label; - break; - case ST_EXPRESSION: - LinearizeExpr(stmt->expr); - break; - case ST_SWITCH: - linear = IRO_NewLinear(IROLinearSwitch); - linear->u.swtch.x4 = LinearizeExpr(stmt->expr); - linear->u.swtch.info = (SwitchInfo *) stmt->label; - break; - case ST_IFGOTO: - linear = IRO_NewLinear(IROLinearIf); - linear->u.label.x4 = LinearizeExpr(stmt->expr); - linear->u.label.label = stmt->label; - break; - case ST_IFNGOTO: - linear = IRO_NewLinear(IROLinearIfNot); - linear->u.label.x4 = LinearizeExpr(stmt->expr); - linear->u.label.label = stmt->label; - break; - case ST_RETURN: - IRO_FunctionHasReturn = 1; - linear = IRO_NewLinear(IROLinearReturn); - if (stmt->expr) - linear->u.monadic = LinearizeExpr(stmt->expr); - else - linear->u.monadic = NULL; - break; - case ST_OVF: - CError_FATAL(2143); - break; - case ST_EXIT: - linear = IRO_NewLinear(IROLinearExit); - linear->u.label.label = stmt->label; - break; - case ST_ENTRY: - linear = IRO_NewLinear(IROLinearEntry); - linear->u.label.label = stmt->label; - linear->flags |= IROLF_1; - break; - case ST_BEGINCATCH: - linear = IRO_NewLinear(IROLinearBeginCatch); - linear->u.ctch.linear = LinearizeExpr(stmt->expr); - linear->u.ctch.x4 = 0; - linear->u.ctch.x8 = 0; - break; - case ST_ENDCATCH: - linear = IRO_NewLinear(IROLinearEndCatch); - linear->u.monadic = LinearizeExpr(stmt->expr); - break; - case ST_ENDCATCHDTOR: - linear = IRO_NewLinear(IROLinearEndCatchDtor); - linear->u.monadic = LinearizeExpr(stmt->expr); - break; - case ST_ASM: - linear = IRO_NewLinear(IROLinearAsm); - linear->u.asm_stmt = stmt; - if (copts.optimizewithasm) { - IAEffects effects; - CodeGen_GetAsmEffects(stmt, &effects); - if (effects.x0 || effects.x3) - DisableDueToAsm = 1; - } else { - DisableDueToAsm = 1; - } - break; - default: - CError_FATAL(2194); - } - - if (linear) - LinkLinear(linear); - stmt = stmt->next; - } - - linear = IRO_NewLinear(IROLinearEnd); - linear->flags |= IROLF_1; - LinkLinear(linear); - - MarkAllSubExprs(IRO_FirstLinear); - IRO_CheckForUserBreak(); -} - -static Statement *NewStatement(IROLinear *linear, StatementType sttype) { - Statement *stmt = lalloc(sizeof(Statement)); - memset(stmt, 0, sizeof(Statement)); - stmt->type = sttype; - stmt->value = 1; - if (linear->stmt) { - stmt->dobjstack = linear->stmt->dobjstack; - stmt->sourceoffset = linear->stmt->sourceoffset; - stmt->sourcefilepath = linear->stmt->sourcefilepath; - stmt->value = linear->stmt->value; - stmt->flags = linear->stmt->flags; - } else { - stmt->sourceoffset = -1; - stmt->sourcefilepath = NULL; - } - return stmt; -} - -ENode *IRO_NewENode(ENodeType nodetype) { - ENode *enode = lalloc(sizeof(ENode)); - memset(enode, 0, sizeof(ENode)); - enode->type = nodetype; - return enode; -} - -static ENode *BuildExpr(IROLinear *linear) { - ENode *enode; - - switch (linear->type) { - case IROLinearOperand: - enode = IRO_NewENode(linear->u.node->type); - enode->flags = linear->nodeflags; - *enode = *linear->u.node; - break; - case IROLinearOp1Arg: - enode = IRO_NewENode(linear->nodetype); - enode->flags = linear->nodeflags; - enode->data.monadic = BuildExpr(linear->u.monadic); - enode->rtype = linear->rtype; - enode->cost = enode->data.monadic->cost; - if (!enode->cost) - enode->cost = 1; - break; - case IROLinearOp2Arg: - enode = IRO_NewENode(linear->nodetype); - enode->flags = linear->nodeflags; - enode->data.diadic.left = BuildExpr(linear->u.diadic.left); - enode->data.diadic.right = BuildExpr(linear->u.diadic.right); - - enode->cost = enode->data.diadic.left->cost; - if (enode->data.diadic.right->cost > enode->cost) - enode->cost = enode->data.diadic.right->cost; - else if (enode->data.diadic.right->cost == enode->cost) - enode->cost += 1; - - if (ENODE_IS4(enode, ESHL, ESHR, EDIV, EMODULO)) - enode->cost += 2; - if (enode->cost > 200) - enode->cost = 200; - - enode->rtype = linear->rtype; - break; - case IROLinearOp3Arg: - enode = IRO_NewENode(linear->nodetype); - enode->flags = linear->nodeflags; - enode->data.cond.cond = BuildExpr(linear->u.args3.a); - enode->data.cond.expr1 = BuildExpr(linear->u.args3.b); - enode->data.cond.expr2 = BuildExpr(linear->u.args3.c); - enode->rtype = linear->rtype; - - enode->cost = enode->data.cond.cond->cost; - if (enode->data.cond.expr1->cost > enode->cost) - enode->cost = enode->data.cond.expr1->cost; - if (enode->data.cond.expr2->cost > enode->cost) - enode->cost = enode->data.cond.expr2->cost; - enode->cost += 1; - - if (enode->cost > 200) - enode->cost = 200; - - break; - - case IROLinearFunccall: { - int i; - enode = IRO_NewENode(linear->u.funccall.ispascal ? EFUNCCALLP : EFUNCCALL); - enode->flags = linear->nodeflags; - enode->data.funccall.funcref = BuildExpr(linear->u.funccall.linear8); - enode->data.funccall.functype = linear->u.funccall.functype; - enode->data.funccall.args = NULL; - enode->cost = 200; - for (i = linear->u.funccall.argCount - 1; i >= 0; i--) { - ENodeList *list = lalloc(sizeof(ENodeList)); - list->node = BuildExpr(linear->u.funccall.args[i]); - list->next = enode->data.funccall.args; - enode->data.funccall.args = list; - } - enode->rtype = linear->rtype; - break; - } - - default: - IRO_Dump("Oh, oh, bad expression type in BuildExpr at: %d\n", linear->index); - CError_FATAL(2390); - } - - enode->pointsTo = linear->pointsToFunction; - return enode; -} - -Statement *IRO_Delinearize(IRONode *node, IROLinear *linear) { - IROLinear *scanlin; - Statement *firstStmt; - Statement *lastStmt; - IRONode *scan; - Statement *stmt; - IRONode mynode; - - firstStmt = lastStmt = NULL; - - if (node) { - scan = node; - MarkAllSubExprs(IRO_FirstLinear); - } else { - memset(&mynode, 0, sizeof(IRONode)); - mynode.first = linear; - scan = &mynode; - MarkAllSubExprs(linear); - } - - while (scan) { - for (scanlin = scan->first; scanlin; scanlin = scanlin->next) { - stmt = NULL; - if (!(scanlin->flags & IROLF_Reffed)) { - switch (scanlin->type) { - case IROLinearNop: - if (scan == node) - stmt = NewStatement(scanlin, ST_NOP); - else - stmt = NULL; - break; - case IROLinearOperand: - case IROLinearOp1Arg: - case IROLinearOp2Arg: - case IROLinearOp3Arg: - case IROLinearFunccall: - stmt = NewStatement(scanlin, ST_EXPRESSION); - stmt->expr = BuildExpr(scanlin); - break; - case IROLinearGoto: - stmt = NewStatement(scanlin, ST_GOTO); - stmt->label = scanlin->u.label.label; - break; - case IROLinearExit: - stmt = NewStatement(scanlin, ST_EXIT); - stmt->label = scanlin->u.label.label; - break; - case IROLinearIf: - case IROLinearIfNot: - stmt = NewStatement(scanlin, (scanlin->type == IROLinearIf) ? ST_IFGOTO : ST_IFNGOTO); - stmt->label = scanlin->u.label.label; - stmt->expr = BuildExpr(scanlin->u.label.x4); - break; - case IROLinearReturn: - stmt = NewStatement(scanlin, ST_RETURN); - if (scanlin->u.monadic) - stmt->expr = BuildExpr(scanlin->u.monadic); - break; - case IROLinearLabel: - stmt = NewStatement(scanlin, ST_LABEL); - stmt->label = scanlin->u.label.label; - stmt->label->stmt = stmt; - break; - case IROLinearEntry: - stmt = NewStatement(scanlin, ST_ENTRY); - stmt->label = scanlin->u.label.label; - stmt->label->stmt = stmt; - break; - case IROLinearSwitch: - stmt = NewStatement(scanlin, ST_SWITCH); - stmt->expr = BuildExpr(scanlin->u.swtch.x4); - stmt->label = (CLabel *) scanlin->u.swtch.info; - break; - case IROLinearBeginCatch: - stmt = NewStatement(scanlin, ST_BEGINCATCH); - stmt->expr = BuildExpr(scanlin->u.ctch.linear); - break; - case IROLinearEndCatch: - stmt = NewStatement(scanlin, ST_ENDCATCH); - stmt->expr = BuildExpr(scanlin->u.monadic); - break; - case IROLinearEndCatchDtor: - stmt = NewStatement(scanlin, ST_ENDCATCHDTOR); - stmt->expr = BuildExpr(scanlin->u.monadic); - break; - case IROLinearAsm: - stmt = scanlin->u.asm_stmt; - break; - case IROLinearEnd: - stmt = NULL; - break; - default: - CError_FATAL(2685); - } - - if (stmt) { - if (LoopOptimizerRun) { - SInt32 i; - SInt32 value = 1; - for (i = 0; i < scan->loopdepth; i++) { - value = (value < 4096) ? (value * 8) : (value + 1); - } - stmt->value = value; - } - if (firstStmt) - lastStmt->next = stmt; - else - firstStmt = stmt; - lastStmt = stmt; - } - } - if (scanlin == scan->last) - break; - } - scan = scan->nextnode; - } - - return firstStmt; -} - -void IRO_RenumberInts(void) { - IROLinear *linear = IRO_FirstLinear; - IRO_NumLinear = 0; - while (linear) { - linear->index = IRO_NumLinear++; - linear = linear->next; - } -} - -static void TravExprToUpdateFlags(IROLinear *linear) { - int i; - - linear->flags &= ~(IROLF_Assigned | IROLF_8 | IROLF_Used | IROLF_Ind | IROLF_Subs | IROLF_LoopInvariant | IROLF_Ris | IROLF_Immind | IROLF_CouldError); - switch (linear->type) { - case IROLinearNop: - case IROLinearOperand: - break; - case IROLinearOp1Arg: - TravExprToUpdateFlags(linear->u.monadic); - if (IRO_IsAssignOp[linear->nodetype]) - MarkAssigned(linear->u.monadic, 1); - if (linear->nodetype == EINDIRECT) { - MarkSubs1(linear->u.monadic); - linear->u.monadic->flags |= IROLF_Immind | IROLF_Ind; - if (IS_LINEAR_DIADIC(linear->u.monadic, EADD)) - MarkSubscript(linear->u.monadic); - } - break; - case IROLinearOp2Arg: - TravExprToUpdateFlags(linear->u.diadic.left); - TravExprToUpdateFlags(linear->u.diadic.right); - if (IRO_IsAssignOp[linear->nodetype]) - MarkAssigned(linear->u.diadic.left, IRO_IsModifyOp[linear->nodetype]); - break; - case IROLinearOp3Arg: - TravExprToUpdateFlags(linear->u.args3.a); - TravExprToUpdateFlags(linear->u.args3.b); - TravExprToUpdateFlags(linear->u.args3.c); - break; - case IROLinearFunccall: - TravExprToUpdateFlags(linear->u.funccall.linear8); - for (i = linear->u.funccall.argCount - 1; i >= 0; i--) - TravExprToUpdateFlags(linear->u.funccall.args[i]); - break; - default: - IRO_Dump("Oh, oh, bad expression type in TravExprToUpdateFlags at: %d\n", linear->index); - CError_FATAL(2853); - } -} - -void IRO_UpdateFlagsOnInts(void) { - IROLinear *linear; - IRONode *node; - - MarkAllSubExprs(IRO_FirstLinear); - - for (node = IRO_FirstNode; node; node = node->nextnode) { - for (linear = node->first; linear; linear = linear->next) { - if (!(linear->flags & IROLF_Reffed)) { - switch (linear->type) { - case IROLinearOperand: - case IROLinearOp1Arg: - case IROLinearOp2Arg: - case IROLinearOp3Arg: - case IROLinearFunccall: - TravExprToUpdateFlags(linear); - break; - case IROLinearIf: - case IROLinearIfNot: - TravExprToUpdateFlags(linear->u.label.x4); - break; - case IROLinearReturn: - if (linear->u.monadic) - TravExprToUpdateFlags(linear->u.monadic); - break; - case IROLinearSwitch: - TravExprToUpdateFlags(linear->u.swtch.x4); - break; - case IROLinearBeginCatch: - TravExprToUpdateFlags(linear->u.ctch.linear); - break; - case IROLinearEndCatch: - TravExprToUpdateFlags(linear->u.monadic); - break; - case IROLinearEndCatchDtor: - TravExprToUpdateFlags(linear->u.monadic); - break; - case IROLinearNop: - case IROLinearGoto: - case IROLinearLabel: - case IROLinearEntry: - case IROLinearExit: - case IROLinearAsm: - case IROLinearEnd: - break; - default: - CError_FATAL(2931); - } - } - if (linear == node->last) - break; - } - } -} - -void IRO_SaveLinearIR(IROLinearIRSave *save) { - save->firstLinear = IRO_FirstLinear; - save->lastLinear = IRO_LastLinear; - save->numLinear = IRO_NumLinear; - save->curStat = CurStat; - save->disableDueToAsm = DisableDueToAsm; - save->isLeafFunction = IRO_IsLeafFunction; - save->functionHasReturn = IRO_FunctionHasReturn; - save->nullCheckList = NullCheckList; - save->currStmt = CurrStmt; - save->prevStmt = PrevStmt; -} - -void IRO_RestoreLinearIR(IROLinearIRSave *save) { - IRO_FirstLinear = save->firstLinear; - IRO_LastLinear = save->lastLinear; - IRO_NumLinear = save->numLinear; - CurStat = save->curStat; - DisableDueToAsm = save->disableDueToAsm; - IRO_IsLeafFunction = save->isLeafFunction; - IRO_FunctionHasReturn = save->functionHasReturn; - NullCheckList = save->nullCheckList; - CurrStmt = save->currStmt; - PrevStmt = save->prevStmt; -} - |