diff options
Diffstat (limited to 'compiler_and_linker/unsorted/IroTransform.c')
-rw-r--r-- | compiler_and_linker/unsorted/IroTransform.c | 2794 |
1 files changed, 0 insertions, 2794 deletions
diff --git a/compiler_and_linker/unsorted/IroTransform.c b/compiler_and_linker/unsorted/IroTransform.c deleted file mode 100644 index 54f3302..0000000 --- a/compiler_and_linker/unsorted/IroTransform.c +++ /dev/null @@ -1,2794 +0,0 @@ -#include "compiler/IroTransform.h" -#include "compiler/CError.h" -#include "compiler/CFunc.h" -#include "compiler/CInt64.h" -#include "compiler/CIRTransform.h" -#include "compiler/CMachine.h" -#include "compiler/CPrep.h" -#include "compiler/CompilerTools.h" -#include "compiler/IroDump.h" -#include "compiler/IroLinearForm.h" -#include "compiler/IroMalloc.h" -#include "compiler/IroPointerAnalysis.h" -#include "compiler/IROUseDef.h" -#include "compiler/IroUtil.h" -#include "compiler/IroVars.h" -#include "compiler/enode.h" -#include "compiler/types.h" - -ENodeType ExprType; -ENode *IndirectRef; -Boolean FirstTime; -CInt64 OperandConst; -Object *OperandObject; -ENodeList *FirstAddend; -ENodeList *LastAddend; -static ENodeType AssignmentOp[MAXEXPR]; -static ENodeType ComplementaryOpLogical[MAXEXPR]; -static ENodeType ComplementaryOp[MAXEXPR]; - -// forward decls -static void DoDiadic(IROLinear *nd); - -static int GetTypeSize(Type *type) { - if (type->size == 1) - return 0; - if (type->size == 2) - return 1; - if (type->size == 4) - return 2; - if (type->size == 8) - return 3; - return -1; -} - -void IRO_InitializeAssignmentOpArray(void) { - int i; - - for (i = 0; i < MAXEXPR; i++) - AssignmentOp[i] = MAXEXPR; - - AssignmentOp[EPOSTINC] = MAXEXPR; - AssignmentOp[EPOSTDEC] = MAXEXPR; - AssignmentOp[EPREINC] = MAXEXPR; - AssignmentOp[EPREDEC] = MAXEXPR; - AssignmentOp[EINDIRECT] = MAXEXPR; - AssignmentOp[EMONMIN] = MAXEXPR; - AssignmentOp[EBINNOT] = MAXEXPR; - AssignmentOp[ELOGNOT] = MAXEXPR; - AssignmentOp[EFORCELOAD] = MAXEXPR; - AssignmentOp[EMUL] = EMULASS; - AssignmentOp[EMULV] = MAXEXPR; - AssignmentOp[EDIV] = EDIVASS; - AssignmentOp[EMODULO] = EMODASS; - AssignmentOp[EADDV] = MAXEXPR; - AssignmentOp[ESUBV] = MAXEXPR; - AssignmentOp[EADD] = EADDASS; - AssignmentOp[ESUB] = ESUBASS; - AssignmentOp[ESHL] = ESHLASS; - AssignmentOp[ESHR] = ESHRASS; - AssignmentOp[ELESS] = MAXEXPR; - AssignmentOp[EGREATER] = MAXEXPR; - AssignmentOp[ELESSEQU] = MAXEXPR; - AssignmentOp[EGREATEREQU] = MAXEXPR; - AssignmentOp[EEQU] = MAXEXPR; - AssignmentOp[ENOTEQU] = MAXEXPR; - AssignmentOp[EAND] = EANDASS; - AssignmentOp[EXOR] = EXORASS; - AssignmentOp[EOR] = EORASS; - AssignmentOp[ELAND] = MAXEXPR; - AssignmentOp[ELOR] = MAXEXPR; - AssignmentOp[EASS] = MAXEXPR; - AssignmentOp[EMULASS] = MAXEXPR; - AssignmentOp[EDIVASS] = MAXEXPR; - AssignmentOp[EMODASS] = MAXEXPR; - AssignmentOp[EADDASS] = MAXEXPR; - AssignmentOp[ESUBASS] = MAXEXPR; - AssignmentOp[ESHLASS] = MAXEXPR; - AssignmentOp[ESHRASS] = MAXEXPR; - AssignmentOp[EANDASS] = MAXEXPR; - AssignmentOp[EXORASS] = MAXEXPR; - AssignmentOp[EORASS] = MAXEXPR; - AssignmentOp[ECOMMA] = MAXEXPR; - AssignmentOp[EPMODULO] = MAXEXPR; - AssignmentOp[EROTL] = MAXEXPR; - AssignmentOp[EROTR] = MAXEXPR; - AssignmentOp[EBCLR] = MAXEXPR; - AssignmentOp[EBTST] = MAXEXPR; - AssignmentOp[EBSET] = MAXEXPR; - AssignmentOp[ETYPCON] = MAXEXPR; - AssignmentOp[EBITFIELD] = MAXEXPR; - AssignmentOp[EINTCONST] = MAXEXPR; - AssignmentOp[EFLOATCONST] = MAXEXPR; - AssignmentOp[ESTRINGCONST] = MAXEXPR; - AssignmentOp[ECOND] = MAXEXPR; - AssignmentOp[EFUNCCALL] = MAXEXPR; - AssignmentOp[EFUNCCALLP] = MAXEXPR; - AssignmentOp[EOBJREF] = MAXEXPR; - AssignmentOp[EMFPOINTER] = MAXEXPR; - AssignmentOp[ENULLCHECK] = MAXEXPR; - AssignmentOp[EPRECOMP] = MAXEXPR; - AssignmentOp[ETEMP] = MAXEXPR; - AssignmentOp[EARGOBJ] = MAXEXPR; - AssignmentOp[ELOCOBJ] = MAXEXPR; - AssignmentOp[ELABEL] = MAXEXPR; - AssignmentOp[ESETCONST] = MAXEXPR; - AssignmentOp[ENEWEXCEPTION] = MAXEXPR; - AssignmentOp[ENEWEXCEPTIONARRAY] = MAXEXPR; - AssignmentOp[EOBJLIST] = MAXEXPR; - AssignmentOp[EMEMBER] = MAXEXPR; - AssignmentOp[ETEMPLDEP] = MAXEXPR; - AssignmentOp[EINSTRUCTION] = MAXEXPR; - AssignmentOp[EDEFINE] = MAXEXPR; - AssignmentOp[EREUSE] = MAXEXPR; - AssignmentOp[EASSBLK] = MAXEXPR; - AssignmentOp[EVECTOR128CONST] = MAXEXPR; - AssignmentOp[ECONDASS] = MAXEXPR; -} - -void IRO_InitializeComplementaryOpArray(void) { - int i; - - for (i = 0; i < MAXEXPR; i++) - ComplementaryOp[i] = MAXEXPR; - - ComplementaryOp[EPOSTINC] = EPOSTDEC; - ComplementaryOp[EPOSTDEC] = EPOSTINC; - ComplementaryOp[EPREINC] = EPREDEC; - ComplementaryOp[EPREDEC] = EPREINC; - ComplementaryOp[EINDIRECT] = MAXEXPR; - ComplementaryOp[EMONMIN] = EMONMIN; - ComplementaryOp[EBINNOT] = EBINNOT; - ComplementaryOp[ELOGNOT] = ELOGNOT; - ComplementaryOp[EFORCELOAD] = MAXEXPR; - ComplementaryOp[EMUL] = EDIV; - ComplementaryOp[EMULV] = MAXEXPR; - ComplementaryOp[EDIV] = EMUL; - ComplementaryOp[EMODULO] = MAXEXPR; - ComplementaryOp[EADDV] = ESUBV; - ComplementaryOp[ESUBV] = EADDV; - ComplementaryOp[EADD] = ESUB; - ComplementaryOp[ESUB] = EADD; - ComplementaryOp[ESHL] = ESHR; - ComplementaryOp[ESHR] = ESHL; - ComplementaryOp[ELESS] = EGREATER; - ComplementaryOp[EGREATER] = ELESS; - ComplementaryOp[ELESSEQU] = EGREATEREQU; - ComplementaryOp[EGREATEREQU] = ELESSEQU; - ComplementaryOp[EEQU] = ENOTEQU; - ComplementaryOp[ENOTEQU] = EEQU; - ComplementaryOp[EAND] = EOR; - ComplementaryOp[EXOR] = MAXEXPR; - ComplementaryOp[EOR] = EAND; - ComplementaryOp[ELAND] = ELOR; - ComplementaryOp[ELOR] = ELAND; - ComplementaryOp[EASS] = MAXEXPR; - ComplementaryOp[EMULASS] = EDIVASS; - ComplementaryOp[EDIVASS] = EMULASS; - ComplementaryOp[EMODASS] = MAXEXPR; - ComplementaryOp[EADDASS] = ESUBASS; - ComplementaryOp[ESUBASS] = EADDASS; - ComplementaryOp[ESHLASS] = ESHRASS; - ComplementaryOp[ESHRASS] = ESHLASS; - ComplementaryOp[EANDASS] = EORASS; - ComplementaryOp[EXORASS] = MAXEXPR; - ComplementaryOp[EORASS] = EANDASS; - ComplementaryOp[ECOMMA] = MAXEXPR; - ComplementaryOp[EPMODULO] = MAXEXPR; - ComplementaryOp[EROTL] = EROTR; - ComplementaryOp[EROTR] = EROTL; - ComplementaryOp[EBCLR] = MAXEXPR; - ComplementaryOp[EBTST] = MAXEXPR; - ComplementaryOp[EBSET] = MAXEXPR; - ComplementaryOp[ETYPCON] = MAXEXPR; - ComplementaryOp[EBITFIELD] = MAXEXPR; - ComplementaryOp[EINTCONST] = MAXEXPR; - ComplementaryOp[EFLOATCONST] = MAXEXPR; - ComplementaryOp[ESTRINGCONST] = MAXEXPR; - ComplementaryOp[ECOND] = MAXEXPR; - ComplementaryOp[EFUNCCALL] = MAXEXPR; - ComplementaryOp[EFUNCCALLP] = MAXEXPR; - ComplementaryOp[EOBJREF] = MAXEXPR; - ComplementaryOp[EMFPOINTER] = MAXEXPR; - ComplementaryOp[ENULLCHECK] = MAXEXPR; - ComplementaryOp[EPRECOMP] = MAXEXPR; - ComplementaryOp[ETEMP] = MAXEXPR; - ComplementaryOp[EARGOBJ] = MAXEXPR; - ComplementaryOp[ELOCOBJ] = MAXEXPR; - ComplementaryOp[ELABEL] = MAXEXPR; - ComplementaryOp[ESETCONST] = MAXEXPR; - ComplementaryOp[ENEWEXCEPTION] = MAXEXPR; - ComplementaryOp[ENEWEXCEPTIONARRAY] = MAXEXPR; - ComplementaryOp[EOBJLIST] = MAXEXPR; - ComplementaryOp[EMEMBER] = MAXEXPR; - ComplementaryOp[ETEMPLDEP] = MAXEXPR; - ComplementaryOp[EINSTRUCTION] = MAXEXPR; - ComplementaryOp[EDEFINE] = MAXEXPR; - ComplementaryOp[EREUSE] = MAXEXPR; - ComplementaryOp[EASSBLK] = MAXEXPR; - ComplementaryOp[EVECTOR128CONST] = MAXEXPR; - ComplementaryOp[ECONDASS] = MAXEXPR; -} - -void IRO_InitializeComplementaryOpLogicalArray(void) { - int i; - - for (i = 0; i < MAXEXPR; i++) - ComplementaryOpLogical[i] = MAXEXPR; - - ComplementaryOpLogical[EPOSTINC] = MAXEXPR; - ComplementaryOpLogical[EPOSTDEC] = MAXEXPR; - ComplementaryOpLogical[EPREINC] = MAXEXPR; - ComplementaryOpLogical[EPREDEC] = MAXEXPR; - ComplementaryOpLogical[EINDIRECT] = MAXEXPR; - ComplementaryOpLogical[EMONMIN] = MAXEXPR; - ComplementaryOpLogical[EBINNOT] = MAXEXPR; - ComplementaryOpLogical[ELOGNOT] = ELOGNOT; - ComplementaryOpLogical[EFORCELOAD] = MAXEXPR; - ComplementaryOpLogical[EMUL] = MAXEXPR; - ComplementaryOpLogical[EMULV] = MAXEXPR; - ComplementaryOpLogical[EDIV] = MAXEXPR; - ComplementaryOpLogical[EMODULO] = MAXEXPR; - ComplementaryOpLogical[EADDV] = MAXEXPR; - ComplementaryOpLogical[ESUBV] = MAXEXPR; - ComplementaryOpLogical[EADD] = MAXEXPR; - ComplementaryOpLogical[ESUB] = MAXEXPR; - ComplementaryOpLogical[ESHL] = MAXEXPR; - ComplementaryOpLogical[ESHR] = MAXEXPR; - ComplementaryOpLogical[ELESS] = EGREATEREQU; - ComplementaryOpLogical[EGREATER] = ELESSEQU; - ComplementaryOpLogical[ELESSEQU] = EGREATER; - ComplementaryOpLogical[EGREATEREQU] = ELESS; - ComplementaryOpLogical[EEQU] = ENOTEQU; - ComplementaryOpLogical[ENOTEQU] = EEQU; - ComplementaryOpLogical[EAND] = MAXEXPR; - ComplementaryOpLogical[EXOR] = MAXEXPR; - ComplementaryOpLogical[EOR] = MAXEXPR; - ComplementaryOpLogical[ELAND] = ELOR; - ComplementaryOpLogical[ELOR] = ELAND; - ComplementaryOpLogical[EASS] = MAXEXPR; - ComplementaryOpLogical[EMULASS] = MAXEXPR; - ComplementaryOpLogical[EDIVASS] = MAXEXPR; - ComplementaryOpLogical[EMODASS] = MAXEXPR; - ComplementaryOpLogical[EADDASS] = MAXEXPR; - ComplementaryOpLogical[ESUBASS] = MAXEXPR; - ComplementaryOpLogical[ESHLASS] = MAXEXPR; - ComplementaryOpLogical[ESHRASS] = MAXEXPR; - ComplementaryOpLogical[EANDASS] = MAXEXPR; - ComplementaryOpLogical[EXORASS] = MAXEXPR; - ComplementaryOpLogical[EORASS] = MAXEXPR; - ComplementaryOpLogical[ECOMMA] = MAXEXPR; - ComplementaryOpLogical[EPMODULO] = MAXEXPR; - ComplementaryOpLogical[EROTL] = MAXEXPR; - ComplementaryOpLogical[EROTR] = MAXEXPR; - ComplementaryOpLogical[EBCLR] = MAXEXPR; - ComplementaryOpLogical[EBTST] = MAXEXPR; - ComplementaryOpLogical[EBSET] = MAXEXPR; - ComplementaryOpLogical[ETYPCON] = MAXEXPR; - ComplementaryOpLogical[EBITFIELD] = MAXEXPR; - ComplementaryOpLogical[EINTCONST] = MAXEXPR; - ComplementaryOpLogical[EFLOATCONST] = MAXEXPR; - ComplementaryOpLogical[ESTRINGCONST] = MAXEXPR; - ComplementaryOpLogical[ECOND] = MAXEXPR; - ComplementaryOpLogical[EFUNCCALL] = MAXEXPR; - ComplementaryOpLogical[EFUNCCALLP] = MAXEXPR; - ComplementaryOpLogical[EOBJREF] = MAXEXPR; - ComplementaryOpLogical[EMFPOINTER] = MAXEXPR; - ComplementaryOpLogical[ENULLCHECK] = MAXEXPR; - ComplementaryOpLogical[EPRECOMP] = MAXEXPR; - ComplementaryOpLogical[ETEMP] = MAXEXPR; - ComplementaryOpLogical[EARGOBJ] = MAXEXPR; - ComplementaryOpLogical[ELOCOBJ] = MAXEXPR; - ComplementaryOpLogical[ELABEL] = MAXEXPR; - ComplementaryOpLogical[ESETCONST] = MAXEXPR; - ComplementaryOpLogical[ENEWEXCEPTION] = MAXEXPR; - ComplementaryOpLogical[ENEWEXCEPTIONARRAY] = MAXEXPR; - ComplementaryOpLogical[EOBJLIST] = MAXEXPR; - ComplementaryOpLogical[EMEMBER] = MAXEXPR; - ComplementaryOpLogical[ETEMPLDEP] = MAXEXPR; - ComplementaryOpLogical[EINSTRUCTION] = MAXEXPR; - ComplementaryOpLogical[EDEFINE] = MAXEXPR; - ComplementaryOpLogical[EREUSE] = MAXEXPR; - ComplementaryOpLogical[EASSBLK] = MAXEXPR; - ComplementaryOpLogical[EVECTOR128CONST] = MAXEXPR; - ComplementaryOpLogical[ECONDASS] = MAXEXPR; -} - -static void DoTransformations(IROLinear *nd) { - IROLinear *nd2; - IROLinear *nd3; - IROLinear *nd4; - IROLinear *nd5; - Type *newtype; - SInt32 value; - - if (nd->type == IROLinearOp2Arg) { - switch (nd->nodetype) { - case EASS: - nd2 = nd->u.diadic.right; - if ( - nd2->type == IROLinearOp2Arg && - AssignmentOp[nd2->nodetype] < MAXEXPR && - IRO_TypesEqual(nd->rtype, nd2->rtype) && - IRO_IsVariable(nd3 = nd->u.diadic.left) && - !(nd3->flags & IROLF_BitfieldIndirect) && - IRO_ExprsSame(nd3, nd2->u.diadic.left) - ) - { - nd->nodetype = AssignmentOp[nd2->nodetype]; - nd->u.diadic.right = nd2->u.diadic.right; - IRO_NopOut(nd2->u.diadic.left); - nd2->type = IROLinearNop; - - nd3->flags |= IROLF_Used; - nd3->u.diadic.left->flags |= IROLF_Used; - } - break; - - case EMUL: - if ( - IS_TYPE_INT(nd->rtype) && - IRO_IsPow2(nd->u.diadic.right, &value) - ) - { - nd->nodetype = ESHL; - CInt64_SetLong(&nd->u.diadic.right->u.node->data.intval, value); - } - break; - - case EDIV: - if ( - IS_TYPE_INT(nd->rtype) && - IRO_IsPow2(nd->u.diadic.right, &value) - ) - { - if (IRO_IsUnsignedType(nd->rtype)) { - nd->nodetype = ESHR; - CInt64_SetLong(&nd->u.diadic.right->u.node->data.intval, value); - } else if ( - !IRO_IsUnsignedType(nd->rtype) && - TYPE_INTEGRAL(nd->rtype)->integral != IT_BOOL && - nd->u.diadic.left->nodetype == ETYPCON && - IS_TYPE_INT(nd->u.diadic.left->u.monadic->rtype) && - IRO_IsUnsignedType(nd->u.diadic.left->u.monadic->rtype) && - nd->u.diadic.left->u.monadic->rtype->size < nd->u.diadic.left->rtype->size - ) - { - nd->nodetype = ESHR; - CInt64_SetLong(&nd->u.diadic.right->u.node->data.intval, value); - if (nd->flags & IROLF_Reffed) { - IROLinear *copy = IRO_NewLinear(IROLinearOp1Arg); - memcpy(copy, nd, sizeof(IROLinear)); - copy->type = IROLinearOp1Arg; - copy->nodetype = ETYPCON; - copy->index = IRO_NumLinear++; - copy->rtype = nd->rtype; - IRO_PasteAfter(copy, copy, nd); - IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, copy); - copy->u.monadic = nd; - nd->flags |= IROLF_Reffed; - } - nd->rtype = IRO_UnsignedType(nd->rtype); - newtype = IRO_UnsignedType(nd->u.diadic.right->rtype); - nd->u.diadic.right->u.node->rtype = newtype; - nd->u.diadic.right->rtype = newtype; - nd->u.diadic.left->rtype = IRO_UnsignedType(nd->u.diadic.left->rtype); - } - } - break; - - case EMODULO: - if ( - IS_TYPE_INT(nd->rtype) && - IRO_IsUnsignedType(nd->rtype) && - IRO_IsPow2(nd->u.diadic.right, &value) - ) - { - nd->nodetype = EAND; - nd->u.diadic.right->u.node->data.intval = CInt64_Sub(nd->u.diadic.right->u.node->data.intval, cint64_one); - } - break; - - case EEQU: - if ( - (nd2 = IRO_LocateFather(nd)) && - nd2->nodetype == ETYPCON && - IS_TYPE_INT(nd2->rtype) && - (nd3 = IRO_LocateFather(nd2)) && - nd3->nodetype == ELOGNOT && - (nd4 = IRO_LocateFather(nd3)) && - nd4->nodetype == ETYPCON && - IS_TYPE_INT(nd4->rtype) && - ( - ((nd5 = IRO_LocateFather(nd4)) && nd5->type == IROLinearIf) || - nd5->type == IROLinearIfNot - ) - ) - { - IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd4, nd); - nd->nodetype = ENOTEQU; - nd2->type = IROLinearNop; - nd3->type = IROLinearNop; - nd4->type = IROLinearNop; - } - break; - } - } -} - -static void IRO_SwitchChildren(IROLinear *nd) { - IROLinear *tmp = nd->u.diadic.left; - nd->u.diadic.left = nd->u.diadic.right; - nd->u.diadic.right = tmp; -} - -static void ReplaceExprWithConst(IROLinear *nd, CInt64 val) { - IRO_NopOut(nd); - nd->type = IROLinearOperand; - nd->nodetype = EINTCONST; - nd->u.node = IRO_NewENode(EINTCONST); - nd->u.node->data.intval = val; - nd->u.node->flags = nd->nodeflags; - nd->u.node->rtype = nd->rtype; - - if (IS_TYPE_FLOAT(nd->rtype)) { - nd->u.node->type = EFLOATCONST; - nd->nodetype = EFLOATCONST; - nd->u.node->data.floatval = CMach_CalcFloatConvertFromInt(TYPE(&stsignedlong), val); - } -} - -static void ReplaceExprWithLeftChild(IROLinear *nd) { - IROLinear *left = nd->u.diadic.left; - IROLinear *right = nd->u.diadic.right; - - if (left->rtype == nd->rtype) { - IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, left); - left->flags = nd->flags; - left->nodeflags = nd->nodeflags; - nd->type = IROLinearNop; - IRO_NopOut(right); - } else { - nd->type = IROLinearOp1Arg; - nd->nodetype = ETYPCON; - nd->u.monadic = left; - IRO_NopOut(right); - } -} - -static void ReplaceExprWithRightChild(IROLinear *nd) { - IROLinear *left = nd->u.diadic.left; - IROLinear *right = nd->u.diadic.right; - - if (right->rtype == nd->rtype) { - IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, right); - right->flags = nd->flags; - right->nodeflags = nd->nodeflags; - nd->type = IROLinearNop; - IRO_NopOut(left); - } else { - nd->type = IROLinearOp1Arg; - nd->nodetype = ETYPCON; - nd->u.monadic = right; - IRO_NopOut(left); - } -} - -static void ReplaceExprWithMonaminRight(IROLinear *nd) { - IROLinear *left = nd->u.diadic.left; - IROLinear *right = nd->u.diadic.right; - - if (right->rtype == nd->rtype) { - nd->type = IROLinearOp1Arg; - nd->nodetype = EMONMIN; - nd->u.monadic = right; - IRO_NopOut(left); - } else { - IRO_NopOut(left); - left->type = IROLinearOp1Arg; - left->nodetype = ETYPCON; - left->expr = right->expr; - left->rtype = nd->rtype; - left->u.monadic = right; - nd->type = IROLinearOp1Arg; - nd->nodetype = EMONMIN; - nd->u.monadic = left; - } -} - -static void ReplaceExprWithMonaminLeft(IROLinear *nd) { - IROLinear *left = nd->u.diadic.left; - IROLinear *right = nd->u.diadic.right; - - if (left->rtype == nd->rtype) { - nd->type = IROLinearOp1Arg; - nd->nodetype = EMONMIN; - nd->u.monadic = left; - IRO_NopOut(right); - } else { - IRO_NopOut(right); - right->type = IROLinearOp1Arg; - right->nodetype = ETYPCON; - right->expr = left->expr; - right->rtype = nd->rtype; - right->u.monadic = left; - nd->type = IROLinearOp1Arg; - nd->nodetype = EMONMIN; - nd->u.monadic = right; - } -} - -static void switchFatherLeftMonadic(IROLinear *nd) { - IROLinear *inner = nd->u.monadic; - IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, inner); - nd->u.monadic = inner->u.monadic; - inner->u.monadic = nd; - inner->rtype = nd->rtype; - inner->flags = nd->flags; - inner->nodeflags = nd->nodeflags; - IRO_CutAndPasteAfter(inner, inner, nd); -} - -static void switchFatherLeft(IROLinear *nd, int isRight) { - IROLinear *a; - IROLinear *b; - - a = nd->u.diadic.left; - IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, a); - - if (isRight) { - nd->u.diadic.left = a->u.diadic.left; - a->u.diadic.left = nd; - b = a->u.diadic.right; - } else { - nd->u.diadic.left = a->u.diadic.right; - a->u.diadic.right = nd; - b = a->u.diadic.left; - } - - a->rtype = nd->rtype; - a->flags = nd->flags; - a->nodeflags = nd->nodeflags; - IRO_CutAndPasteAfter(a, a, nd); - IRO_CutAndPasteAfter(IRO_FindFirst(b), b, nd); -} - -static void PickCommonsubAtLeftLeft(IROLinear *nd) { - switchFatherLeft(nd, 0); - ReplaceExprWithRightChild(nd->u.diadic.right); -} - -static void PickCommonsubAtRightLeft(IROLinear *nd) { - switchFatherLeft(nd, 1); - ReplaceExprWithRightChild(nd->u.diadic.right); -} - -static void PickCommonsubAtLeftRight(IROLinear *nd) { - switchFatherLeft(nd, 0); - ReplaceExprWithLeftChild(nd->u.diadic.right); -} - -static void PickCommonsubAtRightRight(IROLinear *nd) { - switchFatherLeft(nd, 1); - ReplaceExprWithLeftChild(nd->u.diadic.right); -} - -static void DoTransformations11(IROLinear *nd) { - IROLinear *left; - IROLinear *right; - int changed; - int compare; - Type *type; - SInt32 tmp1; - SInt32 tmp2; - CInt64 val; - - if (nd->type == IROLinearOp2Arg) { - left = nd->u.diadic.left; - right = nd->u.diadic.right; - if (IS_TYPE_FLOAT(nd->rtype) || IS_TYPE_FLOAT(left->rtype) || IS_TYPE_FLOAT(right->rtype)) - return; - - changed = 0; - if (!IRO_HasSideEffect(left) && !IRO_HasSideEffect(right)) { - if (IRO_IsIntConstant(right) || IRO_IsFloatConstant(right)) { - if (IRO_IsConstantZero(right)) { - switch (nd->nodetype) { - case EADDV: - case ESUBV: - case EADD: - case ESUB: - case ESHL: - case ESHR: - case EXOR: - case EOR: - case ELOR: - case EADDASS: - case ESUBASS: - case ESHLASS: - case ESHRASS: - case EXORASS: - case EORASS: - ReplaceExprWithLeftChild(nd); - changed = 1; - break; - case EMUL: - case EAND: - case ELAND: - ReplaceExprWithConst(nd, cint64_zero); - changed = 1; - break; - case EMULASS: - case EANDASS: - nd->nodetype = EASS; - nd->u.diadic.right->rtype = nd->rtype; - nd->u.diadic.right->u.node->rtype = nd->rtype; - changed = 1; - break; - case EDIV: - case EMODULO: - case EDIVASS: - case EMODASS: - if (nd->stmt->sourceoffset) { - TStreamElement *token = CPrep_CurStreamElement(); - token->tokenoffset = nd->stmt->sourceoffset; - CError_SetErrorToken(token); - } - CError_Warning(CErrorStr139); - break; - } - } else if (nd->nodetype == ELAND) { - ReplaceExprWithLeftChild(nd); - changed = 1; - } else if (nd->nodetype == ELOR) { - ReplaceExprWithConst(nd, cint64_one); - changed = 1; - } else if (nd->nodetype == ESHL || nd->nodetype == ESHR || nd->nodetype == ESHLASS || nd->nodetype == ESHRASS) { - type = nd->rtype; - tmp1 = type->size * 8; - if (left->type == IROLinearOp1Arg && left->nodetype == ETYPCON) { - type = left->u.monadic->rtype; - if ( - left->u.monadic->type == IROLinearOp1Arg && - left->u.monadic->nodetype == EINDIRECT && - left->u.monadic->u.monadic->type == IROLinearOp1Arg && - left->u.monadic->u.monadic->nodetype == EBITFIELD && - IS_TYPE_BITFIELD(left->u.monadic->u.monadic->rtype) - ) - tmp2 = TYPE_BITFIELD(left->u.monadic->u.monadic->rtype)->bitlength; - else - tmp2 = type->size * 8; - } else { - tmp2 = tmp1; - } - - switch (nd->nodetype) { - case ESHL: - case ESHLASS: - CInt64_SetLong(&val, tmp1); - if (IRO_IsUnsignedType(type)) - compare = CInt64_GreaterEqualU(right->u.node->data.intval, val); - else - compare = CInt64_GreaterEqual(right->u.node->data.intval, val); - break; - case ESHR: - case ESHRASS: - CInt64_SetLong(&val, tmp2); - compare = IRO_IsUnsignedType(type) && CInt64_GreaterEqualU(right->u.node->data.intval, val); - break; - } - - if (compare) { - switch (nd->nodetype) { - case ESHL: - case ESHR: - ReplaceExprWithConst(nd, cint64_zero); - break; - case ESHLASS: - case ESHRASS: - nd->nodetype = EASS; - ReplaceExprWithConst(right, cint64_zero); - break; - } - changed = 1; - } - } else if (IRO_IsConstantOne(right)) { - switch (nd->nodetype) { - case EMUL: - case EMULV: - case EDIV: - case EMULASS: - case EDIVASS: - ReplaceExprWithLeftChild(nd); - changed = 1; - break; - case EMODULO: - ReplaceExprWithConst(nd, cint64_zero); - changed = 1; - break; - case EMODASS: - nd->nodetype = EASS; - ReplaceExprWithConst(right, cint64_zero); - nd->u.diadic.right->rtype = nd->rtype; - nd->u.diadic.right->u.node->rtype = nd->rtype; - changed = 1; - break; - } - } else if (IRO_IsConstantNegativeOne(right)) { - switch (nd->nodetype) { - case EMUL: - case EMULV: - case EDIV: - ReplaceExprWithMonaminLeft(nd); - changed = 1; - break; - case EMODULO: - ReplaceExprWithConst(nd, cint64_zero); - changed = 1; - break; - case EMODASS: - nd->nodetype = EASS; - ReplaceExprWithConst(right, cint64_zero); - nd->u.diadic.right->rtype = nd->rtype; - nd->u.diadic.right->u.node->rtype = nd->rtype; - changed = 1; - break; - } - } - } - - if (!changed && (IRO_IsIntConstant(left) || IRO_IsFloatConstant(left))) { - if (IRO_IsConstantZero(left)) { - switch (nd->nodetype) { - case EADDV: - case EADD: - case EXOR: - case EOR: - case ELOR: - ReplaceExprWithRightChild(nd); - break; - case EMUL: - case ESHL: - case ESHR: - case EAND: - case ELAND: - ReplaceExprWithConst(nd, cint64_zero); - break; - case ESUBV: - case ESUB: - ReplaceExprWithMonaminRight(nd); - break; - } - } else if (nd->nodetype == ELAND) { - ReplaceExprWithRightChild(nd); - } else if (nd->nodetype == ELOR) { - ReplaceExprWithConst(nd, cint64_one); - } else if (IRO_IsConstantOne(left)) { - switch (nd->nodetype) { - case EMUL: - case EMULV: - ReplaceExprWithRightChild(nd); - break; - } - } else if (IRO_IsConstantNegativeOne(left)) { - switch (nd->nodetype) { - case EMUL: - case EMULV: - ReplaceExprWithMonaminRight(nd); - break; - } - } - } - } - } -} - -static void DoTransformations12(IROLinear *nd) { - IROLinear *left; - IROLinear *right; - - if (nd->type == IROLinearOp2Arg) { - left = nd->u.diadic.left; - right = nd->u.diadic.right; - if (IS_TYPE_FLOAT(nd->rtype) || IS_TYPE_FLOAT(left->rtype) || IS_TYPE_FLOAT(right->rtype)) - return; - - if (IRO_ExprsSameSemantically(left, right) && !IRO_HasSideEffect(left)) { - switch (nd->nodetype) { - case ESUBV: - case ESUB: - case ELESS: - case EGREATER: - case ENOTEQU: - case EXOR: - ReplaceExprWithConst(nd, cint64_zero); - break; - case ELESSEQU: - case EGREATEREQU: - case EEQU: - ReplaceExprWithConst(nd, cint64_one); - break; - case EAND: - case EOR: - case ELAND: - case ELOR: - case EASS: - case EANDASS: - case EORASS: - ReplaceExprWithLeftChild(nd); - break; - case ESUBASS: - case EXORASS: - nd->nodetype = EASS; - ReplaceExprWithConst(right, cint64_zero); - break; - } - } - } -} - -static void DoTransformations13(IROLinear *nd) { - IROLinear *left; - IROLinear *right; - IROLinear *left2; - IROLinear *right2; - IROListNode *tmp; - IROListNode *leftlist; - IROListNode *rightlist; - - if (nd->type == IROLinearOp2Arg) { - left = nd->u.diadic.left; - right = nd->u.diadic.right; - - if ( - !IRO_HasSideEffect(left) && - !IRO_HasSideEffect(right) && - (nd->nodetype == EEQU || nd->nodetype == ENOTEQU) && - PointerAnalysis_IsLinearNodePointerExprDefinite(FunctionName, left) && - PointerAnalysis_IsLinearNodePointerExprDefinite(FunctionName, right) - ) - { - leftlist = NULL; - PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, left, &leftlist); - if (leftlist) { - if (leftlist->list.head && leftlist->list.tail && !leftlist->nextList) { - rightlist = NULL; - PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, right, &rightlist); - if (rightlist) { - if (rightlist->list.head && rightlist->list.tail && !rightlist->nextList) { - left2 = leftlist->list.tail; - right2 = rightlist->list.tail; - if (IRO_ExprsSameSemantically(left2, right2)) { - ReplaceExprWithConst(nd, (nd->nodetype == EEQU) ? cint64_one : cint64_zero); - } else if (left2->type == right2->type && IRO_TypesEqual(left2->rtype, right2->rtype)) { - ReplaceExprWithConst(nd, (nd->nodetype == EEQU) ? cint64_zero : cint64_one); - } - } - - while (rightlist) { - tmp = rightlist->nextList; - IRO_free(rightlist); - rightlist = tmp; - } - } - } - - while (leftlist) { - tmp = leftlist->nextList; - IRO_free(leftlist); - leftlist = tmp; - } - } - } - } -} - -static void DoTransformations21(IROLinear *nd) { - IROLinear *left; - IROLinear *right; - Boolean changed; - - if (nd->type == IROLinearOp2Arg) { - left = nd->u.diadic.left; - right = nd->u.diadic.right; - - if (left->type == IROLinearOp1Arg && right->type == IROLinearOp1Arg && left->nodetype == right->nodetype) { - switch (left->nodetype) { - case EMONMIN: - case EBINNOT: - case ELOGNOT: - changed = 0; - switch (nd->nodetype) { - case EXOR: - if (left->nodetype == EBINNOT) - goto collapse; - break; - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - if (left->nodetype == EMONMIN) { - nd->nodetype = ComplementaryOp[nd->nodetype]; - goto collapse; - } - break; - case EMUL: - case EDIV: - if (left->nodetype == EMONMIN) - goto collapse; - break; - case EEQU: - case ENOTEQU: - if (left->nodetype != ELOGNOT) { - collapse: - nd->u.diadic.left = left->u.monadic; - nd->u.diadic.right = right->u.monadic; - left->type = right->type = IROLinearNop; - changed = 1; - } - break; - case ELAND: - case ELOR: - if (left->nodetype == ELOGNOT) { - nd->nodetype = ComplementaryOp[nd->nodetype]; - goto switchfather; - } - break; - case EAND: - case EOR: - if ( - !IS_TYPE_FLOAT(nd->rtype) && - !IS_TYPE_FLOAT(left->rtype) && - !IS_TYPE_FLOAT(right->rtype) && - left->nodetype != EMONMIN - ) - { - nd->nodetype = ComplementaryOp[nd->nodetype]; - goto switchfather; - } - break; - case EADD: - case ESUB: - if ( - !IS_TYPE_FLOAT(nd->rtype) && - !IS_TYPE_FLOAT(left->rtype) && - !IS_TYPE_FLOAT(right->rtype) && - left->nodetype == EMONMIN - ) - { - switchfather: - switchFatherLeftMonadic(nd); - nd->u.diadic.right = right->u.monadic; - right->type = IROLinearNop; - changed = 1; - } - break; - } - - if (changed) { - DoTransformations(nd); - DoTransformations11(nd); - DoTransformations12(nd); - DoTransformations13(nd); - } - break; - } - } - } -} - -static void DoTransformations22(IROLinear *nd) { - IROLinear *left; - IROLinear *right; - IROLinear *ndtmp; - - if (nd->type == IROLinearOp2Arg) { - left = nd->u.diadic.left; - right = nd->u.diadic.right; - if (IS_TYPE_FLOAT(nd->rtype) || IS_TYPE_FLOAT(left->rtype) || IS_TYPE_FLOAT(right->rtype)) - return; - - if (!IRO_HasSideEffect(left) && !IRO_HasSideEffect(right)) { - if (left->type == IROLinearOp1Arg && left->nodetype == EMONMIN) { - switch (nd->nodetype) { - case ESUB: - case ESUBV: - nd->nodetype = ComplementaryOp[nd->nodetype]; - switchFatherLeftMonadic(nd); - break; - - case EADD: - case EADDV: - nd->nodetype = ComplementaryOp[nd->nodetype]; - nd->u.diadic.left = right; - nd->u.diadic.right = left->u.monadic; - left->type = IROLinearNop; - DoTransformations(nd); - DoTransformations12(nd); - DoTransformations21(nd); - break; - - case EDIV: - if (IRO_ExprsSameSemantically(left->u.monadic, right)) - ReplaceExprWithConst(nd, cint64_negone); - break; - } - } else { - ndtmp = NULL; - if (left->type == IROLinearOp1Arg && IRO_ExprsSameSemantically(left->u.monadic, right)) - ndtmp = left; - else if (right->type == IROLinearOp1Arg && IRO_ExprsSameSemantically(left, right->u.monadic)) - ndtmp = right; - - if (ndtmp) { - switch (nd->nodetype) { - case EAND: - if (ndtmp->nodetype == EBINNOT || ndtmp->nodetype == ELOGNOT) - ReplaceExprWithConst(nd, cint64_zero); - break; - - case EANDASS: - if (ndtmp->nodetype == EBINNOT || ndtmp->nodetype == ELOGNOT) { - nd->nodetype = EASS; - ReplaceExprWithConst(right, cint64_zero); - nd->u.diadic.right->rtype = nd->rtype; - nd->u.diadic.right->u.node->rtype = nd->rtype; - } - break; - - case EXOR: - case EOR: - if (ndtmp->nodetype == EBINNOT) { - ReplaceExprWithConst(nd, cint64_zero); - nd->u.node->data.intval = CInt64_Inv(nd->u.node->data.intval); - } - break; - - case EXORASS: - case EORASS: - if (ndtmp->nodetype == EBINNOT) { - nd->nodetype = EASS; - ReplaceExprWithConst(right, cint64_zero); - right->u.node->data.intval = CInt64_Inv(right->u.node->data.intval); - nd->u.diadic.right->rtype = nd->rtype; - nd->u.diadic.right->u.node->rtype = nd->rtype; - } - break; - - case ELOR: - if (ndtmp->nodetype == EBINNOT || ndtmp->nodetype == ELOGNOT) - ReplaceExprWithConst(nd, cint64_one); - break; - - case ELAND: - if (ndtmp->nodetype == ELOGNOT) - ReplaceExprWithConst(nd, cint64_zero); - break; - - case EDIV: - if (ndtmp->nodetype == EMONMIN) - ReplaceExprWithConst(nd, cint64_negone); - break; - - case EDIVASS: - if (ndtmp->nodetype == EMONMIN) { - nd->nodetype = EASS; - ReplaceExprWithConst(right, cint64_negone); - nd->u.diadic.right->rtype = nd->rtype; - nd->u.diadic.right->u.node->rtype = nd->rtype; - } - break; - } - } - } - } - } -} - -static void DoTransformations23(IROLinear *nd) { - Boolean changed; - Boolean isCompare; - UInt8 which; - IROLinear *left; - IROLinear *right; - CInt64 size; - CInt64 val; - - if (nd->type == IROLinearOp2Arg && !IRO_HasSideEffect(nd)) { - left = nd->u.diadic.left; - right = nd->u.diadic.right; - if (IS_TYPE_FLOAT(nd->rtype) || IS_TYPE_FLOAT(left->rtype) || IS_TYPE_FLOAT(right->rtype)) - return; - - isCompare = 0; - changed = 0; - which = 0; - - switch (nd->nodetype) { - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - isCompare = 1; - case EADDV: - case EADD: - case EEQU: - case ENOTEQU: - case EAND: - case EOR: - if (left->type == IROLinearOp2Arg) { - if (IRO_ExprsSameSemantically(right, left->u.diadic.left)) - which = 1; - else if (IRO_ExprsSameSemantically(right, left->u.diadic.right)) - which = 2; - - if (which) { - if (isCompare) - nd->nodetype = ComplementaryOp[nd->nodetype]; - IRO_SwitchChildren(nd); - left = nd->u.diadic.left; - right = nd->u.diadic.right; - break; - } - } - case ESUBV: - case ESUB: - case EADDASS: - case ESUBASS: - case EANDASS: - case EORASS: - if (right->type == IROLinearOp2Arg) { - if (IRO_ExprsSameSemantically(left, right->u.diadic.left)) - which = 1; - else if (IRO_ExprsSameSemantically(left, right->u.diadic.right)) - which = 2; - } - break; - - default: - goto done; - } - - if (which) { - switch (right->nodetype) { - case EAND: - case EOR: - if (which == 2) - IRO_SwitchChildren(right); - - if ( - nd->nodetype == right->nodetype || - (nd->nodetype == EANDASS && right->nodetype == EAND) || - (nd->nodetype == EORASS && right->nodetype == EOR) - ) - { - ReplaceExprWithRightChild(right); - changed = 1; - } - else if ( - nd->nodetype == ComplementaryOp[right->nodetype] || - (nd->nodetype == EANDASS && right->nodetype == EOR) || - (nd->nodetype == EORASS && right->nodetype == EAND) - ) - { - ReplaceExprWithLeftChild(nd); - } - break; - - case EADD: - if (which == 2) - IRO_SwitchChildren(right); - - switch (nd->nodetype) { - case EEQU: - case ENOTEQU: - ReplaceExprWithConst(left, cint64_zero); - ReplaceExprWithRightChild(right); - IRO_SwitchChildren(nd); - if (isCompare) - nd->nodetype = ComplementaryOp[nd->nodetype]; - changed = 1; - break; - - case ESUB: - case ESUBV: - ReplaceExprWithRightChild(right); - ReplaceExprWithMonaminRight(nd); - changed = 1; - break; - - case ESUBASS: - ReplaceExprWithRightChild(right); - changed = 1; - break; - } - break; - - case ESUB: - switch (nd->nodetype) { - case EEQU: - case ENOTEQU: - if (which == 1) { - ReplaceExprWithConst(left, cint64_zero); - ReplaceExprWithRightChild(right); - IRO_SwitchChildren(nd); - } - break; - case EADD: - case EADDV: - if (which == 2) { - ReplaceExprWithLeftChild(right); - ReplaceExprWithRightChild(nd); - } - break; - case ESUB: - case ESUBV: - if (which == 1) { - ReplaceExprWithRightChild(right); - ReplaceExprWithRightChild(nd); - } - break; - case EADDASS: - if (which == 2) { - nd->nodetype = EASS; - ReplaceExprWithLeftChild(right); - changed = 1; - } - break; - case ESUBASS: - if (which == 1) { - nd->nodetype = EASS; - ReplaceExprWithRightChild(right); - changed = 1; - } - break; - } - break; - } - } - - done: - if (!changed) { - switch (nd->nodetype) { - case ESUB: - case ESUBV: - which = 0; - if (left->type == IROLinearOp2Arg) { - if (IRO_ExprsSameSemantically(right, left->u.diadic.left)) - which = 1; - else if (IRO_ExprsSameSemantically(right, left->u.diadic.right)) - which = 2; - } - - if (which == 1) { - if (left->nodetype == ESUB) { - ReplaceExprWithMonaminRight(left); - ReplaceExprWithLeftChild(nd); - } else if (left->nodetype == EADD) { - ReplaceExprWithRightChild(left); - ReplaceExprWithLeftChild(nd); - } - } else if (which == 2) { - if (left->nodetype == EADD) { - ReplaceExprWithLeftChild(left); - ReplaceExprWithLeftChild(nd); - } - } - break; - } - - switch (nd->nodetype) { - case ESHL: - case ESHR: - case ESHLASS: - case ESHRASS: - which = 0; - if (left->type == IROLinearOp2Arg) { - if (left->nodetype == ComplementaryOp[nd->nodetype] || left->nodetype == AssignmentOp[ComplementaryOp[nd->nodetype]]) { - if (IRO_IsIntConstant(right) && IRO_ExprsSameSemantically(right, left->u.diadic.right)) - which = 2; - } - } - - if (which == 2) { - val = right->u.node->data.intval; - if (left->nodetype == ESHR || left->nodetype == ESHRASS) { - ReplaceExprWithLeftChild(left); - nd->nodetype = (nd->nodetype == ESHL) ? EAND : EANDASS; - right->u.node->data.intval = CInt64_Shl(cint64_negone, val); - changed = 1; - } else if (IRO_IsUnsignedType(nd->rtype)) { - ReplaceExprWithLeftChild(left); - nd->nodetype = (nd->nodetype == ESHR) ? EAND : EANDASS; - if (nd->rtype->size < 8) { - CInt64_SetLong(&size, 64 - 8 * nd->rtype->size); - val = CInt64_Add(val, size); - } - right->u.node->data.intval = CInt64_ShrU(cint64_negone, val); - changed = 1; - } - } - break; - } - } - - if (changed) { - DoTransformations(nd); - DoTransformations11(nd); - DoTransformations12(nd); - DoTransformations13(nd); - DoTransformations21(nd); - DoTransformations22(nd); - DoTransformations23(nd); - } - } -} - -static void DoTransformations24(IROLinear *nd) { - IROLinear *left; - IROLinear *right; - UInt8 changed; - - if (nd->type == IROLinearOp2Arg) { - left = nd->u.diadic.left; - right = nd->u.diadic.right; - if (IS_TYPE_FLOAT(nd->rtype) || IS_TYPE_FLOAT(left->rtype) || IS_TYPE_FLOAT(right->rtype)) - return; - - if (left->type == IROLinearOp2Arg && right->type == IROLinearOp2Arg && !IRO_HasSideEffect(nd)) { - changed = 0; - - if (IRO_ExprsSameSemantically(left->u.diadic.left, right->u.diadic.left)) { - if (left->nodetype == right->nodetype) { - switch (left->nodetype) { - case EADD: - if (nd->nodetype == ComplementaryOp[left->nodetype]) { - ReplaceExprWithRightChild(left); - ReplaceExprWithRightChild(right); - changed = 1; - } - break; - case ESUB: - if (nd->nodetype == ESUB || nd->nodetype == ESUBV) { - ReplaceExprWithRightChild(left); - ReplaceExprWithRightChild(right); - IRO_SwitchChildren(nd); - changed = 1; - } - break; - case EMUL: - switch (nd->nodetype) { - case EADD: - case ESUB: - PickCommonsubAtLeftLeft(nd); - changed = 3; - break; - } - break; - case EAND: - if (nd->nodetype == EXOR) { - PickCommonsubAtLeftLeft(nd); - changed = 3; - break; - } - case EOR: - if (nd->nodetype == left->nodetype) { - ReplaceExprWithRightChild(left); - changed = 1; - } else if (nd->nodetype == ComplementaryOp[left->nodetype]) { - PickCommonsubAtLeftLeft(nd); - changed = 3; - } - break; - } - } else if (left->nodetype == ComplementaryOp[right->nodetype]) { - switch (nd->nodetype) { - case ESUB: - case ESUBV: - switch (left->nodetype) { - case EADD: - nd->nodetype = ComplementaryOp[nd->nodetype]; - ReplaceExprWithRightChild(left); - ReplaceExprWithRightChild(right); - changed = 1; - break; - case ESUB: - ReplaceExprWithMonaminRight(left); - ReplaceExprWithRightChild(right); - changed = 1; - break; - } - break; - - case EAND: - case EOR: - if (left->nodetype == nd->nodetype) - ReplaceExprWithLeftChild(nd); - else if (right->nodetype == nd->nodetype) - ReplaceExprWithRightChild(nd); - break; - } - } - } else if (IRO_ExprsSameSemantically(left->u.diadic.right, right->u.diadic.left)) { - if (left->nodetype == right->nodetype) { - switch (left->nodetype) { - case EADD: - if (nd->nodetype == ComplementaryOp[left->nodetype]) { - ReplaceExprWithLeftChild(left); - ReplaceExprWithRightChild(right); - changed = 1; - } - break; - case EMUL: - switch (nd->nodetype) { - case EADD: - case ESUB: - PickCommonsubAtRightLeft(nd); - changed = 3; - break; - } - break; - case EAND: - if (nd->nodetype == EXOR) { - PickCommonsubAtRightLeft(nd); - changed = 3; - break; - } - case EOR: - if (nd->nodetype == left->nodetype) { - ReplaceExprWithLeftChild(left); - changed = 1; - } else if (nd->nodetype == ComplementaryOp[left->nodetype]) { - PickCommonsubAtRightLeft(nd); - changed = 3; - } - break; - } - } else if (left->nodetype == ComplementaryOp[right->nodetype]) { - switch (nd->nodetype) { - case ESUB: - case ESUBV: - if (left->nodetype == EADD) { - nd->nodetype = ComplementaryOp[nd->nodetype]; - ReplaceExprWithLeftChild(left); - ReplaceExprWithRightChild(right); - changed = 1; - } - break; - - case EADD: - case EADDV: - if (left->nodetype == ESUB) { - ReplaceExprWithLeftChild(left); - ReplaceExprWithRightChild(right); - changed = 1; - } - break; - - case EAND: - case EOR: - if (left->nodetype == nd->nodetype) - ReplaceExprWithLeftChild(nd); - else if (right->nodetype == nd->nodetype) - ReplaceExprWithRightChild(nd); - break; - } - } - } else if (IRO_ExprsSameSemantically(left->u.diadic.left, right->u.diadic.right)) { - if (left->nodetype == right->nodetype) { - switch (left->nodetype) { - case EADD: - if (nd->nodetype == ComplementaryOp[left->nodetype]) { - ReplaceExprWithRightChild(left); - ReplaceExprWithLeftChild(right); - changed = 1; - } - break; - case ESUB: - switch (nd->nodetype) { - case EADDV: - case EADD: - nd->nodetype = ComplementaryOp[nd->nodetype]; - ReplaceExprWithRightChild(left); - ReplaceExprWithLeftChild(right); - IRO_SwitchChildren(nd); - changed = 1; - break; - } - break; - case EMUL: - switch (nd->nodetype) { - case EADD: - case ESUB: - PickCommonsubAtLeftRight(nd); - changed = 2; - break; - } - break; - case EAND: - if (nd->nodetype == EXOR) { - PickCommonsubAtLeftRight(nd); - changed = 2; - break; - } - case EOR: - if (nd->nodetype == left->nodetype) { - ReplaceExprWithRightChild(left); - changed = 1; - } else if (nd->nodetype == ComplementaryOp[left->nodetype]) { - PickCommonsubAtLeftRight(nd); - changed = 2; - } - break; - } - } else if (left->nodetype == ComplementaryOp[right->nodetype]) { - switch (nd->nodetype) { - case EADD: - case EADDV: - if (left->nodetype == EADD) { - ReplaceExprWithRightChild(left); - ReplaceExprWithLeftChild(right); - changed = 1; - } - break; - - case ESUB: - case ESUBV: - if (left->nodetype == ESUB) { - ReplaceExprWithMonaminRight(left); - ReplaceExprWithRightChild(right); - changed = 1; - } - break; - - case EAND: - case EOR: - if (left->nodetype == nd->nodetype) - ReplaceExprWithLeftChild(nd); - else if (right->nodetype == nd->nodetype) - ReplaceExprWithRightChild(nd); - break; - } - } - } else if (IRO_ExprsSameSemantically(left->u.diadic.right, right->u.diadic.right)) { - if (left->nodetype == right->nodetype) { - switch (nd->nodetype) { - case ESUB: - switch (left->nodetype) { - case EADD: - case ESUB: - ReplaceExprWithLeftChild(left); - ReplaceExprWithLeftChild(right); - changed = 1; - } - case EADD: - switch (left->nodetype) { - case EMUL: - case ESHL: - PickCommonsubAtRightRight(nd); - changed = 2; - break; - } - break; - case EXOR: - switch (left->nodetype) { - case ESHL: - case ESHR: - case EAND: - PickCommonsubAtRightRight(nd); - changed = 2; - break; - } - break; - case EAND: - case EOR: - if (left->nodetype == nd->nodetype) { - ReplaceExprWithLeftChild(right); - changed = 1; - } else if ( - left->nodetype == ComplementaryOp[nd->nodetype] || - left->nodetype == ESHR || - left->nodetype == ESHL - ) - { - PickCommonsubAtRightRight(nd); - changed = 2; - } - break; - } - } else if (left->nodetype == ComplementaryOp[right->nodetype]) { - switch (nd->nodetype) { - case EADD: - case EADDV: - switch (left->nodetype) { - case EADD: - case ESUB: - ReplaceExprWithLeftChild(left); - ReplaceExprWithLeftChild(right); - changed = 1; - break; - } - break; - - case EAND: - case EOR: - if (left->nodetype == nd->nodetype) - ReplaceExprWithLeftChild(nd); - else if (right->nodetype == nd->nodetype) - ReplaceExprWithRightChild(nd); - break; - } - } - } - - if (changed) { - DoDiadic(nd); - if (changed == 2) - DoDiadic(nd->u.diadic.left); - else if (changed == 3) - DoDiadic(nd->u.diadic.right); - IRO_Dump("remove common op at: %d\n", nd->index); - } - } - } -} - -static void DoTransformations25(IROLinear *nd) { - int changed = 0; - IROLinear *left; - IROLinear *right; - - if (nd->type == IROLinearOp2Arg) { - left = nd->u.diadic.left; - right = nd->u.diadic.right; - - if ( - (left->type == IROLinearOp2Arg && (IS_TYPE_FLOAT(left->u.diadic.left->rtype) || IS_TYPE_FLOAT(left->u.diadic.right->rtype))) || - (right->type == IROLinearOp2Arg && (IS_TYPE_FLOAT(right->u.diadic.left->rtype) || IS_TYPE_FLOAT(right->u.diadic.right->rtype))) - ) - return; - - switch (left->nodetype) { - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - case EEQU: - case ENOTEQU: - switch (nd->nodetype) { - case EEQU: - if (IRO_IsConstantOne(right)) { - ReplaceExprWithLeftChild(nd); - changed = 1; - } else if (IRO_IsConstantZero(right)) { - left->nodetype = ComplementaryOpLogical[left->nodetype]; - ReplaceExprWithLeftChild(nd); - changed = 1; - } - break; - case ENOTEQU: - if (IRO_IsConstantOne(right)) { - left->nodetype = ComplementaryOpLogical[left->nodetype]; - ReplaceExprWithLeftChild(nd); - changed = 1; - } else if (IRO_IsConstantZero(right)) { - ReplaceExprWithLeftChild(nd); - changed = 1; - } - break; - } - break; - case ELAND: - case ELOR: - switch (nd->nodetype) { - case EEQU: - if (IRO_IsConstantOne(right)) { - ReplaceExprWithLeftChild(nd); - changed = 1; - } - break; - case ENOTEQU: - if (IRO_IsConstantZero(right)) { - ReplaceExprWithLeftChild(nd); - changed = 1; - } - break; - } - break; - } - - if (!changed) { - switch (right->nodetype) { - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - case EEQU: - case ENOTEQU: - switch (nd->nodetype) { - case EEQU: - if (IRO_IsConstantOne(left)) { - ReplaceExprWithRightChild(nd); - } else if (IRO_IsConstantZero(left)) { - right->nodetype = ComplementaryOpLogical[right->nodetype]; - ReplaceExprWithRightChild(nd); - } - break; - case ENOTEQU: - if (IRO_IsConstantOne(left)) { - right->nodetype = ComplementaryOpLogical[right->nodetype]; - ReplaceExprWithRightChild(nd); - } else if (IRO_IsConstantZero(left)) { - ReplaceExprWithRightChild(nd); - } - break; - } - break; - case ELAND: - case ELOR: - switch (nd->nodetype) { - case EEQU: - if (IRO_IsConstantOne(left)) { - ReplaceExprWithRightChild(nd); - } - break; - case ENOTEQU: - if (IRO_IsConstantZero(left)) { - ReplaceExprWithRightChild(nd); - } - break; - } - break; - } - } - } -} - -static Boolean isOrderingOperator(ENodeType op) { - switch (op) { - case ELAND: - case ELOR: - case ECOMMA: - case ECOND: - case ECONDASS: - return 1; - default: - return 0; - } -} - -static void RemoveUnreffed(IROLinear *nd) { - if (!(nd->flags & IROLF_Reffed)) { - switch (nd->type) { - case IROLinearOperand: - IRO_NopNonSideEffects(nd, 0); - break; - case IROLinearOp1Arg: - case IROLinearOp2Arg: - case IROLinearOp3Arg: - case IROLinearFunccall: - if (!isOrderingOperator(nd->nodetype)) - IRO_NopNonSideEffects(nd, 0); - break; - } - } -} - -static void RemoveRedundantMonadicOp(IROLinear *nd) { - IROLinear *nd2; - IROLinear *nd3; - - if (nd->type == IROLinearOp1Arg && (nd2 = IRO_LocateFather(nd)) && nd2->nodetype == nd->nodetype) { - switch (nd->nodetype) { - case ELOGNOT: - if ((nd3 = IRO_LocateFather(nd2))) { - if ( - nd3->rtype && - TYPE_INTEGRAL(nd3->rtype)->integral == IT_BOOL && - nd->u.monadic->rtype && - TYPE_INTEGRAL(nd->u.monadic->rtype)->integral == IT_BOOL - ) - goto remove; - - if (nd3->type == IROLinearIf) - goto remove; - if (nd3->type == IROLinearIfNot) - goto remove; - if (nd3->type == IROLinearOp3Arg && nd == nd3->u.args3.a) - goto remove; - - switch (nd3->nodetype) { - case ELOGNOT: - case ELAND: - case ELOR: - goto remove; - } - } - - if (nd->u.monadic->type == IROLinearOp1Arg || nd->u.monadic->type == IROLinearOp2Arg) { - switch (nd->u.monadic->nodetype) { - case ELOGNOT: - case ELESS: - case EGREATER: - case ELESSEQU: - case EGREATEREQU: - case EEQU: - case ENOTEQU: - case ELAND: - case ELOR: - goto remove; - } - } - break; - - case EMONMIN: - case EBINNOT: - remove: - IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd2, nd->u.monadic); - nd2->type = IROLinearNop; - nd->type = IROLinearNop; - break; - - case ETYPCON: - if (TYPE_INTEGRAL(nd->rtype)->integral == IT_FLOAT) { - switch (TYPE_INTEGRAL(nd2->rtype)->integral) { - case IT_DOUBLE: - case IT_LONGDOUBLE: - switch (TYPE_INTEGRAL(nd->u.monadic->rtype)->integral) { - case IT_BOOL: - case IT_CHAR: - case IT_SCHAR: - case IT_UCHAR: - case IT_SHORT: - case IT_USHORT: - nd->type = IROLinearNop; - nd2->u.monadic = nd->u.monadic; - break; - } - break; - } - } - break; - } - } -} - -static void ReverseOpForMonmin(IROLinear *nd) { - IROLinear *father; - - if ( - nd->type == IROLinearOp1Arg && - nd->nodetype == EMONMIN && - (father = IRO_LocateFather(nd)) && - father->type == IROLinearOp2Arg && - father->u.diadic.right == nd - ) - { - switch (father->nodetype) { - case EADDV: - case ESUBV: - case EADD: - case ESUB: - case EADDASS: - case ESUBASS: - father->nodetype = ComplementaryOp[father->nodetype]; - nd->type = IROLinearNop; - father->u.diadic.right = nd->u.monadic; - break; - } - } -} - -static void DoDiadic(IROLinear *nd) { - RemoveUnreffed(nd); - DoTransformations(nd); - DoTransformations11(nd); - DoTransformations12(nd); - DoTransformations13(nd); - DoTransformations21(nd); - DoTransformations22(nd); - DoTransformations23(nd); - DoTransformations24(nd); - DoTransformations25(nd); -} - -void IRO_DoTransformations(void) { - IROLinear *nd; - - for (nd = IRO_FirstLinear; nd; nd = nd->next) { - switch (nd->type) { - case IROLinearOp2Arg: - DoDiadic(nd); - break; - case IROLinearOp1Arg: - RemoveUnreffed(nd); - RemoveRedundantMonadicOp(nd); - ReverseOpForMonmin(nd); - break; - case IROLinearOperand: - RemoveUnreffed(nd); - break; - } - } - - IRO_CheckForUserBreak(); -} - -static Boolean ReconcileAssignments(IROLinear *nd1, IROLinear *nd2, IROList *list) { - IROLinear *copy; - Boolean result = 0; - int argCount; - int i; - IROLinear *tmp; - - if ( - (nd2->type == IROLinearOp1Arg && nd2->nodetype == ETYPCON) && - !(nd1->type == IROLinearOp1Arg && nd1->nodetype == ETYPCON) && - ReconcileAssignments(nd1, nd2->u.monadic, list) - ) - { - result = 1; - } - - if ( - (nd1->type == IROLinearOp1Arg && nd1->nodetype == ETYPCON) && - !(nd2->type == IROLinearOp1Arg && nd2->nodetype == ETYPCON) && - ReconcileAssignments(nd1->u.monadic, nd2, list) - ) - { - copy = IRO_NewLinear(IROLinearOp1Arg); - *copy = *nd2; - copy->index = IRO_NumLinear++; - copy->type = IROLinearOp1Arg; - copy->nodetype = ETYPCON; - copy->rtype = nd1->rtype; - copy->next = NULL; - copy->u.monadic = list->tail; - IRO_AddToList(copy, list); - result = 1; - } - - if (nd1->type == nd2->type && nd1->nodetype == nd2->nodetype) { - copy = IRO_NewLinear(IROLinearNop); - *copy = *nd2; - copy->index = IRO_NumLinear++; - copy->rtype = nd1->rtype; - copy->next = NULL; - switch (nd1->type) { - case IROLinearOperand: - if (nd1->u.node->type == nd2->u.node->type) { - if (!(nd1->u.node->type == EOBJREF && nd1->u.node->data.objref != nd2->u.node->data.objref)) - result = 1; - } - break; - - case IROLinearOp1Arg: - if (ReconcileAssignments(nd1->u.monadic, nd2->u.monadic, list)) { - copy->u.monadic = list->tail; - result = 1; - } - break; - - case IROLinearOp2Arg: - tmp = list->tail; - if (ReconcileAssignments(nd1->u.diadic.left, nd2->u.diadic.left, list)) { - copy->u.diadic.left = list->tail; - if (ReconcileAssignments(nd1->u.diadic.right, nd2->u.diadic.right, list)) { - copy->u.diadic.right = list->tail; - result = 1; - } - } - - if (!result && !IRO_HasSideEffect(nd1) && !IRO_HasSideEffect(nd2)) { - if (nd1->nodetype == EMUL || nd1->nodetype == EADD || nd1->nodetype == EAND || nd1->nodetype == EXOR || nd1->nodetype == EOR) { - list->tail = tmp; - if (ReconcileAssignments(nd1->u.diadic.left, nd2->u.diadic.right, list)) { - copy->u.diadic.right = list->tail; - if (ReconcileAssignments(nd1->u.diadic.right, nd2->u.diadic.left, list)) { - copy->u.diadic.left = list->tail; - result = 1; - } - } - } - } - break; - - case IROLinearOp3Arg: - if (ReconcileAssignments(nd1->u.args3.c, nd2->u.args3.c, list)) { - copy->u.args3.c = list->tail; - if (ReconcileAssignments(nd1->u.args3.b, nd2->u.args3.b, list)) { - copy->u.args3.b = list->tail; - if (ReconcileAssignments(nd1->u.args3.a, nd2->u.args3.a, list)) { - copy->u.args3.a = list->tail; - result = 1; - } - } - } - break; - - case IROLinearFunccall: - argCount = nd1->u.funccall.argCount; - if (argCount == nd2->u.funccall.argCount) { - result = 1; - copy->u.funccall.args = oalloc(sizeof(IROLinear *) * argCount); - for (i = argCount - 1; i >= 0; i--) { - if (!ReconcileAssignments(nd1->u.funccall.args[i], nd2->u.funccall.args[i], list)) { - result = 0; - break; - } - copy->u.funccall.args[i] = list->tail; - } - - if (result) { - if (!ReconcileAssignments(nd1->u.funccall.linear8, nd2->u.funccall.linear8, list)) { - result = 0; - break; - } - copy->u.funccall.linear8 = list->tail; - } - } - break; - } - - if (result) - IRO_AddToList(copy, list); - } - - return result; -} - -static IROLinear *FrontendTransformSelfAssignmentToAssignment(IROLinear *nd) { - Statement *stmt; - IROList list; - IROLinearIRSave save; - - IRO_SaveLinearIR(&save); - - IRO_InitList(&list); - IRO_DuplicateExpr(nd, &list); - - stmt = IRO_Delinearize(NULL, list.head); - CError_ASSERT(3550, stmt); - CError_ASSERT(3552, stmt->expr); - stmt->expr = CIRTrans_TransformOpAss(stmt->expr); - CError_ASSERT(3557, stmt->expr); - - if (DoLinearize) - IRO_PreLinearize(stmt); - IRO_Linearize(stmt); - - IRO_InitList(&list); - list.head = IRO_FirstLinear; - list.tail = IRO_LastLinear; - - IRO_RestoreLinearIR(&save); - - for (nd = list.head; nd; nd = nd->next) { - if (!(nd->flags & IROLF_Reffed) && IRO_IsAssignment(nd)) - break; - } - - return nd; -} - -static Type *PromotedIntegralType(Type *type) { - CError_ASSERT(3586, IS_TYPE_ENUM(type) || IS_TYPE_INT(type)); - - if (IS_TYPE_ENUM(type)) - type = TYPE_ENUM(type)->enumtype; - - if (TYPE_INTEGRAL(type)->integral < IT_INT) { - if (IRO_IsUnsignedType(type)) - return TYPE(&stunsignedint); - else - return TYPE(&stsignedint); - } else { - return type; - } -} - -static Boolean TransformMonadicSelfAssignmentToDiadicSelfAssignment(IROLinear *nd) { - ENodeType t; - ENodeType newtype; - IROLinear *incExpr; - IROLinear *varExpr; - - t = nd->nodetype; - - if (IRO_IsAssignment(nd) && IRO_IsModifyOp[t]) { - incExpr = NULL; - varExpr = NULL; - newtype = MAXEXPR; - - if ( - nd->type == IROLinearOp1Arg && - (t == EPOSTINC || t == EPOSTDEC || t == EPREINC || t == EPREDEC) && - (!(nd->flags & IROLF_Reffed) || t == EPREINC || t == EPREDEC) - ) - { - Type *type = nd->rtype; - TypeType typetype = type->type; - varExpr = nd->u.monadic; - if (typetype == TYPEINT || typetype == TYPEENUM) { - incExpr = IRO_NewIntConst(cint64_one, PromotedIntegralType(type)); - } else if (typetype == TYPEPOINTER || typetype == TYPEARRAY || typetype == TYPEMEMBERPOINTER) { - Type *inner = NULL; - CInt64 val = cint64_zero; - - if (typetype == TYPEPOINTER || typetype == TYPEARRAY) - inner = TPTR_TARGET(type); - else if (typetype == TYPEMEMBERPOINTER) - inner = TYPE_MEMBER_POINTER(type)->ty1; - - if (inner) - CInt64_SetLong(&val, inner->size); - - if (!CInt64_IsZero(&val)) { - incExpr = IRO_NewIntConst(val, TYPE(&stsignedlong)); - } else { - return 0; - } - } else if (typetype == TYPEFLOAT) { - Float fval; - fval = CMach_CalcFloatConvertFromInt(type, cint64_one); - incExpr = IRO_NewFloatConst(fval, nd->rtype); - } else { - return 0; - } - - if (t == EPOSTINC || t == EPREINC) - newtype = EADDASS; - else - newtype = ESUBASS; - } - - if ( - varExpr && - incExpr && - newtype != MAXEXPR && - varExpr->u.diadic.left && - varExpr->u.diadic.left->type == IROLinearOperand && - varExpr->u.diadic.left->u.node && - varExpr->u.diadic.left->u.node->type == EOBJREF && - !IRO_HasSideEffect(varExpr) - ) - { - incExpr->flags |= IROLF_Reffed; - nd->nodetype = newtype; - nd->u.diadic.right = incExpr; - nd->type = IROLinearOp2Arg; - IRO_Paste(incExpr, incExpr, nd); - return 1; - } - } - - return 0; -} - -Boolean IRO_TransformSelfAssignmentToAssignment(IROLinear *nd) { - ENodeType nonAssOp; - IROLinear *left; - IROLinear *right; - ENodeType nodetype; - IROLinear *nonAss; - IROLinear *dupLeft; - IROLinear *last; - IROList list1; - IROList list2; - - nodetype = nd->nodetype; - if ( - IRO_IsAssignment(nd) && - IRO_IsModifyOp[nodetype] && - nd->type == IROLinearOp1Arg && - TransformMonadicSelfAssignmentToDiadicSelfAssignment(nd) - ) - nodetype = nd->nodetype; - - if ( - IRO_IsAssignment(nd) && - IRO_IsModifyOp[nodetype] && - nd->type == IROLinearOp2Arg && - IRO_NonAssignmentOp[nodetype] != MAXEXPR - ) - { - left = nd->u.diadic.left; - right = nd->u.diadic.right; - nonAssOp = IRO_NonAssignmentOp[nodetype]; - if ( - left && - right && - nonAssOp != MAXEXPR && - left->u.monadic && - left->u.monadic->type == IROLinearOperand && - left->u.monadic->u.node && - left->u.monadic->u.node->type == EOBJREF && - !IRO_HasSideEffect(left) - ) - { - IRO_InitList(&list1); - dupLeft = IRO_DuplicateExpr(left, &list1); - - if (left->rtype != right->rtype) { - IROLinear *tmp = IRO_NewLinear(IROLinearOp1Arg); - tmp->nodetype = ETYPCON; - tmp->flags |= IROLF_Reffed; - tmp->rtype = right->rtype; - tmp->index = ++IRO_NumLinear; - tmp->u.monadic = dupLeft; - IRO_AddToList(tmp, &list1); - dupLeft = tmp; - } - - nonAss = IRO_NewLinear(IROLinearOp2Arg); - nonAss->nodetype = nonAssOp; - nonAss->flags |= IROLF_Reffed; - nonAss->rtype = dupLeft->rtype; - nonAss->index = ++IRO_NumLinear; - nonAss->u.diadic.left = dupLeft; - nonAss->u.diadic.right = right; - IRO_AddToList(nonAss, &list1); - - if (left->rtype != right->rtype) { - IROLinear *tmp = IRO_NewLinear(IROLinearOp1Arg); - tmp->nodetype = ETYPCON; - tmp->flags |= IROLF_Reffed; - tmp->rtype = left->rtype; - tmp->index = ++IRO_NumLinear; - tmp->u.monadic = nonAss; - IRO_AddToList(tmp, &list1); - nonAss = tmp; - } - - IRO_InitList(&list2); - last = FrontendTransformSelfAssignmentToAssignment(nd); - if ( - last && - last->type == IROLinearOp2Arg && - ReconcileAssignments(last->u.diadic.right, nonAss, &list2) - ) - { - IRO_NopOut(nd->u.diadic.right); - nd->nodetype = EASS; - nd->u.diadic.right = list2.tail; - nd->type = IROLinearOp2Arg; - IRO_Paste(list2.head, list2.tail, nd); - return 1; - } - } - } - - return 0; -} - -static void AddAddend(ENode *expr) { - if (expr->type == EADD) { - AddAddend(expr->data.diadic.left); - AddAddend(expr->data.diadic.right); - } else { - ENodeList *list = oalloc(sizeof(ENodeList)); - list->node = expr; - list->next = NULL; - - if (FirstAddend) - LastAddend->next = list; - else - FirstAddend = list; - LastAddend = list; - } -} - -static ENode *CombineConstants(ENode *expr) { - ENode *addend; - ENodeList *el; - ENode *result; - ENode *var; - Type *type; - ENode *tmp; - ENodeList *prev; - CInt64 val; - - FirstAddend = LastAddend = NULL; - AddAddend(expr->data.diadic.left); - AddAddend(expr->data.diadic.right); - - // these variable names are courtesy of the resource fork in abort_exit.c - el = FirstAddend; - prev = NULL; - var = NULL; - while (el) { - addend = el->node; - if (addend->type == EOBJREF) { - var = addend; - if (prev) - prev->next = el->next; - else - FirstAddend = el->next; - break; - } - prev = el; - el = el->next; - } - - if (!var) { - el = FirstAddend; - prev = NULL; - while (el) { - addend = el->node; - if (addend->type == EINDIRECT) { - var = addend; - if (prev) - prev->next = el->next; - else - FirstAddend = el->next; - break; - } - prev = el; - el = el->next; - } - } - - prev = NULL; - CInt64_SetLong(&val, 0); - type = NULL; - - for (el = FirstAddend; el; el = el->next) { - addend = el->node; - if (addend->type == EINTCONST && addend->rtype) { - if (!type || type->size < addend->rtype->size) - type = addend->rtype; - val = CInt64_Add(val, addend->data.intval); - if (prev) - prev->next = el->next; - else - FirstAddend = el->next; - } else if (addend->type == EMUL && addend->data.diadic.right->type == EINTCONST && addend->rtype) { - if (!type || type->size < addend->rtype->size) - type = addend->rtype; - - tmp = addend->data.diadic.left; - if (tmp->type == EADD && tmp->data.diadic.right->type == EINTCONST) { - val = CInt64_Add(val, CInt64_MulU(tmp->data.diadic.right->data.intval, addend->data.diadic.right->data.intval)); - addend->data.diadic.left = tmp->data.diadic.left; - } - prev = el; - } else { - prev = el; - } - } - - result = NULL; - if (var) { - result = var; - if (!CInt64_IsZero(&val)) { - result = IRO_NewENode(EADD); - result->data.diadic.left = var; - result->data.diadic.right = IRO_NewENode(EINTCONST); - result->data.diadic.right->data.intval = val; - result->data.diadic.right->rtype = type; - result->rtype = var->rtype; - result->cost = 1; - CInt64_SetLong(&val, 0); - } - } - - for (el = FirstAddend; el; el = el->next) { - addend = el->node; - if (result) { - tmp = IRO_NewENode(EADD); - tmp->data.diadic.left = result; - tmp->data.diadic.right = addend; - tmp->cost = result->cost + 1; - tmp->rtype = result->rtype; - result = tmp; - } else { - result = addend; - } - } - - if (!CInt64_IsZero(&val)) { - tmp = IRO_NewENode(EADD); - tmp->data.diadic.left = result; - tmp->data.diadic.right = IRO_NewENode(EINTCONST); - tmp->data.diadic.right->data.intval = val; - tmp->data.diadic.right->rtype = type; - tmp->cost = result->cost + 1; - tmp->rtype = result->rtype; - result = tmp; - } - - return result; -} - -static ENode *TransformExprNode(ENode *expr) { - ENode *left; - ENode *right; - - switch (expr->type) { - case EINDIRECT: - if (ENODE_IS(expr->data.monadic, EADD)) - expr->data.monadic = CombineConstants(expr->data.monadic); - break; - - case EMUL: - case EADD: - case EAND: - case EXOR: - case EOR: - if ( - IS_TYPE_INT(expr->rtype) && - !ENODE_IS(right = expr->data.diadic.right, EINTCONST) && - ENODE_IS(left = expr->data.diadic.left, EINTCONST) - ) - { - expr->data.diadic.left = right; - expr->data.diadic.right = left; - } - break; - - case EEQU: - case ENOTEQU: - if ( - IS_TYPE_INT(expr->rtype) && - !ENODE_IS(left = expr->data.diadic.right, EINTCONST) && - ENODE_IS(right = expr->data.diadic.left, EINTCONST) - ) - { - expr->data.diadic.left = left; - expr->data.diadic.right = right; - } - - if ( - ENODE_IS(expr->data.diadic.right, EINTCONST) && - ENODE_IS(left = expr->data.diadic.left, EBINNOT) - ) - { - expr->data.diadic.left = left->data.monadic; - left->data.monadic = expr->data.diadic.right; - expr->data.diadic.right = left; - } - - break; - } - - return expr; -} - -static ENode *TransformExprTree(ENode *expr) { - ENodeList *list; - - switch (expr->type) { - ENODE_CASE_MONADIC: - expr->data.monadic = TransformExprTree(expr->data.monadic); - break; - - ENODE_CASE_DIADIC_ALL: - expr->data.diadic.left = TransformExprTree(expr->data.diadic.left); - expr->data.diadic.right = TransformExprTree(expr->data.diadic.right); - break; - - case EFUNCCALL: - case EFUNCCALLP: - TransformExprTree(expr->data.funccall.funcref); - for (list = expr->data.funccall.args; list; list = list->next) - TransformExprTree(list->node); - break; - - case ECOND: - TransformExprTree(expr->data.cond.cond); - TransformExprTree(expr->data.cond.expr1); - TransformExprTree(expr->data.cond.expr2); - break; - - case ENULLCHECK: - TransformExprTree(expr->data.nullcheck.nullcheckexpr); - TransformExprTree(expr->data.nullcheck.condexpr); - break; - } - - return TransformExprNode(expr); -} - -static void FoldConstantsinAssociativeExprs(ENode *expr) { - short nodetype1; - short nodetype2; - short nodetype3; - Boolean changed; - short op; - CInt64 val1; - CInt64 val2; - CInt64 tmpval; - - if ( - ( - expr->type == EADD || - expr->type == EMUL || - expr->type == EAND || - expr->type == EXOR || - expr->type == EOR || - expr->type == ESHL || - expr->type == ESHR - ) && - IS_TYPE_INT(expr->rtype) && - expr->data.diadic.right->type == EINTCONST - ) - { - do { - changed = 0; - - if ( - expr->data.diadic.left->type == expr->type && - expr->data.diadic.left->data.diadic.right->type == EINTCONST - ) - { - val1 = expr->data.diadic.right->data.intval; - val2 = expr->data.diadic.left->data.diadic.right->data.intval; - switch (expr->type) { - case EADD: - case ESHL: - op = '+'; - break; - case ESHR: - op = '+'; - if (!IRO_IsUnsignedType(expr->rtype)) { - CInt64_SetLong(&tmpval, expr->rtype->size * 8); - if (CInt64_GreaterEqualU(val1, tmpval) || CInt64_GreaterEqualU(val2, tmpval)) - return; - - if (CInt64_GreaterEqualU(CMach_CalcIntDiadic(expr->rtype, val1, '+', val2), tmpval)) { - val1 = CInt64_Sub(tmpval, cint64_one); - val2 = cint64_zero; - } - } - break; - case EMUL: - op = '*'; - break; - case EAND: - op = '&'; - break; - case EOR: - op = '|'; - break; - case EXOR: - op = '^'; - break; - default: - return; - } - - expr->data.diadic.right->data.intval = CMach_CalcIntDiadic(expr->rtype, val1, op, val2); - expr->data.diadic.left = expr->data.diadic.left->data.diadic.left; - changed = 1; - } else if ( - ((nodetype1 = expr->type) == EAND || nodetype1 == EOR) && - ((nodetype2 = expr->data.diadic.left->type) == EAND || nodetype2 == EOR) && - ((nodetype3 = expr->data.diadic.left->data.diadic.left->type) == EAND || nodetype3 == EOR) && - expr->data.diadic.left->data.diadic.left->data.diadic.right->type == EINTCONST - ) - { - val1 = expr->data.diadic.right->data.intval; - if (CInt64_Equal(val1, expr->data.diadic.left->data.diadic.left->data.diadic.right->data.intval)) { - if (nodetype1 == nodetype3) { - expr->data.diadic.left->data.diadic.left = expr->data.diadic.left->data.diadic.left->data.diadic.left; - changed = 1; - } else if (nodetype2 == nodetype3) { - *expr = *expr->data.diadic.right; - changed = 1; - } else { - expr->data.diadic.left = expr->data.diadic.left->data.diadic.right; - changed = 1; - } - } - } - } while (changed); - } -} - -static void TransformExprTree1(ENode *expr) { - ENodeList *list; - - switch (expr->type) { - ENODE_CASE_MONADIC: - TransformExprTree1(expr->data.monadic); - break; - - ENODE_CASE_DIADIC_ALL: - TransformExprTree1(expr->data.diadic.left); - TransformExprTree1(expr->data.diadic.right); - break; - - case EFUNCCALL: - case EFUNCCALLP: - TransformExprTree1(expr->data.funccall.funcref); - for (list = expr->data.funccall.args; list; list = list->next) - TransformExprTree1(list->node); - break; - - case ECOND: - TransformExprTree1(expr->data.cond.cond); - TransformExprTree1(expr->data.cond.expr1); - TransformExprTree1(expr->data.cond.expr2); - break; - - case ENULLCHECK: - TransformExprTree1(expr->data.nullcheck.nullcheckexpr); - TransformExprTree1(expr->data.nullcheck.condexpr); - break; - } - - FoldConstantsinAssociativeExprs(expr); -} - -static int RemoveRedundantBitOperations(ENode *expr) { - Boolean a; - Boolean b; - - if (expr->type == ExprType) { - a = RemoveRedundantBitOperations(expr->data.diadic.left); - b = RemoveRedundantBitOperations(expr->data.diadic.right); - return a & b; - } - - if (expr->type == EINDIRECT) { - if (expr->data.monadic->type == EOBJREF) { - if (!OperandObject) { - OperandObject = expr->data.monadic->data.objref; - IndirectRef = expr; - return 1; - } else { - return expr->data.monadic->data.objref == OperandObject; - } - } else { - return 0; - } - } - - if (expr->type == EINTCONST) { - if (FirstTime) { - OperandConst = expr->data.intval; - FirstTime = 0; - } else if (ExprType == EAND) { - OperandConst = CInt64_And(expr->data.intval, OperandConst); - } else if (ExprType == EOR) { - OperandConst = CInt64_Or(expr->data.intval, OperandConst); - } else if (ExprType == EXOR) { - OperandConst = CInt64_Xor(expr->data.intval, OperandConst); - } - return 1; - } - - return 0; -} - -static void TransformExprTree2(ENode *expr) { - ENodeList *list; - - switch (expr->type) { - ENODE_CASE_MONADIC: - TransformExprTree2(expr->data.monadic); - break; - - ENODE_CASE_DIADIC_ALL: - TransformExprTree2(expr->data.diadic.left); - TransformExprTree2(expr->data.diadic.right); - break; - - case EFUNCCALL: - case EFUNCCALLP: - TransformExprTree2(expr->data.funccall.funcref); - for (list = expr->data.funccall.args; list; list = list->next) - TransformExprTree2(list->node); - break; - - case ECOND: - TransformExprTree2(expr->data.cond.cond); - TransformExprTree2(expr->data.cond.expr1); - TransformExprTree2(expr->data.cond.expr2); - break; - - case ENULLCHECK: - TransformExprTree2(expr->data.nullcheck.nullcheckexpr); - TransformExprTree2(expr->data.nullcheck.condexpr); - break; - } - - if ( - ENODE_IS3(expr, EAND, EOR, EXOR) && - (expr->type == expr->data.diadic.left->type || expr->type == expr->data.diadic.right->type) - ) - { - OperandObject = NULL; - ExprType = expr->type; - FirstTime = 1; - IndirectRef = NULL; - - if (RemoveRedundantBitOperations(expr)) { - expr->data.diadic.left = IndirectRef; - expr->data.diadic.right->type = EINTCONST; - expr->data.diadic.right->data.intval = OperandConst; - } - } -} - -static void PullOutPostOps(Statement *stmt, ENode **pExpr) { - ENode *ind; - ENode *inner; - Statement *newStmt; - - switch ((*pExpr)->type) { - ENODE_CASE_MONADIC: - if ((*pExpr)->type != EFORCELOAD) - PullOutPostOps(stmt, &(*pExpr)->data.monadic); - - if (ENODE_IS2(*pExpr, EPOSTINC, EPOSTDEC)) { - inner = (*pExpr)->data.monadic; - if ( - ENODE_IS(inner, EINDIRECT) && - inner->rtype && - !CParser_IsVolatile(inner->rtype, ENODE_QUALS(inner)) && - ENODE_IS(inner->data.monadic, EOBJREF) && - !is_volatile_object(inner->data.monadic->data.objref) - ) - { - newStmt = lalloc(sizeof(Statement)); - memset(newStmt, 0, sizeof(Statement)); - newStmt->type = ST_EXPRESSION; - newStmt->expr = *pExpr; - newStmt->dobjstack = stmt->dobjstack; - newStmt->sourceoffset = stmt->sourceoffset; - newStmt->sourcefilepath = stmt->sourcefilepath; - newStmt->value = stmt->value; - newStmt->flags = stmt->flags; - newStmt->next = stmt->next; - stmt->next = newStmt; - - ind = IRO_NewENode(EINDIRECT); - *ind = *inner; - ind->data.monadic = IRO_NewENode(EOBJREF); - *ind->data.monadic = *inner->data.monadic; - *pExpr = ind; - } - } - break; - - ENODE_CASE_DIADIC_ALL: - if (ENODE_IS(*pExpr, ECOND)) - break; - if (ENODE_IS(*pExpr, ECOMMA)) - break; - if (ENODE_IS(*pExpr, ELOR)) - break; - if (ENODE_IS(*pExpr, ELAND)) - break; - if (ENODE_IS(*pExpr, ENULLCHECK)) - break; - PullOutPostOps(stmt, &(*pExpr)->data.diadic.left); - PullOutPostOps(stmt, &(*pExpr)->data.diadic.right); - break; - } -} - -void IRO_TransformTree(Statement *statements) { - Statement *stmt; - Statement *next; - - for (stmt = statements; stmt; stmt = next) { - next = stmt->next; - switch (stmt->type) { - case ST_EXPRESSION: - case ST_SWITCH: - case ST_IFGOTO: - case ST_IFNGOTO: - case ST_RETURN: - if (stmt->expr) { - stmt->expr = TransformExprTree(stmt->expr); - TransformExprTree2(stmt->expr); - TransformExprTree1(stmt->expr); - } - break; - } - } - - IRO_CheckForUserBreak(); -} |