diff options
Diffstat (limited to 'compiler_and_linker/unsorted/IroUtil.c')
-rw-r--r-- | compiler_and_linker/unsorted/IroUtil.c | 1262 |
1 files changed, 0 insertions, 1262 deletions
diff --git a/compiler_and_linker/unsorted/IroUtil.c b/compiler_and_linker/unsorted/IroUtil.c deleted file mode 100644 index 4ade9b1..0000000 --- a/compiler_and_linker/unsorted/IroUtil.c +++ /dev/null @@ -1,1262 +0,0 @@ -#include "compiler/IroUtil.h" -#include "compiler/IroCSE.h" -#include "compiler/IroDump.h" -#include "compiler/IroFlowgraph.h" -#include "compiler/IroLinearForm.h" -#include "compiler/IroLoop.h" -#include "compiler/IroVars.h" -#include "compiler/InlineAsmPPC.h" -#include "compiler/CompilerTools.h" -#include "compiler/CCompiler.h" -#include "compiler/CError.h" -#include "compiler/CException.h" -#include "compiler/CExpr.h" -#include "compiler/CFunc.h" -#include "compiler/CInt64.h" -#include "compiler/CMachine.h" -#include "compiler/CParser.h" -#include "compiler/Exceptions.h" -#include "compiler/objects.h" -#include "compiler/types.h" -#include "cos.h" - -static UInt32 IRO_LastUserBreakTick; -static IROLinear *ExprStart; -static IROLinear *ExprEnd; -static IRONode *IRO_Node; -static SInt32 FuncLevel; -Object *FunctionName; -Boolean IRO_IsLeafFunction; -Boolean IRO_FunctionHasReturn; -Boolean DisableDueToAsm; -Boolean LoopOptimizerRun; - -Object *IRO_IsVariable(IROLinear *linear) { - if (linear->type == IROLinearOp1Arg && - linear->nodetype == EINDIRECT && - linear->u.monadic->type == IROLinearOperand && - linear->u.monadic->u.node->type == EOBJREF) - return linear->u.monadic->u.node->data.objref; - - return NULL; -} - -Boolean IRO_IsConstant(IROLinear *linear) { - if (linear->type == IROLinearOperand && ENODE_IS3(linear->u.node, EINTCONST, EVECTOR128CONST, EFLOATCONST)) - return 1; - return 0; -} - -Boolean IRO_IsPow2(IROLinear *linear, SInt32 *powvalue) { - UInt32 desired; - UInt32 value; - SInt32 i; - - *powvalue = -1; - if (linear->type == IROLinearOperand && linear->u.node->type == EINTCONST) { - if (CTool_EndianReadWord32(&linear->u.node->data.intval.hi)) - return 0; - - desired = CInt64_GetULong(&linear->u.node->data.intval); - value = 1; - for (i = 0; i < 31; i++) { - if (value == desired) { - *powvalue = i; - return 1; - } - value += value; - } - } - - return 0; -} - -Boolean IRO_IsIntConstant(IROLinear *linear) { - if (linear->type == IROLinearOperand && ENODE_IS(linear->u.node, EINTCONST)) - return 1; - return 0; -} - -Boolean IRO_IsFloatConstant(IROLinear *linear) { - if (linear->type == IROLinearOperand && ENODE_IS(linear->u.node, EFLOATCONST)) - return 1; - return 0; -} - -Boolean IRO_IsVector128Constant(IROLinear *linear) { - if (linear->type == IROLinearOperand && ENODE_IS(linear->u.node, EVECTOR128CONST)) - return 1; - return 0; -} - -Boolean IRO_IsAssignment(IROLinear *linear) { - if (linear->type == IROLinearOp1Arg || linear->type == IROLinearOp2Arg) { - if (IRO_IsAssignOp[linear->nodetype]) - return 1; - } - return 0; -} - -static Boolean IRO_OperandsSame(ENode *a, ENode *b) { - if (a->type == b->type) { - switch (a->type) { - case EINTCONST: - return CInt64_Equal(a->data.intval, b->data.intval); - case ESTRINGCONST: - return 0; - case EFLOATCONST: - return a->data.floatval.value == b->data.floatval.value; - case EVECTOR128CONST: - return (a->data.vector128val.ul[0] == b->data.vector128val.ul[0]) && - (a->data.vector128val.ul[1] == b->data.vector128val.ul[1]) && - (a->data.vector128val.ul[2] == b->data.vector128val.ul[2]) && - (a->data.vector128val.ul[3] == b->data.vector128val.ul[3]); - case EOBJREF: - return a->data.objref == b->data.objref; - } - } - - return 0; -} - -Boolean IRO_TypesEqual(Type *a, Type *b) { - if (IS_TYPE_BITFIELD(a)) { - if (IS_TYPE_BITFIELD(b)) { - if ( - (TYPE_BITFIELD(a)->bitfieldtype == TYPE_BITFIELD(b)->bitfieldtype) && - (TYPE_BITFIELD(a)->offset == TYPE_BITFIELD(b)->offset) && - (TYPE_BITFIELD(a)->bitlength == TYPE_BITFIELD(b)->bitlength)) - return 1; - } - return 0; - } - - if (IS_TYPE_POINTER_ONLY(a) && IS_TYPE_POINTER_ONLY(b)) - return 1; - - return is_typeequal(a, b) != 0; -} - -Type *IRO_UnsignedType(Type *type) { - if (IS_TYPE_ENUM(type) || IS_TYPE_POINTER_ONLY(type)) { - if (type->size == stunsignedchar.size) - return TYPE(&stunsignedchar); - if (type->size == stunsignedint.size) - return TYPE(&stunsignedint); - if (type->size == stunsignedshort.size) - return TYPE(&stunsignedshort); - if (type->size == stunsignedlong.size) - return TYPE(&stunsignedlong); - if (type->size == stunsignedlonglong.size) - return TYPE(&stunsignedlonglong); - CError_FATAL(281); - return NULL; - } - - if (!IS_TYPE_INT(type)) { - CError_FATAL(287); - return NULL; - } - - if (type == TYPE(&stbool) || type == TYPE(&stwchar)) - return type; - - if (type == TYPE(&stchar) || type == TYPE(&stsignedchar) || type == TYPE(&stunsignedchar)) - return TYPE(&stunsignedchar); - if (type == TYPE(&stsignedshort) || type == TYPE(&stunsignedshort)) - return TYPE(&stunsignedshort); - if (type == TYPE(&stsignedint) || type == TYPE(&stunsignedint)) - return TYPE(&stunsignedint); - if (type == TYPE(&stsignedlong) || type == TYPE(&stunsignedlong)) - return TYPE(&stunsignedlong); - if (type == TYPE(&stsignedlonglong) || type == TYPE(&stunsignedlonglong)) - return TYPE(&stunsignedlonglong); - - CError_FATAL(319); - return NULL; -} - -Type *IRO_SignedType(Type *type) { - if (IS_TYPE_ENUM(type) || IS_TYPE_POINTER_ONLY(type)) { - if (type->size == stsignedchar.size) - return TYPE(&stsignedchar); - if (type->size == stsignedint.size) - return TYPE(&stsignedint); - if (type->size == stsignedshort.size) - return TYPE(&stsignedshort); - if (type->size == stsignedlong.size) - return TYPE(&stsignedlong); - if (type->size == stsignedlonglong.size) - return TYPE(&stsignedlonglong); - CError_FATAL(357); - return NULL; - } - - if (!IS_TYPE_INT(type)) { - CError_FATAL(363); - return NULL; - } - - if (type == TYPE(&stbool) && type->size == stsignedchar.size) - return TYPE(&stsignedchar); - - if (type == TYPE(&stwchar) && type->size == stsignedshort.size) - return TYPE(&stsignedshort); - - if (type == TYPE(&stchar) || type == TYPE(&stsignedchar) || type == TYPE(&stunsignedchar)) - return TYPE(&stsignedchar); - if (type == TYPE(&stsignedshort) || type == TYPE(&stunsignedshort)) - return TYPE(&stsignedshort); - if (type == TYPE(&stsignedint) || type == TYPE(&stunsignedint)) - return TYPE(&stsignedint); - if (type == TYPE(&stsignedlong) || type == TYPE(&stunsignedlong)) - return TYPE(&stsignedlong); - if (type == TYPE(&stsignedlonglong) || type == TYPE(&stunsignedlonglong)) - return TYPE(&stsignedlonglong); - - CError_FATAL(399); - return NULL; -} - -Boolean IRO_is_CPtypeequal(Type *a, Type *b) { - if (IS_TYPE_POINTER_ONLY(a) && IS_TYPE_POINTER_ONLY(b)) - return 1; - - return is_typeequal(a, b) != 0; -} - -Boolean IRO_ExprsSame(IROLinear *a, IROLinear *b) { - if (a->type == b->type && IRO_TypesEqual(a->rtype, b->rtype)) { - switch (a->type) { - case IROLinearOperand: - return IRO_OperandsSame(a->u.node, b->u.node); - case IROLinearOp1Arg: - if (a->nodetype == b->nodetype) - return IRO_ExprsSame(a->u.monadic, b->u.monadic); - return 0; - case IROLinearOp2Arg: - if (a->nodetype == b->nodetype) - return IRO_ExprsSame(a->u.diadic.left, b->u.diadic.left) && - IRO_ExprsSame(a->u.diadic.right, b->u.diadic.right); - return 0; - case IROLinearOp3Arg: - if (a->nodetype == b->nodetype) - return IRO_ExprsSame(a->u.args3.a, b->u.args3.a) && - IRO_ExprsSame(a->u.args3.b, b->u.args3.b) && - IRO_ExprsSame(a->u.args3.c, b->u.args3.c); - return 0; - case IROLinearFunccall: - return 0; - default: - return 0; - } - } - - return 0; -} - -CLabel *IRO_NewLabel(void) { - CLabel *label = newlabel(); - label->next = Labels; - Labels = label; - return label; -} - -Boolean IRO_ExprsSameSemantically(IROLinear *a, IROLinear *b) { - if (a->type == b->type && IRO_TypesEqual(a->rtype, b->rtype)) { - Boolean flag = 0; - - switch (a->type) { - case IROLinearOperand: - return IRO_OperandsSame(a->u.node, b->u.node); - case IROLinearOp1Arg: - if (a->nodetype == b->nodetype) - return IRO_ExprsSameSemantically(a->u.monadic, b->u.monadic); - return 0; - case IROLinearOp2Arg: - if (a->nodetype == b->nodetype) { - switch (a->nodetype) { - case EMUL: - case EADD: - case EAND: - case EXOR: - case EOR: - case ELAND: - case ELOR: - if (!IRO_HasSideEffect(a)) { - flag = IRO_ExprsSameSemantically(a->u.diadic.left, b->u.diadic.right) && - IRO_ExprsSameSemantically(a->u.diadic.right, b->u.diadic.left); - } - } - - return flag || (IRO_ExprsSameSemantically(a->u.diadic.left, b->u.diadic.left) && - IRO_ExprsSameSemantically(a->u.diadic.right, b->u.diadic.right)); - } - return 0; - case IROLinearOp3Arg: - if (a->nodetype == b->nodetype) - return IRO_ExprsSameSemantically(a->u.args3.a, b->u.args3.a) && - IRO_ExprsSameSemantically(a->u.args3.b, b->u.args3.b) && - IRO_ExprsSameSemantically(a->u.args3.c, b->u.args3.c); - return 0; - case IROLinearFunccall: - return 0; - default: - return 0; - } - } - - return 0; -} - -IROLinear *IRO_FindPrecedAfter(IROLinear *a, IROLinear *iter) { - IROLinear *prev = iter; - while (iter && iter != a) { - prev = iter; - iter = iter->next; - } - - if (iter) - return prev; - return iter; -} - -IROLinear *IRO_FindPreced(IROLinear *a) { - IROLinear *iter; - IROLinear *prev; - - prev = iter = IRO_FirstLinear; - while (iter && iter != a) { - prev = iter; - iter = iter->next; - } - - if (iter) - return prev; - return iter; -} - -IROLinear *IRO_FindFirst(IROLinear *linear) { - short i; - - switch (linear->type) { - case IROLinearOperand: - return linear; - case IROLinearOp1Arg: - return IRO_FindFirst(linear->u.monadic); - case IROLinearOp2Arg: - if (linear->u.diadic.right->index < linear->u.diadic.left->index) - return IRO_FindFirst(linear->u.diadic.right); - else - return IRO_FindFirst(linear->u.diadic.left); - case IROLinearOp3Arg: - if (linear->u.args3.a->index < linear->u.args3.b->index) { - if (linear->u.args3.b->index < linear->u.args3.c->index) - return IRO_FindFirst(linear->u.args3.a); - else - return IRO_FindFirst(linear->u.args3.c); - } else { - if (linear->u.args3.b->index < linear->u.args3.c->index) - return IRO_FindFirst(linear->u.args3.b); - else - return IRO_FindFirst(linear->u.args3.c); - } - case IROLinearFunccall: - i = linear->u.funccall.argCount - 1; - return IRO_FindFirst(linear->u.funccall.args[i]); - default: - CError_FATAL(641); - return NULL; - } -} - -void IRO_CutAndPasteAfter(IROLinear *a, IROLinear *b, IROLinear *c) { - IROLinear *preced = IRO_FindPreced(a); - preced->next = b->next; - b->next = c->next; - c->next = a; -} - -Boolean IRO_IsConstantZero(IROLinear *linear) { - return (IRO_IsIntConstant(linear) && CInt64_IsZero(&linear->u.node->data.intval)) || - (IRO_IsFloatConstant(linear) && CMach_FloatIsZero(linear->u.node->data.floatval)); -} - -Boolean IRO_IsConstantOne(IROLinear *linear) { - return (IRO_IsIntConstant(linear) && CInt64_IsOne(&linear->u.node->data.intval)) || - (IRO_IsFloatConstant(linear) && CMach_FloatIsOne(linear->u.node->data.floatval)); -} - -Boolean IRO_IsConstantNegativeOne(IROLinear *linear) { - CInt64 neg = CInt64_Neg(linear->u.node->data.intval); - return (IRO_IsIntConstant(linear) && CInt64_IsOne(&neg)) || - (IRO_IsFloatConstant(linear) && CMach_FloatIsNegOne(linear->u.node->data.floatval)); -} - -static void ActNop(IROLinear *linear, Boolean isEntry) { - if (!isEntry) { - linear->type = IROLinearNop; - linear->expr = NULL; - } -} - -void IRO_NopOut(IROLinear *linear) { - IRO_WalkTree(linear, ActNop); -} - -static Boolean NotNoppable(IROLinear *linear) { - return ( - (linear->type == IROLinearFunccall) || - IRO_IsAssignment(linear) || - ((linear->type == IROLinearOperand) && ENODE_IS(linear->u.node, EINSTRUCTION)) || - (linear->rtype && CParser_IsVolatile(linear->rtype, linear->nodeflags & ENODE_FLAG_QUALS)) || - ((linear->type == IROLinearOperand) && ENODE_IS(linear->u.node, EOBJREF) && is_volatile_object(linear->u.node->data.objref)) - ); -} - -static void ActNopNonSideEffects(IROLinear *linear, Boolean isEntry) { - if (isEntry) { - if (NotNoppable(linear)) { - if (!FuncLevel) - linear->flags &= ~IROLF_Reffed; - FuncLevel++; - } - } else { - if (NotNoppable(linear)) { - FuncLevel--; - } else if (!FuncLevel) { - linear->type = IROLinearNop; - } - } -} - -void IRO_NopNonSideEffects(IROLinear *linear, SInt32 level) { - FuncLevel = level; - IRO_WalkTree(linear, ActNopNonSideEffects); -} - -void IRO_BuildList(IROLinear *linear, Boolean isEntry) { - if (!isEntry) { - linear->next = NULL; - IRO_AddToList(linear, &IRO_InitLList); - } -} - -void IRO_WalkTree(IROLinear *linear, IROWalkTreeFunc func) { - int i; - - func(linear, 1); - switch (linear->type) { - case IROLinearOperand: - break; - case IROLinearOp1Arg: - IRO_WalkTree(linear->u.monadic, func); - break; - case IROLinearOp2Arg: - IRO_WalkTree(linear->u.diadic.left, func); - IRO_WalkTree(linear->u.diadic.right, func); - break; - case IROLinearOp3Arg: - IRO_WalkTree(linear->u.args3.a, func); - IRO_WalkTree(linear->u.args3.b, func); - IRO_WalkTree(linear->u.args3.c, func); - break; - case IROLinearFunccall: - IRO_WalkTree(linear->u.funccall.linear8, func); - for (i = 0; i < linear->u.funccall.argCount; i++) - IRO_WalkTree(linear->u.funccall.args[i], func); - break; - } - func(linear, 0); -} - -void IRO_WalkTreeToPropagateFlags(IROLinear *linear, IROWalkTreeFunc func) { - int i; - - switch (linear->type) { - case IROLinearOperand: - break; - case IROLinearOp1Arg: - IRO_WalkTreeToPropagateFlags(linear->u.monadic, func); - break; - case IROLinearOp2Arg: - IRO_WalkTreeToPropagateFlags(linear->u.diadic.left, func); - IRO_WalkTreeToPropagateFlags(linear->u.diadic.right, func); - break; - case IROLinearOp3Arg: - IRO_WalkTreeToPropagateFlags(linear->u.args3.a, func); - IRO_WalkTreeToPropagateFlags(linear->u.args3.b, func); - IRO_WalkTreeToPropagateFlags(linear->u.args3.c, func); - break; - case IROLinearFunccall: - IRO_WalkTreeToPropagateFlags(linear->u.funccall.linear8, func); - for (i = 0; i < linear->u.funccall.argCount; i++) - IRO_WalkTreeToPropagateFlags(linear->u.funccall.args[i], func); - break; - } - func(linear, 0); -} - -void IRO_WalkInts(IROLinear *a, IROLinear *b, IROWalkTreeFunc func) { - IROLinear *scan; - - for (scan = a; scan; scan = scan->next) { - switch (scan->type) { - case IROLinearBeginCatch: - case IROLinearEndCatch: - case IROLinearEndCatchDtor: - IRO_WalkTree(scan->u.ctch.linear, func); - break; - case IROLinearOperand: - case IROLinearOp1Arg: - case IROLinearOp2Arg: - case IROLinearOp3Arg: - case IROLinearFunccall: - IRO_WalkTree(scan, func); - break; - case IROLinearIf: - case IROLinearIfNot: - IRO_WalkTree(scan->u.label.x4, func); - break; - case IROLinearReturn: - if (scan->u.monadic) - IRO_WalkTree(scan->u.monadic, func); - break; - case IROLinearSwitch: - IRO_WalkTree(scan->u.swtch.x4, func); - break; - case IROLinearAsm: - func(scan, 1); - func(scan, 0); - break; - case IROLinearEnd: - break; - } - - if (scan == b) - break; - } -} - -void IRO_Cut(IROLinear *a, IROLinear *b) { - IROLinear *scan; - IROLinear *prev; - IRONode *node; - - scan = a; - while (1) { - scan->stmt = NULL; - if (scan == b) - break; - scan = scan->next; - } - - prev = NULL; - for (scan = IRO_FirstLinear; scan && scan != a; scan = scan->next) - prev = scan; - - CError_ASSERT(951, scan); - - for (node = IRO_FirstNode; node; node = node->nextnode) { - if (node->first == a) { - if (node->last == b) { - node->first = node->last = NULL; - break; - } else { - node->first = b->next; - break; - } - } else if (node->last == b) { - node->last = prev; - break; - } - } - - if (prev) - prev->next = b->next; - else - IRO_FirstLinear = b->next; -} - -void IRO_Paste(IROLinear *a, IROLinear *b, IROLinear *c) { - IROLinear *prev; - IROLinear *scan; - IRONode *node; - - CError_ASSERT(1002, c && c->type != IROLinearLabel); - - prev = NULL; - for (scan = IRO_FirstLinear; scan && scan != c; scan = scan->next) - prev = scan; - - CError_ASSERT(1016, scan); - - for (node = IRO_FirstNode; node; node = node->nextnode) { - if (node->first == c) { - node->first = a; - break; - } - } - - b->next = c; - if (prev) - prev->next = a; - else - IRO_FirstLinear = a; -} - -void IRO_PasteAfter(IROLinear *a, IROLinear *b, IROLinear *c) { - IRONode *node; - - switch (c->type) { - case IROLinearGoto: - case IROLinearIf: - case IROLinearIfNot: - case IROLinearSwitch: - CError_FATAL(1060); - } - - for (node = IRO_FirstNode; node; node = node->nextnode) { - if (node->last == c) { - node->last = b; - break; - } - } - - b->next = c->next; - c->next = a; -} - -static void FindStart(IROLinear *linear, Boolean isEntry) { - IROLinear *scan; - if (isEntry) { - scan = linear; - do { - if (scan == ExprStart) { - ExprStart = linear; - return; - } - if (scan == ExprEnd) - return; - } while ((scan = scan->next)); - } -} - -void IRO_ClipExpr(IROExpr *expr) { - ExprStart = ExprEnd = expr->linear; - IRO_WalkTree(expr->linear, FindStart); - IRO_Cut(ExprStart, ExprEnd); -} - -void IRO_ClipExprTree(IROLinear *linear) { - ExprStart = ExprEnd = linear; - IRO_WalkTree(linear, FindStart); - IRO_Cut(ExprStart, ExprEnd); -} - -static void SetNodeNumInExprList(IROLinear *linear, Boolean isEntry) { - if (isEntry && linear->expr) - linear->expr->node = IRO_Node; -} - -void IRO_MoveExpression(IROExpr *expr, IROLinear *linear) { - IRONode *node; - IROLinear *scan; - - ExprStart = ExprEnd = expr->linear; - IRO_WalkTree(expr->linear, FindStart); - - if (ExprStart != linear) { - IRO_Cut(ExprStart, ExprEnd); - IRO_Paste(ExprStart, ExprEnd, linear); - for (node = IRO_FirstNode; node; node = node->nextnode) { - for (scan = node->first; scan; scan = scan->next) { - if (scan == expr->linear) { - expr->node = node; - break; - } - if (scan == node->last) - break; - } - } - - IRO_Node = expr->node; - IRO_WalkTree(expr->linear, SetNodeNumInExprList); - } -} - -void IRO_InitList(IROList *list) { - list->head = list->tail = NULL; -} - -void IRO_AddToList(IROLinear *linear, IROList *list) { - if (list->head) - list->tail->next = linear; - else - list->head = linear; - - list->tail = linear; - while (list->tail->next) - list->tail = list->tail->next; -} - -IROLinear *IRO_FindLabelNode(CLabel *label, IROLinear *linear) { - IROLinear *scan; - - for (scan = linear; scan; scan = scan->next) { - if (scan->type == IROLinearLabel && scan->u.label.label == label) - break; - } - - CError_ASSERT(1244, scan); - return scan; -} - -void IRO_DuplicateExprRange(IROLinear *start, IROLinear *end, IROList *list) { - IROLinear *scan; - - for (scan = start; scan; scan = scan->next) { - if (scan->type != IROLinearNop && !(scan->flags & IROLF_Reffed)) - IRO_DuplicateExpr(scan, list); - if (scan == end) - break; - } -} - -IROLinear *IRO_DuplicateExpr(IROLinear *linear, IROList *list) { - IROLinear *copy; - ENode *copynode; - int i; - - copy = IRO_NewLinear(linear->type); - *copy = *linear; - - copy->index = ++IRO_NumLinear; - copy->next = NULL; - copy->expr = NULL; - - switch (copy->type) { - case IROLinearOperand: - copynode = lalloc(sizeof(ENode)); - *copynode = *linear->u.node; - copy->u.node = copynode; - break; - case IROLinearOp1Arg: - copy->u.monadic = IRO_DuplicateExpr(copy->u.monadic, list); - break; - case IROLinearOp2Arg: - if (linear->flags & IROLF_8000) { - copy->u.diadic.right = IRO_DuplicateExpr(copy->u.diadic.right, list); - copy->u.diadic.left = IRO_DuplicateExpr(copy->u.diadic.left, list); - } else { - copy->u.diadic.left = IRO_DuplicateExpr(copy->u.diadic.left, list); - copy->u.diadic.right = IRO_DuplicateExpr(copy->u.diadic.right, list); - } - break; - case IROLinearOp3Arg: - copy->u.args3.a = IRO_DuplicateExpr(copy->u.args3.a, list); - copy->u.args3.b = IRO_DuplicateExpr(copy->u.args3.b, list); - copy->u.args3.c = IRO_DuplicateExpr(copy->u.args3.c, list); - break; - case IROLinearFunccall: - copy->u.funccall.linear8 = IRO_DuplicateExpr(copy->u.funccall.linear8, list); - copy->u.funccall.args = oalloc(sizeof(IROLinear *) * copy->u.funccall.argCount); - for (i = 0; i < copy->u.funccall.argCount; i++) { - copy->u.funccall.args[i] = IRO_DuplicateExpr(linear->u.funccall.args[i], list); - } - break; - case IROLinearAsm: - copy->u.asm_stmt = CodeGen_CopyAsmStat(linear->u.asm_stmt); - break; - } - - IRO_AddToList(copy, list); - return copy; -} - -IROLinear *IRO_TempReference(Object *obj, IROList *list) { - IROLinear *op; - IROLinear *ind; - - op = IRO_NewLinear(IROLinearOperand); - op->u.node = create_objectrefnode(obj); - op->rtype = op->u.node->data.objref->type; - op->index = ++IRO_NumLinear; - op->flags |= IROLF_Reffed | IROLF_Ind; - IRO_AddToList(op, list); - - ind = IRO_NewLinear(IROLinearOp1Arg); - ind->nodetype = EINDIRECT; - ind->rtype = obj->type; - ind->u.monadic = op; - ind->index = ++IRO_NumLinear; - ind->next = NULL; - IRO_AddToList(ind, list); - - return ind; -} - -CW_INLINE IROLinear *LocateFatherHelper(IROLinear *linear, Boolean a, IROLinear ***b) { - IROLinear *scan; - SInt32 index; - int i; - - for (scan = linear->next, index = 0; index < (a ? 2 : 1); index++) { - while (scan) { - switch (scan->type) { - case IROLinearIf: - case IROLinearIfNot: - if (scan->u.label.x4 == linear) { - if (b) - *b = &scan->u.label.x4; - return scan; - } - break; - case IROLinearReturn: - if (scan->u.monadic == linear) { - if (b) - *b = &scan->u.monadic; - return scan; - } - break; - case IROLinearOp1Arg: - if (scan->u.monadic == linear) { - if (b) - *b = &scan->u.monadic; - return scan; - } - break; - case IROLinearSwitch: - if (scan->u.swtch.x4 == linear) { - if (b) - *b = &scan->u.swtch.x4; - return scan; - } - break; - case IROLinearOp2Arg: - if (scan->u.diadic.left == linear) { - if (b) - *b = &scan->u.diadic.left; - return scan; - } - if (scan->u.diadic.right == linear) { - if (b) - *b = &scan->u.diadic.right; - return scan; - } - break; - case IROLinearOp3Arg: - if (scan->u.args3.a == linear) { - if (b) - *b = &scan->u.args3.a; - return scan; - } - if (scan->u.args3.b == linear) { - if (b) - *b = &scan->u.args3.b; - return scan; - } - if (scan->u.args3.c == linear) { - if (b) - *b = &scan->u.args3.c; - return scan; - } - break; - case IROLinearFunccall: - if (scan->u.funccall.linear8 == linear) { - if (b) - *b = &scan->u.funccall.linear8; - return scan; - } - for (i = 0; i < scan->u.funccall.argCount; i++) { - if (scan->u.funccall.args[i] == linear) { - if (b) - *b = &scan->u.funccall.args[i]; - return scan; - } - } - break; - case IROLinearNop: - case IROLinearOperand: - case IROLinearGoto: - case IROLinearLabel: - case IROLinearEntry: - case IROLinearExit: - case IROLinearBeginCatch: - case IROLinearEndCatch: - case IROLinearEndCatchDtor: - case IROLinearAsm: - case IROLinearEnd: - break; - default: - CError_FATAL(1536); - } - scan = scan->next; - } - - scan = IRO_FirstLinear; - } - - if (b) - *b = NULL; - return NULL; -} - -IROLinear *IRO_LocateFather(IROLinear *linear) { - return LocateFatherHelper(linear, 0, NULL); -} - -IROLinear *IRO_LocateFather_Cut_And_Paste(IROLinear *a, IROLinear *b) { - IROLinear **p; - IROLinear *l = LocateFatherHelper(a, 0, &p); - if (l) { - CError_ASSERT(1568, p && *p); - IRO_NopOut(a); - *p = b; - } - return l; -} - -IROLinear *IRO_LocateFather_Cut_And_Paste_Without_Nopping(IROLinear *a, IROLinear *b) { - IROLinear **p; - IROLinear *l = LocateFatherHelper(a, 0, &p); - if (l) { - CError_ASSERT(1585, p && *p); - *p = b; - } - return l; -} - -void IRO_ReplaceReference(IROLinear *a, Object *obj, IROLinear *b) { - IROLinear **ptr; - IROList list; - - if (LocateFatherHelper(a, 1, &ptr)) { - CError_ASSERT(1605, ptr && *ptr); - IRO_InitList(&list); - *ptr = IRO_TempReference(obj, &list); - IRO_PasteAfter(list.head, list.tail, b); - if (a->flags & IROLF_LoopInvariant) - list.tail->flags |= IROLF_LoopInvariant; - } else { - IRO_Dump("Oh, oh, did not find reference to replace\n"); - } -} - -void IRO_ReplaceReferenceWithNode(IROLinear *a, IROLinear *b) { - IROLinear **ptr; - IROList list; - - if (LocateFatherHelper(a, 1, &ptr)) { - CError_ASSERT(1664, ptr && *ptr); - *ptr = b; - b->flags |= IROLF_Reffed; - } else { - IRO_Dump("Oh, oh, did not find reference to replace\n"); - } -} - -VarRecord *IRO_GetTemp(IROExpr *expr) { - expr->x8 = create_temp_object(expr->linear->rtype); - return IRO_FindVar(expr->x8, 1, 1); -} - -IROLinear *IRO_AssignToTemp(IROExpr *expr) { - IROLinear *objref; - IROLinear *ind; - IROLinear *ass; - - objref = IRO_NewLinear(IROLinearOperand); - objref->u.node = create_objectrefnode(expr->x8); - objref->rtype = objref->u.node->data.objref->type; - objref->index = ++IRO_NumLinear; - objref->flags |= IROLF_Reffed | IROLF_Assigned | IROLF_Ind; - - ind = IRO_NewLinear(IROLinearOp1Arg); - ind->nodetype = EINDIRECT; - ind->rtype = expr->linear->rtype; - ind->u.monadic = objref; - ind->index = ++IRO_NumLinear; - ind->flags |= IROLF_Reffed | IROLF_Assigned; - - ass = IRO_NewLinear(IROLinearOp2Arg); - ass->nodetype = EASS; - ass->u.diadic.left = ind; - ass->u.diadic.right = expr->linear; - ass->rtype = expr->linear->rtype; - ass->index = ++IRO_NumLinear; - - objref->next = ind; - ind->next = ass; - IRO_PasteAfter(objref, ass, expr->linear); - return ass; -} - -IROLinear *IRO_FindStart(IROLinear *linear) { - ExprStart = ExprEnd = linear; - IRO_WalkTree(linear, FindStart); - return ExprStart; -} - -void IRO_DeleteCommaNode(IROLinear *linear, IROExpr *expr) { - IROLinear *scan; - for (scan = linear; scan; scan = scan->next) { - if (scan->nodetype == ECOMMA) { - if (scan != expr->linear) { - IRO_NopOut(scan->u.diadic.left); - IRO_LocateFather_Cut_And_Paste(scan, scan->u.diadic.right); - } else { - IRO_NopOut(scan->u.diadic.left); - expr->linear = scan->u.diadic.right; - } - } - } -} - -void IRO_RemoveCommaNodeFromIR(void) { - IRONode *node; - IROLinear *linear; - - for (node = IRO_FirstNode; node; node = node->nextnode) { - linear = node->first; - do { - if (!linear) - break; - if (linear->nodetype == ECOMMA) { - linear->u.diadic.left->flags = linear->u.diadic.left->flags & ~IROLF_Reffed; - IRO_LocateFather_Cut_And_Paste_Without_Nopping(linear, linear->u.diadic.right); - linear->type = IROLinearNop; - } - linear = linear->next; - } while (linear != node->last); - } -} - -IROAddrRecord *IRO_InitAddrRecordPointer(IROLinear *linear) { - IROAddrRecord *rec = oalloc(sizeof(IROAddrRecord)); - rec->numObjRefs = 0; - rec->objRefs = NULL; - rec->numMisc = 0; - rec->misc = NULL; - rec->numInts = 0; - rec->ints = NULL; - rec->x16 = 0; - rec->linear = linear; - return rec; -} - -IROLinear *IRO_HasSideEffect(IROLinear *linear) { - IROLinear *tmp; - - if (!linear) - return linear; - - if (linear->rtype && CParser_IsVolatile(linear->rtype, linear->nodeflags & ENODE_FLAG_QUALS)) - return linear; - - switch (linear->type) { - case IROLinearAsm: - return linear; - case IROLinearOperand: - if (ENODE_IS(linear->u.node, EOBJREF) && is_volatile_object(linear->u.node->data.objref)) - return linear; - return NULL; - case IROLinearOp1Arg: - if (IRO_IsAssignOp[linear->nodetype]) - return linear; - else - return IRO_HasSideEffect(linear->u.monadic); - case IROLinearOp2Arg: - if (IRO_IsAssignOp[linear->nodetype]) - return linear; - else if ((tmp = IRO_HasSideEffect(linear->u.diadic.left))) - return tmp; - else - return IRO_HasSideEffect(linear->u.diadic.right); - case IROLinearOp3Arg: - if ((tmp = IRO_HasSideEffect(linear->u.args3.a))) - return tmp; - else if ((tmp = IRO_HasSideEffect(linear->u.args3.b))) - return tmp; - else - return IRO_HasSideEffect(linear->u.args3.c); - case IROLinearFunccall: - return linear; - default: - return linear; - } -} - -IROLinear *IRO_CheckSideEffect(IROLinear *linear) { - IROLinear *result; - IROLinear *tmp; - IROLinear *tmp2; - IROLinear *tmp3; - - if (!linear) - return linear; - - if (linear->rtype && CParser_IsVolatile(linear->rtype, linear->nodeflags & ENODE_FLAG_QUALS)) { - linear->flags &= ~IROLF_Reffed; - return linear; - } - - result = NULL; - switch (linear->type) { - case IROLinearAsm: - linear->flags &= ~IROLF_Reffed; - return linear; - case IROLinearOperand: - if (ENODE_IS(linear->u.node, EOBJREF) && is_volatile_object(linear->u.node->data.objref)) { - linear->flags &= ~IROLF_Reffed; - return linear; - } - break; - case IROLinearOp1Arg: - if (IRO_IsAssignOp[linear->nodetype]) { - linear->flags &= ~IROLF_Reffed; - return linear; - } - if ((result = IRO_CheckSideEffect(linear->u.monadic))) { - if (linear->nodetype == EINDIRECT && linear->u.monadic->type == IROLinearOperand) { - linear->flags &= ~IROLF_Reffed; - return linear; - } - } - break; - case IROLinearOp2Arg: - if (IRO_IsAssignOp[linear->nodetype]) { - linear->flags &= ~IROLF_Reffed; - return linear; - } - tmp = IRO_CheckSideEffect(linear->u.diadic.left); - tmp2 = IRO_CheckSideEffect(linear->u.diadic.right); - if (tmp) - result = tmp; - else - result = tmp2; - break; - case IROLinearOp3Arg: - tmp = IRO_CheckSideEffect(linear->u.args3.a); - tmp2 = IRO_CheckSideEffect(linear->u.args3.b); - tmp3 = IRO_CheckSideEffect(linear->u.args3.c); - result = tmp ? tmp : tmp2 ? tmp2 : tmp3; - break; - case IROLinearFunccall: - linear->flags &= ~IROLF_Reffed; - return linear; - default: - return linear; - } - - linear->type = IROLinearNop; - IRO_Dump("Nop out with side-effects checking at: %d\n", linear->index); - return result; -} - -void IRO_WalkExcActions(ExceptionAction *action, WalkObjFunc func) { - while (action) { - switch (action->type) { - case EAT_DESTROYLOCAL: - func(action->data.destroy_local.local); - break; - case EAT_DESTROYLOCALCOND: - func(action->data.destroy_local_cond.local); - func(action->data.destroy_local_cond.cond); - break; - case EAT_DESTROYLOCALOFFSET: - func(action->data.destroy_local_offset.local); - break; - case EAT_DESTROYLOCALPOINTER: - func(action->data.destroy_local_pointer.pointer); - break; - case EAT_DESTROYLOCALARRAY: - func(action->data.destroy_local_array.localarray); - break; - case EAT_DESTROYPARTIALARRAY: - func(action->data.destroy_partial_array.arraypointer); - func(action->data.destroy_partial_array.arraycounter); - func(action->data.destroy_partial_array.element_size); - break; - case EAT_DESTROYBASE: - func(action->data.destroy_member.objectptr); // wrong union? - break; - case EAT_DESTROYMEMBER: - func(action->data.destroy_member.objectptr); - break; - case EAT_DESTROYMEMBERCOND: - func(action->data.destroy_member_cond.objectptr); - func(action->data.destroy_member_cond.cond); - break; - case EAT_DESTROYMEMBERARRAY: - func(action->data.destroy_member_array.objectptr); - break; - case EAT_DELETEPOINTER: - func(action->data.delete_pointer.pointerobject); - break; - case EAT_DELETEPOINTERCOND: - func(action->data.delete_pointer_cond.pointerobject); - func(action->data.delete_pointer_cond.cond); - break; - } - action = action->prev; - } -} - -Boolean IRO_FunctionCallMightThrowException(IROLinear *linear) { - Object *obj; - if (linear->type == IROLinearFunccall) { - obj = NULL; - if (linear->u.funccall.linear8->type == IROLinearOperand && ENODE_IS(linear->u.funccall.linear8->u.node, EOBJREF)) - obj = linear->u.funccall.linear8->u.node->data.objref; - if (!obj || CExcept_CanThrowException(obj, obj->datatype == DVFUNC && !(linear->nodeflags & ENODE_FLAG_80))) - return 1; - } - return 0; -} - -IROLinear *IRO_NewIntConst(CInt64 val, Type *type) { - ENode *node; - IROLinear *linear; - - node = IRO_NewENode(EINTCONST); - node->data.intval = val; - node->rtype = type; - - linear = IRO_NewLinear(IROLinearOperand); - linear->index = ++IRO_NumLinear; - linear->rtype = type; - linear->u.node = node; - return linear; -} - -IROLinear *IRO_NewFloatConst(const Float val, Type *type) { - ENode *node; - IROLinear *linear; - - node = IRO_NewENode(EFLOATCONST); - node->data.floatval = val; - node->rtype = type; - - linear = IRO_NewLinear(IROLinearOperand); - linear->index = ++IRO_NumLinear; - linear->rtype = type; - linear->u.node = node; - return linear; -} - -Boolean IRO_IsAddressMultiply(IROLinear *linear) { - return 0; -} - -void IRO_SetupForUserBreakChecking(void) { - IRO_LastUserBreakTick = 0; -} - -void IRO_CheckForUserBreak(void) { - if (IRO_LastUserBreakTick + 8 < COS_GetTicks()) { - if (CWUserBreak(cparams.context)) - CError_UserBreak(); - IRO_LastUserBreakTick = COS_GetTicks(); - } -} |