summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted/IroUtil.c
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
committerAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
commit094b96ca1df4a035b5f93c351f773306c0241f3f (patch)
tree95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/IroUtil.c
parentfc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff)
downloadMWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.tar.gz
MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.zip
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted/IroUtil.c')
-rw-r--r--compiler_and_linker/unsorted/IroUtil.c1262
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();
- }
-}