diff options
Diffstat (limited to 'compiler_and_linker/unsorted/IroLoop.c')
-rw-r--r-- | compiler_and_linker/unsorted/IroLoop.c | 2324 |
1 files changed, 0 insertions, 2324 deletions
diff --git a/compiler_and_linker/unsorted/IroLoop.c b/compiler_and_linker/unsorted/IroLoop.c deleted file mode 100644 index d6ec5f0..0000000 --- a/compiler_and_linker/unsorted/IroLoop.c +++ /dev/null @@ -1,2324 +0,0 @@ -#include "compiler/IroLoop.h" -#include "compiler/IroCSE.h" -#include "compiler/IroDump.h" -#include "compiler/IroFlowgraph.h" -#include "compiler/IroLinearForm.h" -#include "compiler/IroPropagate.h" -#include "compiler/IroSubable.h" -#include "compiler/IroUtil.h" -#include "compiler/IroVars.h" -#include "compiler/CFunc.h" -#include "compiler/CInt64.h" -#include "compiler/CMachine.h" -#include "compiler/objects.h" -#include "compiler/types.h" - -IRONode *LoopNode; -Boolean ConditionalHeaderAtBottom; -IROLoopInd *FirstInd; -BitVector *InLoop; -IROList IRO_InitLList; -BitVector *InLoop_Exits; -BitVector *InLoop_Tails; -UInt32 LoopExitNumber; -UInt32 LoopTailNum; -IRONode *LoopExitSuccessor; -IRONode *LoopTail; -IROLoopMemRef *IRO_LoopMemRefFirst; -IROLoopMemRef *IRO_LoopMemRefCurrent; -static IROExpr *RisList; -static BitVector *AllKills; -static Boolean KnownBounds; -static SInt32 Times; -static IROLinear *PredInt; -static IROElmList *FirstAddendLinear; -static IROElmList *LastAddendLinear; -static int NoSubableSubs; - -// forward decls -static void MyHandleLoop_Vector(IRONode *fnode); -static void MyHandleLoop_Motion(IRONode *fnode); -static void CheckAllLoopAddresses(IRONode *fnode, BitVector *bv, Boolean *resultFlag); -static void MakeLoopEntry(IROLinear *nd, IROAddrRecord *rec, Boolean mustreach1, Boolean flag2); -static void MoveInvarianceInAddressExpr(void); -static IROLinear *RearrangeInvarianceInAddressExpr(IROLinear *nd, IROList *list); -static UInt32 IsAssignmentReductionCandidate(IROLinear *nd); - -void FindMustReach(void) { - IRONode *fnode; - IRONode *fnode2; - IRONode *pred; - int i; - - for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) { - fnode->mustreach = 0; - if (Bv_IsBitSet(fnode->index, InLoop)) { - fnode->mustreach = 1; - - for (i = 0; i < LoopNode->numpred; i++) { - pred = IRO_NodeTable[LoopNode->pred[i]]; - if (Bv_IsBitSet(pred->index, InLoop) && !Bv_IsBitSet(fnode->index, pred->dom)) { - fnode->mustreach = 0; - break; - } - } - - for (fnode2 = IRO_FirstNode; fnode2; fnode2 = fnode2->nextnode) { - if (Bv_IsBitSet(fnode2->index, InLoop)) { - for (i = 0; i < fnode2->numsucc; i++) { - if (!Bv_IsBitSet(fnode2->succ[i], InLoop) && !Bv_IsBitSet(fnode->index, fnode2->dom)) { - fnode->mustreach = 0; - break; - } - } - - if (!fnode->mustreach) - break; - } - } - } - } -} - -void FindMustReach1(IRONode *checkfnode) { - IRONode *fnode; - IRONode *fnode2; - - for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) { - if (Bv_IsBitSet(fnode->index, InLoop)) { - fnode->mustreach1 = 1; - for (fnode2 = IRO_FirstNode; fnode2; fnode2 = fnode2->nextnode) { - if (Bv_IsBitSet(fnode2->index, InLoop)) { - if (Bv_IsBitSet(fnode2->index, InLoop_Tails) && !Bv_IsBitSet(fnode->index, fnode2->dom)) - fnode->mustreach1 = 0; - - if (Bv_IsBitSet(fnode2->index, InLoop_Exits) && fnode2 != checkfnode && !Bv_IsBitSet(fnode->index, fnode2->dom)) - fnode->mustreach1 = 0; - - if (!fnode->mustreach1) - break; - } - } - } - } -} - -static void IRO_FindLoopTailsAndExits(IRONode *fnode) { - IRONode *scan; - IRONode *succ; - int i; - - for (scan = IRO_FirstNode; scan; scan = scan->nextnode) { - if (Bv_IsBitSet(scan->index, InLoop)) { - for (i = 0; i < scan->numsucc; i++) { - succ = IRO_NodeTable[scan->succ[i]]; - if (succ == fnode) { - Bv_SetBit(scan->index, InLoop_Tails); - LoopTail = scan; - LoopTailNum++; - } - if (!Bv_IsBitSet(succ->index, InLoop)) { - LoopExitNumber++; - LoopExitSuccessor = succ; - Bv_SetBit(scan->index, InLoop_Exits); - } - } - } - } - - IRO_Dump("IRO_FindLoopTailsAndExits:For header %d, Loop exits and loop tails are \n", fnode->index); - IRO_DumpBits("Loop Exits: ", InLoop_Exits); - IRO_DumpBits("Loop Tails: ", InLoop_Tails); - IRO_Dump("LoopExitNum=%d: \n", LoopExitNumber); - if (LoopExitSuccessor) - IRO_Dump("LoopExitSuccessor node =%d: \n", LoopExitSuccessor->index); -} - -static int IsSafeTypcon(IROLinear *nd) { - Type *srcType; - Type *destType; - SInt32 srcSize; - SInt32 destSize; - Boolean srcUnsigned; - Boolean destUnsigned; - - srcType = nd->u.monadic->rtype; - destType = nd->rtype; - if (!IS_TYPE_INT(srcType) || !IS_TYPE_INT(destType)) - return 0; - - srcSize = srcType->size; - destSize = destType->size; - srcUnsigned = IRO_IsUnsignedType(srcType); - destUnsigned = IRO_IsUnsignedType(destType); - - if (srcUnsigned == destUnsigned && destSize >= srcSize) - return 1; - if (srcUnsigned == 1 && destUnsigned == 0 && destSize > srcSize) - return 1; - return 0; -} - -static int Reducable(IROLinear *nd, IROLinear **resultNd1, IROLinear **resultNd2, VarRecord **resultVar) { - IROLinear *indirect; - IROLinear *left; - IROLinear *right; - Boolean leftInvariant; - Boolean rightInvariant; - Boolean leftTypcon; - Boolean rightTypcon; - Object *obj; - ENode *enode; - IROLoopInd *ind; - CInt64 val64; - SInt32 val; - SInt32 div; - - leftInvariant = 0; - rightInvariant = 0; - leftTypcon = 0; - rightTypcon = 0; - - if (nd->type == IROLinearOp2Arg && nd->nodetype == EADD && (IS_TYPE_INT(nd->rtype) || IS_TYPE_POINTER_ONLY(nd->rtype))) { - left = nd->u.diadic.left; - right = nd->u.diadic.right; - if (left->type == IROLinearOp1Arg && left->nodetype == ETYPCON) { - leftTypcon = 1; - leftInvariant = (left->flags & IROLF_LoopInvariant) != 0; - left = left->u.monadic; - } - if (right->type == IROLinearOp1Arg && right->nodetype == ETYPCON) { - rightTypcon = 1; - rightInvariant = (right->flags & IROLF_LoopInvariant) != 0; - right = right->u.monadic; - } - - if (((left->flags & IROLF_LoopInvariant) || leftInvariant) && IRO_IsVariable(right)) { - if (leftInvariant || ((!(obj = IRO_IsVariable(left)) || !IRO_IsRegable(obj)) && !IRO_IsConstant(left))) { - if ( - left->type == IROLinearOp2Arg && - left->nodetype == EADD && - (obj = IRO_IsVariable(left->u.diadic.left)) && - IRO_IsRegable(obj) && - IRO_IsConstant(left->u.diadic.right) - ) - return 0; - - if (rightTypcon) { - if (!IsSafeTypcon(nd->u.diadic.right)) - return 0; - *resultNd2 = nd->u.diadic.right; - } else { - *resultNd2 = right; - } - - indirect = right; - *resultNd1 = IRO_NewLinear(IROLinearOperand); - - enode = IRO_NewENode(EINTCONST); - enode->data.intval = cint64_one; - enode->rtype = nd->u.diadic.right->rtype; - (*resultNd1)->rtype = nd->u.diadic.right->rtype; - (*resultNd1)->u.node = enode; - } else { - return 0; - } - } else if ( - ((left->flags & IROLF_LoopInvariant) || leftInvariant) && - right->type == IROLinearOp2Arg && - !rightTypcon && - (right->nodetype == EMUL || right->nodetype == ESHL) - ) { - if (IRO_IsConstant(right->u.diadic.right)) { - if (right->nodetype == ESHL) { - right->nodetype = EMUL; - right->u.diadic.right->u.node->data.intval = CInt64_Shl(cint64_one, right->u.diadic.right->u.node->data.intval); - } - if (right->u.diadic.left->type == IROLinearOp1Arg) { - if (IRO_IsVariable(right->u.diadic.left)) { - *resultNd2 = right->u.diadic.left; - indirect = right->u.diadic.left; - *resultNd1 = right->u.diadic.right; - } else if (right->u.diadic.left->nodetype == ETYPCON && IRO_IsVariable(right->u.diadic.left->u.monadic)) { - if (!IsSafeTypcon(right->u.diadic.left)) - return 0; - *resultNd2 = right->u.diadic.left; - indirect = right->u.diadic.left->u.monadic; - *resultNd1 = right->u.diadic.right; - } else { - return 0; - } - } else { - return 0; - } - } else { - return 0; - } - } else if ( - ((right->flags & IROLF_LoopInvariant) || rightInvariant) && - left->type == IROLinearOp2Arg && - !leftTypcon && - (left->nodetype == EMUL || left->nodetype == ESHL) - ) { - if (IRO_IsConstant(left->u.diadic.right)) { - if (left->nodetype == ESHL) { - left->nodetype = EMUL; - left->u.diadic.right->u.node->data.intval = CInt64_Shl(cint64_one, left->u.diadic.right->u.node->data.intval); - } - if (left->u.diadic.left->type == IROLinearOp1Arg) { - if (IRO_IsVariable(left->u.diadic.left)) { - *resultNd2 = left->u.diadic.left; - indirect = left->u.diadic.left; - *resultNd1 = left->u.diadic.right; - } else if (left->u.diadic.left->nodetype == ETYPCON && IRO_IsVariable(left->u.diadic.left->u.monadic)) { - if (!IsSafeTypcon(left->u.diadic.left)) - return 0; - *resultNd2 = left->u.diadic.left; - indirect = left->u.diadic.left->u.monadic; - *resultNd1 = left->u.diadic.right; - } else { - return 0; - } - } else { - return 0; - } - } else { - return 0; - } - } else if ( - ((right->flags & IROLF_LoopInvariant) || rightInvariant) && - IRO_IsVariable(left) - ) { - if (rightInvariant || ((!(obj = IRO_IsVariable(right)) || !IRO_IsRegable(obj)) && !IRO_IsConstant(right))) { - if ( - right->type == IROLinearOp2Arg && - right->nodetype == EADD && - (obj = IRO_IsVariable(right->u.diadic.left)) && - IRO_IsRegable(obj) && - IRO_IsConstant(right->u.diadic.right) - ) - return 0; - - if (leftTypcon) { - if (!IsSafeTypcon(nd->u.diadic.left)) - return 0; - *resultNd2 = nd->u.diadic.left; - } else { - *resultNd2 = left; - } - - indirect = left; - *resultNd1 = IRO_NewLinear(IROLinearOperand); - - enode = IRO_NewENode(EINTCONST); - enode->data.intval = cint64_one; - enode->rtype = nd->u.diadic.left->rtype; - (*resultNd1)->rtype = nd->u.diadic.left->rtype; - (*resultNd1)->u.node = enode; - } else { - return 0; - } - } else { - return 0; - } - } else if (nd->type == IROLinearOp2Arg && (nd->nodetype == EMUL || nd->nodetype == ESHL) && nd->rtype->size <= 4 && (IS_TYPE_INT(nd->rtype) || IS_TYPE_POINTER_ONLY(nd->rtype))) { - left = nd->u.diadic.left; - right = nd->u.diadic.right; - - if (IRO_IsConstant(right) && IRO_IsVariable(left)) { - *resultNd2 = left; - indirect = left; - *resultNd1 = right; - } else if (IRO_IsConstant(nd->u.diadic.right) && left->type == IROLinearOp1Arg && left->nodetype == ETYPCON && - IRO_IsVariable(left->u.monadic)) { - if (!IsSafeTypcon(left)) - return 0; - *resultNd2 = left; - indirect = left->u.monadic; - *resultNd1 = right; - } else { - if (nd->type == IROLinearOp2Arg && nd->nodetype == ESHL) - return 0; - - if (nd->u.diadic.right->flags & IROLF_LoopInvariant) { - if (IRO_IsVariable(left)) { - *resultNd2 = left; - indirect = left; - *resultNd1 = right; - } else if (left->type == IROLinearOp1Arg && left->nodetype == ETYPCON && IRO_IsVariable(left->u.monadic)) { - if (!IsSafeTypcon(left)) - return 0; - *resultNd2 = left; - indirect = left->u.monadic; - *resultNd1 = right; - } else { - return 0; - } - } else if (nd->u.diadic.left->flags & IROLF_LoopInvariant) { - if (IRO_IsVariable(right)) { - *resultNd2 = right; - indirect = right; - *resultNd1 = left; - } else if (right->type == IROLinearOp1Arg && right->nodetype == ETYPCON && IRO_IsVariable(right->u.monadic) && nd->type == IROLinearOp2Arg && nd->nodetype == EMUL) { - if (!IsSafeTypcon(right)) - return 0; - *resultNd2 = right; - indirect = right->u.monadic; - *resultNd1 = left; - } else { - return 0; - } - } else { - return 0; - } - } - } else if (nd->type == IROLinearOp2Arg && (nd->nodetype == EDIV || nd->nodetype == ESHR) && nd->rtype->size <= 4 && IS_TYPE_INT(nd->rtype)) { - if (IRO_IsVariable(nd->u.diadic.left) && IRO_IsConstant(nd->u.diadic.right)) { - val64 = nd->u.diadic.right->u.node->data.intval; - if (nd->type == IROLinearOp2Arg && nd->nodetype == ESHR) { - CInt64_GetULong(&val64); - if (CInt64_GetULong(&val64) > 32 || CTool_EndianReadWord32(&val64.hi)) - return 0; - val64 = CInt64_Shl(cint64_one, val64); - } - *resultNd2 = nd->u.diadic.left; - indirect = nd->u.diadic.left; - } else { - return 0; - } - } else { - return 0; - } - - if ( - nd->type == IROLinearOp2Arg && - nd->nodetype == ESHL && - ( - !IRO_IsConstant(*resultNd1) || - (SInt32) CInt64_GetULong(&(*resultNd1)->u.node->data.intval) < 0 || - (SInt32) CInt64_GetULong(&(*resultNd1)->u.node->data.intval) > 32 || - CTool_EndianReadWord32(&(*resultNd1)->u.node->data.intval.hi) - ) - ) - return 0; - - CError_ASSERT(802, indirect->u.monadic->u.node != NULL); - *resultVar = IRO_FindVar(indirect->u.monadic->u.node->data.objref, 0, 1); - if (!*resultVar || (*resultVar)->xA != 2) - return 0; - - if (copts.ANSIstrict || copts.strengthreductionstrict) { - Type *type = (*resultVar)->object->type; - if (IRO_IsUnsignedType(type) && type->size < stunsignedlong.size) - return 0; - } - - if (nd->type == IROLinearOp2Arg && (nd->nodetype == ESHR || nd->nodetype == EDIV)) { - ind = FirstInd; - while (ind && ind->var != *resultVar) - ind = ind->next; - - CError_ASSERT(845, ind != NULL); - - if (ind->addNode == NULL) { - if (ind->addConst < (val = CInt64_GetULong(&val64))) - return 0; - if ((div = ind->addConst / val) <= 0) - return 0; - - *resultNd1 = IRO_NewLinear(IROLinearOperand); - enode = IRO_NewENode(EINTCONST); - CInt64_SetULong(&enode->data.intval, div); - enode->rtype = nd->u.diadic.left->rtype; - (*resultNd1)->rtype = nd->u.diadic.left->rtype; - (*resultNd1)->u.node = enode; - } else { - return 0; - } - } - - return 1; -} - -static void IRO_RemoveExpr_Action(IROLinear *linear, Boolean isFirst) { - if (isFirst && linear->expr) - IRO_RemoveExpr(linear->expr); -} - -static void IRO_ActUnmarkRISCandidate(IROLinear *linear, Boolean isFirst) { - if (isFirst && linear->expr) - linear->flags &= ~IROLF_Ris; -} - -static IROExpr *CreateRIS(IROExpr *expr, IROLinear *nd1, IROLinear *nd2, IROLoopInd *induction, int unk) { - Object *tempObj; - Type *type; - Boolean flag23; - Object *tempObj2; - IROLinear *firstnode; - IROLinear *fourthnode; - IROLinear *fifthnode; - IROLinear *secondnode; - IROLinear *thirdnode; - IROLinear *tmp; - ENode *enode; - IROList list1; - IROList list2; - - flag23 = 0; - type = expr->linear->rtype; - tempObj = create_temp_object(type); - IRO_FindVar(tempObj, 1, 1); - IRO_InitList(&list1); - - if (IS_LINEAR_DIADIC(expr->linear, EADD)) { - firstnode = IRO_DuplicateExpr(expr->linear, &list1); - } else if (IS_LINEAR_DIADIC_2(expr->linear, EDIV, ESHR)) { - firstnode = IRO_DuplicateExpr(expr->linear, &list1); - } else { - firstnode = IRO_NewLinear(IROLinearOp2Arg); - firstnode->index = ++IRO_NumLinear; - firstnode->rtype = type; - firstnode->nodetype = EMUL; - firstnode->u.diadic.left = IRO_DuplicateExpr(nd1, &list1); - if (unk) - firstnode->u.diadic.right = IRO_DuplicateExpr(nd1, &list1); - else - firstnode->u.diadic.right = IRO_DuplicateExpr(nd2, &list1); - IRO_AddToList(firstnode, &list1); - } - - secondnode = IRO_NewLinear(IROLinearOp2Arg); - secondnode->index = ++IRO_NumLinear; - secondnode->rtype = type; - secondnode->nodetype = EASS; - secondnode->u.diadic.left = IRO_TempReference(tempObj, &list1); - secondnode->u.diadic.left->flags |= IROLF_Ind | IROLF_Assigned; - secondnode->u.diadic.left->u.monadic->flags |= IROLF_Ind | IROLF_Assigned; - secondnode->u.diadic.right = firstnode; - IRO_AddToList(secondnode, &list1); - IRO_Paste(list1.head, list1.tail, PredInt); - if ( - !IS_LINEAR_DIADIC_2(expr->linear, EDIV, ESHR) && - induction->addConst != 1 && - (induction->addNode || !IRO_IsConstant(nd2)) - ) { - flag23 = 1; - IRO_InitList(&list1); - thirdnode = IRO_NewLinear(IROLinearOp2Arg); - thirdnode->index = ++IRO_NumLinear; - thirdnode->rtype = nd2->rtype; - thirdnode->nodetype = EMUL; - - if (!induction->addNode) { - thirdnode->u.diadic.left = IRO_DuplicateExpr(nd2, &list1); - thirdnode->u.diadic.right = IRO_NewLinear(IROLinearOperand); - thirdnode->u.diadic.right->index = ++IRO_NumLinear; - enode = IRO_NewENode(EINTCONST); - enode->rtype = nd2->rtype; - thirdnode->u.diadic.right->rtype = nd2->rtype; - CInt64_SetLong(&enode->data.intval, induction->addConst); - thirdnode->u.diadic.right->u.node = enode; - IRO_AddToList(thirdnode->u.diadic.right, &list1); - } else { - thirdnode->u.diadic.left = IRO_DuplicateExpr(nd2, &list1); - thirdnode->u.diadic.right = IRO_DuplicateExpr(induction->addNode, &list1); - if (nd2->rtype != induction->addNode->rtype) { - tmp = IRO_NewLinear(IROLinearOp1Arg); - tmp->nodetype = ETYPCON; - tmp->index = ++IRO_NumLinear; - tmp->rtype = nd2->rtype; - tmp->u.monadic = thirdnode->u.diadic.right; - IRO_AddToList(tmp, &list1); - thirdnode->u.diadic.right = tmp; - } - } - IRO_AddToList(thirdnode, &list1); - - tempObj2 = create_temp_object(nd2->rtype); - - fourthnode = IRO_NewLinear(IROLinearOp2Arg); - fourthnode->index = ++IRO_NumLinear; - fourthnode->rtype = nd2->rtype; - fourthnode->nodetype = EASS; - fourthnode->u.diadic.left = IRO_TempReference(tempObj2, &list1); - fourthnode->u.diadic.left->flags |= IROLF_Ind | IROLF_Assigned; - fourthnode->u.diadic.left->u.monadic->flags |= IROLF_Ind | IROLF_Assigned; - fourthnode->u.diadic.right = thirdnode; - IRO_AddToList(fourthnode, &list1); - IRO_Paste(list1.head, list1.tail, PredInt); - } - - IRO_InitList(&list2); - fifthnode = IRO_NewLinear(IROLinearOp2Arg); - fifthnode->index = ++IRO_NumLinear; - fifthnode->rtype = type; - if (induction->nd->type == IROLinearOp2Arg) { - if (induction->nd->nodetype == EASS && IS_LINEAR_DIADIC(induction->nd->u.diadic.right, EADD)) - fifthnode->nodetype = EADDASS; - else if (induction->nd->nodetype == EASS && IS_LINEAR_DIADIC(induction->nd->u.diadic.right, ESUB)) - fifthnode->nodetype = ESUBASS; - else - fifthnode->nodetype = induction->nd->nodetype; - } else { - if (induction->nd->nodetype == EPREINC || induction->nd->nodetype == EPOSTINC) - fifthnode->nodetype = EADDASS; - else - fifthnode->nodetype = ESUBASS; - } - - fifthnode->u.diadic.left = IRO_TempReference(tempObj, &list2); - fifthnode->u.diadic.left->flags |= IROLF_Ind | IROLF_Used | IROLF_Assigned; - fifthnode->u.diadic.left->u.monadic->flags |= IROLF_Ind | IROLF_Used | IROLF_Assigned; - if (!unk) { - if (!flag23) { - if (induction->addConst == 1 || IS_LINEAR_DIADIC_2(expr->linear, EDIV, ESHR)) { - fifthnode->u.diadic.right = IRO_DuplicateExpr(nd2, &list2); - } else { - fifthnode->u.diadic.right = IRO_NewLinear(IROLinearOperand); - fifthnode->u.diadic.right->index = ++IRO_NumLinear; - enode = IRO_NewENode(EINTCONST); - enode->rtype = nd2->rtype; - fifthnode->u.diadic.right->rtype = nd2->rtype; - CInt64_SetLong(&enode->data.intval, induction->addConst * CInt64_GetULong(&nd2->u.node->data.intval)); - fifthnode->u.diadic.right->u.node = enode; - IRO_AddToList(fifthnode->u.diadic.right, &list2); - } - } else { - fifthnode->u.diadic.right = IRO_TempReference(tempObj2, &list2); - fifthnode->u.diadic.right->flags |= IROLF_Used; - } - } - - fifthnode->index = ++IRO_NumLinear; - IRO_AddToList(fifthnode, &list2); - IRO_Paste(list2.head, list2.tail, IRO_FindStart(induction->nd)); - IRO_WalkTree(expr->linear, IRO_RemoveExpr_Action); - expr->x8 = tempObj; - expr->next = RisList; - RisList = expr; - return expr; -} - -static IRONode *CreatePreHeader(IRONode *fnode1, IRONode *fnode2) { - IROLinear *labelnode; - IRONode *newfnode; - IRONode *iter; - CLabel *oldlabel; - CLabel *newlabel; - SwitchInfo *swinfo; - SwitchCase *swcase; - - newfnode = oalloc(sizeof(IRONode)); - memset(newfnode, 0, sizeof(IRONode)); - newfnode->index = IRO_NumNodes; - IRO_NumNodes++; - - labelnode = IRO_NewLinear(IROLinearLabel); - labelnode->index = IRO_NumLinear++; - labelnode->next = NULL; - labelnode->u.label.label = IRO_NewLabel(); - labelnode->flags |= IROLF_1; - labelnode->u.label.label->stmt = (Statement *) newfnode; - newfnode->first = labelnode; - newfnode->last = labelnode; - - if (fnode2) { - fnode2->last->next = labelnode; - labelnode->next = IRO_NewLinear(IROLinearNop); - labelnode->next->next = fnode1->first; - fnode2->nextnode = newfnode; - newfnode->nextnode = fnode1; - } else { - CError_ASSERT(1254, fnode1->first->type == IROLinearLabel); - labelnode->next = IRO_NewLinear(IROLinearGoto); - labelnode->next->u.label.label = fnode1->first->u.label.label; - IRO_LastNode->last->next = labelnode; - IRO_LastNode->nextnode = newfnode; - IRO_LastNode = newfnode; - IRO_LastLinear = labelnode->next; - } - - newfnode->last = labelnode->next; - - IRO_NodeTable = oalloc(sizeof(IRONode *) * IRO_NumNodes); - memset(IRO_NodeTable, 0, sizeof(IRONode *) * IRO_NumNodes); - for (iter = IRO_FirstNode; iter; iter = iter->nextnode) - IRO_NodeTable[iter->index] = iter; - - if (fnode1->first->type == IROLinearLabel) { - oldlabel = fnode1->first->u.label.label; - newlabel = newfnode->first->u.label.label; - for (iter = IRO_FirstNode; iter; iter = iter->nextnode) { - if (!Bv_IsBitSet(iter->index, InLoop) && iter != newfnode) { - switch (iter->last->type) { - case IROLinearGoto: - if (iter->last->u.label.label == oldlabel) - iter->last->u.label.label = newlabel; - break; - case IROLinearIf: - case IROLinearIfNot: - if (iter->last->u.label.label == oldlabel) - iter->last->u.label.label = newlabel; - break; - case IROLinearSwitch: - swinfo = iter->last->u.swtch.info; - for (swcase = swinfo->cases; swcase; swcase = swcase->next) { - if (swcase->label == oldlabel) - swcase->label = newlabel; - } - if (swinfo->defaultlabel == oldlabel) - swinfo->defaultlabel = newlabel; - break; - } - } - } - } - - IRO_ComputeSuccPred(); - IRO_ComputeDom(); - return newfnode; -} - -static IRONode *CreateNewLoopExitSuccessor(IRONode *fnode1) { - IROLinear *labelnode; - IRONode *fnode2; - IRONode *newfnode; - Boolean flag; - IRONode *iter; - CLabel *oldlabel; - CLabel *newlabel; - SwitchInfo *swinfo; - SwitchCase *swcase; - UInt16 i; - - CError_ASSERT(1355, fnode1 != NULL && LoopExitNumber == 1); - - fnode2 = NULL; - flag = 0; - - for (i = 0; i < fnode1->numpred; i++) { - iter = IRO_NodeTable[fnode1->pred[i]]; - if (Bv_IsBitSet(iter->index, InLoop_Exits)) { - CError_ASSERT(1366, fnode2 == NULL); - fnode2 = iter; - if (!flag) { - if ( - !iter->last || - !fnode1->first || - fnode1->first->type != IROLinearLabel || - ( - (iter->last->type == IROLinearIf || iter->last->type == IROLinearIfNot) && - iter->last->u.label.label != fnode1->first->u.label.label - )) - flag = 1; - } - } - } - - CError_ASSERT(1382, fnode2 != NULL); - - newfnode = oalloc(sizeof(IRONode)); - memset(newfnode, 0, sizeof(IRONode)); - newfnode->index = IRO_NumNodes; - IRO_NumNodes++; - - labelnode = IRO_NewLinear(IROLinearLabel); - labelnode->index = IRO_NumLinear++; - labelnode->next = NULL; - labelnode->u.label.label = IRO_NewLabel(); - labelnode->flags |= IROLF_1; - labelnode->u.label.label->stmt = (Statement *) newfnode; - newfnode->first = labelnode; - newfnode->last = labelnode; - - if (flag) { - fnode2->last->next = labelnode; - labelnode->next = IRO_NewLinear(IROLinearNop); - labelnode->next->next = fnode1->first; - fnode2->nextnode = newfnode; - newfnode->nextnode = fnode1; - } else { - CError_ASSERT(1422, fnode1->first->type == IROLinearLabel); - labelnode->next = IRO_NewLinear(IROLinearGoto); - labelnode->next->u.label.label = fnode1->first->u.label.label; - IRO_LastNode->last->next = labelnode; - IRO_LastNode->nextnode = newfnode; - IRO_LastNode = newfnode; - IRO_LastLinear = labelnode->next; - } - - newfnode->last = labelnode->next; - - IRO_NodeTable = oalloc(sizeof(IRONode *) * IRO_NumNodes); - memset(IRO_NodeTable, 0, sizeof(IRONode *) * IRO_NumNodes); - for (iter = IRO_FirstNode; iter; iter = iter->nextnode) - IRO_NodeTable[iter->index] = iter; - - if (fnode1->first->type == IROLinearLabel) { - oldlabel = fnode1->first->u.label.label; - newlabel = newfnode->first->u.label.label; - switch (fnode2->last->type) { - case IROLinearGoto: - if (fnode2->last->u.label.label == oldlabel) - fnode2->last->u.label.label = newlabel; - break; - case IROLinearIf: - case IROLinearIfNot: - if (fnode2->last->u.label.label == oldlabel) - fnode2->last->u.label.label = newlabel; - break; - case IROLinearSwitch: - swinfo = fnode2->last->u.swtch.info; - for (swcase = swinfo->cases; swcase; swcase = swcase->next) { - if (swcase->label == oldlabel) - swcase->label = newlabel; - } - if (swinfo->defaultlabel == oldlabel) - swinfo->defaultlabel = newlabel; - break; - } - } - - IRO_ComputeSuccPred(); - IRO_ComputeDom(); - return newfnode; -} - -void AddPreds(IRONode *fnode) { - IRONode *pred; - int i; - - for (i = 0; i < fnode->numpred; i++) { - pred = IRO_NodeTable[fnode->pred[i]]; - if (!Bv_IsBitSet(pred->index, InLoop)) { - Bv_SetBit(pred->index, InLoop); - AddPreds(pred); - } - } -} - -static void RemoveNoopsFromExprList(void) { - IROExpr *expr; - IROExpr *prev; - - expr = IRO_FirstExpr; - prev = NULL; - while (expr) { - if (expr->linear->type == IROLinearNop) { - if (prev) - prev->next = expr->next; - else - IRO_FirstExpr = expr->next; - expr = expr->next; - } else { - prev = expr; - expr = expr->next; - } - } -} - -void IncLoopDepth(void) { - IRONode *fnode; - - for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) { - if (Bv_IsBitSet(fnode->index, InLoop)) - fnode->loopdepth++; - } -} - -void IRO_SetLoopDepth(void) { - IRONode *fnode; - IRONode *pred; - UInt16 i; - UInt16 flag; - - for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) - fnode->loopdepth = 0; - - for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) { - flag = 0; - - for (i = 0; i < fnode->numpred; i++) { - pred = IRO_NodeTable[fnode->pred[i]]; - if (Bv_IsBitSet(fnode->index, pred->dom)) { - if (!flag) { - Bv_AllocVector(&InLoop, IRO_NumNodes + 1); - Bv_Clear(InLoop); - Bv_SetBit(fnode->index, InLoop); - } - flag = 1; - Bv_SetBit(pred->index, InLoop); - if (pred != fnode) - AddPreds(pred); - } - } - - if (flag) - IncLoopDepth(); - } - - IRO_CheckForUserBreak(); -} - -static void InsertBranchAroundLoopPreheaders(void) { - IRONode *fnode; - CLabel *label; - IRONode *iter; - IROLinear *endnode; - IROLinear *labelnode; - - if (IRO_EndNode && IRO_EndNode->last && IRO_EndNode->last->type == IROLinearEnd) { - label = IRO_NewLabel(); - fnode = IRO_NewFlowGraphNode(); - IRO_LastNode->nextnode = fnode; - label->stmt = (Statement *) fnode; - - IRO_NodeTable = oalloc(sizeof(IRONode *) * IRO_NumNodes); - memset(IRO_NodeTable, 0, sizeof(IRONode *) * IRO_NumNodes); - for (iter = IRO_FirstNode; iter; iter = iter->nextnode) - IRO_NodeTable[iter->index] = iter; - - labelnode = IRO_NewLinear(IROLinearLabel); - labelnode->index = ++IRO_NumLinear; - labelnode->u.label.label = label; - labelnode->flags |= IROLF_1; - fnode->first = labelnode; - IRO_LastLinear->next = labelnode; - - endnode = IRO_NewLinear(IROLinearEnd); - memcpy(endnode, IRO_EndNode->last, sizeof(IROLinear)); - endnode->index = ++IRO_NumLinear; - endnode->next = NULL; - fnode->last = endnode; - labelnode->next = endnode; - IRO_LastLinear = endnode; - - IRO_EndNode->last->type = IROLinearGoto; - IRO_EndNode->last->u.label.label = label; - IRO_LastNode = fnode; - IRO_EndNode = fnode; - - IRO_ComputeSuccPred(); - IRO_ComputeDom(); - } -} - -void IRO_FindLoops(void) { - IRONode *fnode; - IRONode *pred; - UInt16 i; - UInt16 flag; - - for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) { - flag = 0; - - for (i = 0; i < fnode->numpred; i++) { - pred = IRO_NodeTable[fnode->pred[i]]; - if (Bv_IsBitSet(fnode->index, pred->dom)) { - if (!flag) { - Bv_AllocVector(&InLoop, IRO_NumNodes + 1); - Bv_Clear(InLoop); - Bv_SetBit(fnode->index, InLoop); - } - flag = 1; - Bv_SetBit(pred->index, InLoop); - if (pred != fnode) - AddPreds(pred); - } - } - - if (flag) { - IncLoopDepth(); - IRO_Dump("IRO_FindLoops:Found loop with header %d\n", fnode->index); - IRO_DumpBits("Loop includes: ", InLoop); - MyHandleLoop_Motion(fnode); - IRO_UpdateFlagsOnInts(); - MyHandleLoop_Vector(fnode); - RemoveNoopsFromExprList(); - IRO_UpdateFlagsOnInts(); - IRO_UpdateVars(); - } - } - - if (!IRO_FunctionHasReturn && IRO_EndNode != IRO_LastNode) - InsertBranchAroundLoopPreheaders(); -} - -static void CheckSubableSub(IROLinear *linear, Boolean isFirst) { - if (isFirst && IRO_IsSubableExpression(linear)) { - IRO_Dump("Subable Expression is %d\n", linear->index); - NoSubableSubs = 0; - } -} - -static int NoSubableSubExprs(IROLinear *nd) { - NoSubableSubs = 1; - IRO_WalkTree(nd, CheckSubableSub); - return NoSubableSubs; -} - -void ComputeLoopKills(void) { - IRONode *fnode; - IROLinear *nd; - - Bv_AllocVector(&AllKills, IRO_NumVars + 1); - Bv_AllocVector(&IRO_VarKills, IRO_NumVars + 1); - - for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) { - if (Bv_IsBitSet(fnode->index, InLoop) && (nd = fnode->first)) { - Bv_AllocVector(&fnode->x16, IRO_NumVars + 1); - Bv_AllocVector(&fnode->x1E, IRO_NumVars + 1); - while (1) { - Bv_Clear(IRO_VarKills); - IRO_GetKills(nd); - Bv_Or(IRO_VarKills, AllKills); - if (nd == fnode->last) - break; - nd = nd->next; - } - } - } -} - -void ComputeLoopInvariance(void) { - IRONode *fnode; - IROLinear *nd; - - IRO_Depends = IRO_VarKills; - - for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) { - if (Bv_IsBitSet(fnode->index, InLoop) && (nd = fnode->first)) { - nd->flags &= ~IROLF_LoopInvariant; - while (1) { - if ((nd->flags & IROLF_Reffed) && nd->type != IROLinearNop) { - IRO_FindDepends_NoAlloc(nd); - if (!IRO_IsVolatile && !Bv_BitsInCommon(IRO_Depends, AllKills)) - nd->flags |= IROLF_LoopInvariant; - - if (IRO_CouldError) - nd->flags |= IROLF_CouldError; - else - nd->flags &= ~IROLF_CouldError; - } - - if (nd == fnode->last) - break; - nd = nd->next; - } - } - } -} - -void ComputeLoopInduction(void) { - IRONode *fnode; - IROLinear *nd; - Boolean flag; - Object *obj; - Object *obj2; - Object *obj3; - VarRecord *var; - IROLinear *tmpnd; - IROLoopInd *ind; - Boolean isUnsigned; - - Bv_AllocVector(&AllKills, IRO_NumVars + 1); - Bv_AllocVector(&IRO_VarKills, IRO_NumVars + 1); - - for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) { - if (Bv_IsBitSet(fnode->index, InLoop) && (nd = fnode->first)) { - while (1) { - Bv_Clear(IRO_VarKills); - IRO_GetKills(nd); - Bv_Or(IRO_VarKills, AllKills); - flag = 0; - if ( - ( - nd->type == IROLinearOp2Arg && - nd->rtype->size <= 4 && - (nd->nodetype == EADDASS || nd->nodetype == ESUBASS) && - (obj = IRO_IsVariable(nd->u.diadic.left)) && - obj->type->size == nd->rtype->size && - IS_TYPE_INT(obj->type) && - ( - (IRO_IsIntConstant(nd->u.diadic.right) && CInt64_GetULong(&nd->u.diadic.right->u.node->data.intval)) - || - (nd->u.diadic.right->flags & IROLF_LoopInvariant) - ) - ) - || - ( - nd->type == IROLinearOp1Arg && - nd->rtype->size <= 4 && - (nd->nodetype == EPOSTINC || nd->nodetype == EPOSTDEC || nd->nodetype == EPREINC || nd->nodetype == EPREDEC) && - (obj = IRO_IsVariable(nd->u.monadic)) && - obj->type->size == nd->rtype->size && - IS_TYPE_INT(obj->type) - ) - ) - { - flag = 1; - } - else if ( - nd->type == IROLinearOp2Arg && - nd->rtype->size <= 4 && - nd->nodetype == EASS && - (obj = IRO_IsVariable(nd->u.diadic.left)) && - obj->type->size == nd->rtype->size && - IS_TYPE_INT(obj->type) && - nd->u.diadic.right->type == IROLinearOp2Arg && - (nd->u.diadic.right->nodetype == EADD || nd->u.diadic.right->nodetype == ESUB) - ) - { - if (nd->u.diadic.right->nodetype == EADD) { - obj2 = IRO_IsVariable(nd->u.diadic.right->u.diadic.left); - obj3 = IRO_IsVariable(nd->u.diadic.right->u.diadic.right); - if (obj2 == obj && obj3 != obj && (nd->u.diadic.right->u.diadic.right->flags & IROLF_LoopInvariant)) - flag = 1; - - if (obj3 == obj && obj2 != obj && (nd->u.diadic.right->u.diadic.left->flags & IROLF_LoopInvariant)) { - flag = 1; - tmpnd = nd->u.diadic.right->u.diadic.left; - nd->u.diadic.right->u.diadic.left = nd->u.diadic.right->u.diadic.right; - nd->u.diadic.right->u.diadic.right = tmpnd; - } - } else { - obj2 = IRO_IsVariable(nd->u.diadic.right->u.diadic.left); - obj3 = IRO_IsVariable(nd->u.diadic.right->u.diadic.right); - if (obj2 == obj && obj3 != obj && (nd->u.diadic.right->u.diadic.right->flags & IROLF_LoopInvariant)) - flag = 1; - } - } - - if (flag) { - if ((var = IRO_FindAssigned(nd))) { - if (var->xA == 2) - var->xA = 0; - else if (var->xA == 1) - var->xA = 2; - } - } else { - for (var = IRO_FirstVar; var; var = var->next) { - if (Bv_IsBitSet(var->index, IRO_VarKills)) - var->xA = 0; - } - } - - if (nd == fnode->last) - break; - nd = nd->next; - } - } - } - - IRO_DumpBits("Killed in loop: ", AllKills); - - for (fnode = IRO_FirstNode, FirstInd = NULL; fnode; fnode = fnode->nextnode) { - if (Bv_IsBitSet(fnode->index, InLoop) && (nd = fnode->first)) { - while (1) { - if ( - ( - nd->type == IROLinearOp2Arg && - (nd->nodetype == EADDASS || nd->nodetype == ESUBASS || nd->nodetype == EASS) - ) - || - ( - nd->type == IROLinearOp1Arg && - (nd->nodetype == EPOSTINC || nd->nodetype == EPOSTDEC || nd->nodetype == EPREINC || nd->nodetype == EPREDEC) - ) - ) { - if ((var = IRO_FindAssigned(nd)) && var->xA == 2 && var->object->type->size <= 4) { - ind = oalloc(sizeof(IROLoopInd)); - ind->fnode = fnode; - ind->var = var; - ind->nd = nd; - ind->next = FirstInd; - ind->addNode = NULL; - ind->addConst = 0; - ind->flags = 0; - - if (nd->type == IROLinearOp2Arg) { - isUnsigned = IRO_IsUnsignedType(nd->rtype); - if (IRO_IsIntConstant(nd->u.diadic.right)) { - CInt64 val = nd->u.diadic.right->u.node->data.intval; - if (IS_LINEAR_DIADIC(nd, EADDASS) && CInt64_Less(val, cint64_zero)) { - nd->nodetype = ESUBASS; - nd->u.diadic.right->u.node->data.intval = CInt64_Neg(val); - } - if (isUnsigned) { - CInt64_ConvertUInt32(&nd->u.diadic.right->u.node->data.intval); - ind->addConst = CInt64_GetULong(&nd->u.diadic.right->u.node->data.intval); - } else { - CInt64_ConvertInt32(&nd->u.diadic.right->u.node->data.intval); - ind->addConst = CInt64_GetULong(&nd->u.diadic.right->u.node->data.intval); - } - ind->addNode = NULL; - } else if (nd->nodetype == EADDASS || nd->nodetype == ESUBASS) { - ind->addNode = nd->u.diadic.right; - } else if (nd->nodetype == EASS) { - ind->addNode = nd->u.diadic.right->u.diadic.right; - } - } else { - if (IS_TYPE_POINTER_ONLY(nd->rtype)) - ind->addConst = TPTR_TARGET(nd->rtype)->size; - else - ind->addConst = 1; - ind->addNode = NULL; - } - - FirstInd = ind; - - if (IS_LINEAR_DIADIC_2(nd, EADDASS, ESUBASS)) { - if (nd->u.diadic.right->flags & IROLF_LoopInvariant) - IRO_Dump("Found induction variable the new way: %s\n", var->object->name->name); - else - IRO_Dump("Found induction variable the old way: %s\n", var->object->name->name); - } else if (nd->type == IROLinearOp2Arg && (nd->u.diadic.right->nodetype == EADD || nd->u.diadic.right->nodetype == ESUB)) { - IRO_Dump("Found induction variable the new way: %s\n", var->object->name->name); - } else { - IRO_Dump("Found induction variable the old way: %s\n", var->object->name->name); - } - } - } - - if (nd == fnode->last) - break; - nd = nd->next; - } - } - } -} - -static void IRO_ActUnmarkLoopInvariance(IROLinear *linear, Boolean isFirst) { - if (isFirst) - linear->flags &= ~IROLF_LoopInvariant; -} - -static void UnmarkSubexpressionsOfInvariantExpressions(void) { - IROExpr *expr; - - for (expr = IRO_FirstExpr; expr; expr = expr->next) { - if ( - Bv_IsBitSet(expr->node->index, InLoop) && - !expr->notSubable && - (!expr->couldError || expr->node->mustreach) && - (expr->linear->flags & IROLF_LoopInvariant) - ) { - IRO_WalkTree(expr->linear, IRO_ActUnmarkLoopInvariance); - expr->linear->flags |= IROLF_LoopInvariant; - } - } -} - -static void MyHandleLoop_Vector(IRONode *fnode) { - IRONode *pred; - UInt16 i; - IROExpr *expr; - IROExpr *removedExprs; - IROExpr *exprnext; - IROLoopInd *induction; - IROExpr *exprinner; - Boolean flag24; - IRONode *v2; - IRONode *node22; - int flag21; - IRONode *iter; - IROExpr *searchris; - IROLinear *reduceNd1; - VarRecord *var; - IROLinear *reduceNd2; - - IRO_FirstExpr = NULL; - LoopNode = fnode; - FindMustReach(); - - for (var = IRO_FirstVar; var; var = var->next) - var->xA = 1; - - ComputeLoopKills(); - ComputeLoopInvariance(); - ComputeLoopInduction(); - LoopNode = fnode; - ConditionalHeaderAtBottom = 0; - - v2 = NULL; - flag21 = 0; - node22 = NULL; - for (i = 0; i < LoopNode->numpred; i++) { - pred = IRO_NodeTable[LoopNode->pred[i]]; - if (!Bv_IsBitSet(pred->index, InLoop)) { - if (flag21) - node22 = NULL; - else - node22 = pred; - flag21 = 1; - if (pred->nextnode == fnode) { - CError_ASSERT(2880, v2 == NULL || pred == v2); - v2 = pred; - } - } - } - - if (!flag21) { - IRO_Dump("No predecessor outside the loop\n"); - return; - } - - if (!node22 || node22->last->type != IROLinearGoto) - node22 = CreatePreHeader(fnode, v2); - PredInt = node22->last; - - if (PredInt->type == IROLinearGoto && PredInt->u.label.label != LoopNode->first->u.label.label) { - if (!KnownBounds || !Times) { - for (iter = IRO_FirstNode; iter; iter = iter->nextnode) - iter->mustreach = 0; - } else { - PredInt->u.label.label = LoopNode->first->u.label.label; - IRO_ComputeSuccPred(); - } - } - - if (copts.loopinvariants || copts.strengthreduction) { - MoveInvarianceInAddressExpr(); - IRO_DumpAfterPhase("MoveInvarianceInAddressExpr", 0); - IRO_FindExpressions(InLoop, 1); - IRO_DumpExprs(); - } - - if (copts.loopinvariants) - UnmarkSubexpressionsOfInvariantExpressions(); - - if (!copts.optimizesize && copts.strengthreduction) { - for (expr = IRO_FirstExpr; expr; expr = expr->next) { - if ( - !(expr->x0 & 4) && - Bv_IsBitSet(expr->node->index, InLoop) && - !expr->notSubable && - (!expr->couldError || expr->node->mustreach) && - Reducable(expr->linear, &reduceNd1, &reduceNd2, &var) - ) { - IRO_WalkTree(expr->linear, IRO_ActUnmarkRISCandidate); - expr->linear->flags |= IROLF_Ris; - expr->x1A = reduceNd1; - expr->x1E = var; - expr->x22 = reduceNd2; - } - } - } - - if (!copts.optimizesize && copts.strengthreduction) { - RisList = NULL; - for (expr = IRO_FirstExpr; expr; expr = exprnext) { - exprnext = expr->next; - if (!(expr->x0 & 4) && (expr->linear->flags & IROLF_Ris)) { - reduceNd1 = expr->x1A; - var = expr->x1E; - reduceNd2 = expr->x22; - - induction = FirstInd; - while (induction && induction->var != var) - induction = induction->next; - CError_ASSERT(3529, induction != NULL); - - IRO_FindDepends(reduceNd1); - if (!Bv_BitsInCommon(IRO_Depends, AllKills)) { - IRO_Dump("Found reduction in strength: %d\n", expr->linear->index); - if (IS_LINEAR_DIADIC(expr->linear, ESHL)) { - expr->linear->nodetype = EMUL; - CInt64_SetULong(&reduceNd1->u.node->data.intval, 1 << CInt64_GetULong(&reduceNd1->u.node->data.intval)); - reduceNd1->u.node->rtype = expr->linear->rtype; - } - - searchris = RisList; - while (1) { - if (!searchris) - break; - if (IRO_ExprsSame(expr->linear, searchris->linear)) - break; - searchris = searchris->next; - } - - if (searchris) { - IRO_Dump("Using existing RIS: %d\n", searchris->linear->index); - IRO_WalkTree(expr->linear, IRO_RemoveExpr_Action); - } else { - searchris = CreateRIS(expr, reduceNd2, reduceNd1, induction, 0); - } - IRO_ReplaceReference(expr->linear, searchris->x8, expr->linear); - IRO_ClipExpr(expr); - } - } - } - } - - RisList = NULL; - - expr = IRO_FirstExpr; - removedExprs = NULL; - if (copts.loopinvariants) { - while (expr) { - exprnext = expr->next; - flag24 = 0; - - if ( - Bv_IsBitSet(expr->node->index, InLoop) && - !expr->notSubable && - (!expr->couldError || expr->node->mustreach) && - (expr->linear->flags & IROLF_LoopInvariant) && - !(expr->x0 & 4) - ) { - IRO_Dump("Found loop invariant: %d\n", expr->linear->index); - - for (exprinner = removedExprs; exprinner; exprinner = exprinner->next) { - if (IRO_ExprsSame(exprinner->linear, expr->linear)) { - IRO_ReplaceReference(expr->linear, exprinner->x8, expr->linear); - IRO_NopOut(expr->linear); - IRO_Dump("Using already removed expr: %d\n", exprinner->linear->index); - IRO_RemoveExpr(expr); - flag24 = 1; - } - } - - if (!flag24 && !expr->x8) { - IRO_GetTemp(expr); - IRO_ReplaceReference(expr->linear, expr->x8, expr->linear); - IRO_MoveExpression(expr, PredInt); - IRO_AssignToTemp(expr); - IRO_RemoveExpr(expr); - expr->next = removedExprs; - removedExprs = expr; - } - } - - expr = exprnext; - } - } -} - -static void MyHandleLoop_Motion(IRONode *fnode) { - IROLoopMemRef *memref; - IRONode *pred; - UInt16 i; - IRONode *v2; - IRONode *node21; - Object *tempobj; - int flag20; - IRONode *iter; - IROLinear *ass; - VarRecord *var; - Boolean checkflag; - IROLoop *loop; - IROList list; - IROElmList *refiter; - - IRO_FirstExpr = NULL; - LoopNode = fnode; - FindMustReach(); - - for (var = IRO_FirstVar; var; var = var->next) - var->xA = 1; - - ComputeLoopKills(); - ComputeLoopInvariance(); - ComputeLoopInduction(); - LoopNode = fnode; - ConditionalHeaderAtBottom = 0; - - v2 = NULL; - flag20 = 0; - node21 = NULL; - for (i = 0; i < LoopNode->numpred; i++) { - pred = IRO_NodeTable[LoopNode->pred[i]]; - if (!Bv_IsBitSet(pred->index, InLoop)) { - if (flag20) - node21 = NULL; - else - node21 = pred; - flag20 = 1; - if (pred->nextnode == fnode) { - CError_ASSERT(3880, v2 == NULL || pred == v2); - v2 = pred; - } - } - } - - if (!flag20) { - IRO_Dump("No predecessor outside the loop\n"); - return; - } - - if (!node21 || node21->last->type != IROLinearGoto) - node21 = CreatePreHeader(fnode, v2); - PredInt = node21->last; - - if (PredInt->type == IROLinearGoto && PredInt->u.label.label != LoopNode->first->u.label.label) { - if (!KnownBounds || !Times) { - for (iter = IRO_FirstNode; iter; iter = iter->nextnode) - iter->mustreach = 0; - } else { - PredInt->u.label.label = LoopNode->first->u.label.label; - IRO_ComputeSuccPred(); - } - } - - if (copts.loopinvariants || copts.strengthreduction) { - MoveInvarianceInAddressExpr(); - IRO_DumpAfterPhase("MoveInvarianceInAddressExpr", 0); - IRO_FindExpressions(InLoop, 0); - IRO_DumpExprs(); - } - - if (copts.loopinvariants) - UnmarkSubexpressionsOfInvariantExpressions(); - - checkflag = 1; - Bv_AllocVector(&InLoop_Exits, IRO_NumNodes + 1); - Bv_AllocVector(&InLoop_Tails, IRO_NumNodes + 1); - LoopExitNumber = 0; - LoopExitSuccessor = NULL; - LoopTailNum = 0; - LoopTail = NULL; - IRO_FindLoopTailsAndExits(fnode); - FindMustReach1(fnode); - - loop = NULL; - if (LoopTailNum == 1) { - if (fnode->last->type == IROLinearIf || fnode->last->type == IROLinearIfNot) - loop = ExtractLoopInfo(fnode); - else if (LoopTail->last->type == IROLinearIf || LoopTail->last->type == IROLinearIfNot) - loop = ExtractLoopInfo(LoopTail); - } - - if (loop && !(loop->flags & LP_IFEXPR_NON_CANONICAL) && LoopExitNumber == 1) { - IRO_LoopMemRefFirst = NULL; - IRO_LoopMemRefCurrent = NULL; - CheckAllLoopAddresses(IRO_FirstNode, InLoop, &checkflag); - CheckAllLoopAddresses(IRO_FirstNode, InLoop, &checkflag); - if (checkflag) { - for (memref = IRO_LoopMemRefFirst; memref; memref = memref->next) { - if (memref->flags & LoopMemRef_10) - memref->flags |= LoopMemRef_8; - } - - for (memref = IRO_LoopMemRefFirst; memref; memref = memref->next) { - IRO_Dump("Loop Motion Candidate:: Int= %d", memref->nd->index); - if (memref->flags & LoopMemRef_8) - IRO_Dump("<invalid>"); - if (memref->flags & LoopMemRef_1) - IRO_Dump("<load>"); - if (memref->flags & LoopMemRef_2) - IRO_Dump("<store>"); - IRO_Dump("\n"); - - if (!(memref->flags & LoopMemRef_8)) { - tempobj = create_temp_object(memref->nd->rtype); - IRO_FindVar(tempobj, 1, 1); - if (IRO_FindVar(((IROLinear *) memref->rec->objRefs->element)->u.node->data.objref, 0, 1)) { - IRO_InitList(&list); - ass = IRO_NewLinear(IROLinearOp2Arg); - ass->index = ++IRO_NumLinear; - ass->rtype = memref->nd->rtype; - ass->nodetype = EASS; - ass->u.diadic.left = IRO_TempReference(tempobj, &list); - ass->u.diadic.left->flags |= IROLF_Ind | IROLF_Assigned; - ass->u.diadic.left->u.monadic->flags |= IROLF_Ind | IROLF_Assigned; - ass->u.diadic.right = IRO_DuplicateExpr(memref->nd, &list); - IRO_AddToList(ass, &list); - IRO_Paste(list.head, list.tail, PredInt); - } else { - CError_FATAL(4123); - } - - if (LoopExitSuccessor->numpred != 1) - LoopExitSuccessor = CreateNewLoopExitSuccessor(LoopExitSuccessor); - - IRO_InitList(&list); - ass = IRO_NewLinear(IROLinearOp2Arg); - ass->index = ++IRO_NumLinear; - ass->rtype = memref->nd->rtype; - ass->nodetype = EASS; - ass->u.diadic.left = IRO_DuplicateExpr(memref->nd, &list); - ass->u.diadic.left->flags |= IROLF_Ind | IROLF_Assigned; - ass->u.diadic.left->u.monadic->flags |= IROLF_Ind | IROLF_Assigned; - ass->u.diadic.right = IRO_TempReference(tempobj, &list); - IRO_AddToList(ass, &list); - - if (LoopExitSuccessor->first->type == IROLinearLabel) - IRO_PasteAfter(list.head, list.tail, LoopExitSuccessor->first); - else - IRO_Paste(list.head, list.tail, LoopExitSuccessor->first); - - for (refiter = memref->list; refiter; refiter = refiter->next) { - IRO_Dump("Loop Motion Candidate Reference at Int= %d\n", ((IROLinear *) refiter->element)->index); - IRO_InitList(&list); - IRO_TempReference(tempobj, &list); - IRO_Paste(list.head, list.tail, refiter->element); - IRO_LocateFather_Cut_And_Paste(refiter->element, list.tail); - } - } - } - } - } - - IRO_DumpAfterPhase("After Motion", 0); -} - -static Boolean CheckLoopAddress(IROLinear *nd, Boolean mustreach1) { - IROLoopMemRef *memref; - IROAddrRecord *rec; - IROAddrRecord *otherrec; - IROLinear *inner; - IROElmList *list; - Boolean flag; - - inner = nd->u.monadic; - rec = IRO_InitAddrRecordPointer(inner); - if (IS_LINEAR_ENODE(inner, EOBJREF)) { - rec->numObjRefs++; - IRO_AddElmToList(inner, &rec->objRefs); - } else if (IS_LINEAR_DIADIC(inner, EADD)) { - IRO_DecomposeAddressExpression(inner, rec); - } else { - return 0; - } - - if (rec->numObjRefs != 1) - return 0; - - flag = (nd->flags & IROLF_CouldError) || !(nd->flags & IROLF_Reffed); - if (!IRO_LoopMemRefFirst) { - MakeLoopEntry(nd, rec, mustreach1, flag); - } else { - for (memref = IRO_LoopMemRefFirst; memref; memref = memref->next) { - otherrec = memref->rec; - if (((IROLinear *) rec->objRefs->element)->u.node->data.objref == ((IROLinear *) otherrec->objRefs->element)->u.node->data.objref) { - if (IRO_ExprsSame(inner, otherrec->linear)) { - list = oalloc(sizeof(IROElmList)); - list->element = nd; - list->next = NULL; - if (!memref->list) { - memref->list = list; - } else { - list->next = memref->list; - memref->list = list; - } - } else { - memref->flags |= LoopMemRef_8; - } - - if (!mustreach1 && flag) - memref->flags |= LoopMemRef_8; - if (mustreach1 || flag) - memref->flags &= ~LoopMemRef_10; - break; - } - } - - if (!memref) - MakeLoopEntry(nd, rec, mustreach1, flag); - } - - return 1; -} - -static void CheckAllLoopAddresses(IRONode *fnode, BitVector *bv, Boolean *resultFlag) { - IROLinear *nd; - Boolean flag; - - flag = *resultFlag; - while (fnode) { - if (Bv_IsBitSet(fnode->index, bv) && (nd = fnode->first)) { - while (flag) { - if (nd->type == IROLinearOp1Arg && nd->nodetype == EINDIRECT) - flag = CheckLoopAddress(nd, fnode->mustreach1); - else if (nd->type == IROLinearFunccall) - flag = 0; - - if (nd == fnode->last) - break; - nd = nd->next; - } - - if (!flag) - break; - } - fnode = fnode->nextnode; - } - *resultFlag = flag; -} - -static void MakeLoopEntry(IROLinear *nd, IROAddrRecord *rec, Boolean mustreach1, Boolean flag2) { - IROElmList *list; - - if (!IRO_IsRegable(((IROLinear *) rec->objRefs->element)->u.node->data.objref) && - (nd->u.monadic->flags & IROLF_LoopInvariant) && - !IRO_HasSideEffect(nd)) { - if (!IRO_LoopMemRefFirst) { - IRO_LoopMemRefCurrent = IRO_LoopMemRefFirst = oalloc(sizeof(IROLoopMemRef)); - } else { - IRO_LoopMemRefCurrent->next = oalloc(sizeof(IROLoopMemRef)); - IRO_LoopMemRefCurrent = IRO_LoopMemRefCurrent->next; - } - IRO_LoopMemRefCurrent->flags = LoopMemRef_10; - IRO_LoopMemRefCurrent->nd = nd; - IRO_LoopMemRefCurrent->rec = rec; - IRO_LoopMemRefCurrent->next = NULL; - IRO_LoopMemRefCurrent->list = NULL; - - list = oalloc(sizeof(IROElmList)); - list->element = nd; - list->next = NULL; - if (!IRO_LoopMemRefCurrent->list) { - IRO_LoopMemRefCurrent->list = list; - } else { - list->next = IRO_LoopMemRefCurrent->list; - IRO_LoopMemRefCurrent->list = list; - } - - if (((IROLinear *) rec->objRefs->element)->flags & IROLF_Assigned) { - IRO_LoopMemRefCurrent->flags |= LoopMemRef_2; - if (((IROLinear *) rec->objRefs->element)->flags & IROLF_Used) - IRO_LoopMemRefCurrent->flags |= LoopMemRef_1; - } else { - IRO_LoopMemRefCurrent->flags |= LoopMemRef_1; - } - - if (!mustreach1 && flag2) - IRO_LoopMemRefCurrent->flags |= LoopMemRef_8; - - if (mustreach1 || flag2) - IRO_LoopMemRefCurrent->flags &= ~LoopMemRef_10; - } -} - -void FindAssignmenttoInductionVar(IROLoop *loop, IRONode *fnode) { - IROLinear *nd; - UInt32 index; - - if (!loop->induction) { - loop->nd14 = NULL; - } else { - index = loop->induction->var->index; - for (nd = fnode->first; nd; nd = nd->next) { - Bv_Clear(IRO_VarKills); - IRO_GetKills(nd); - if (Bv_IsBitSet(index, IRO_VarKills)) - loop->nd14 = nd; - - if (nd == fnode->last) - break; - } - - if (loop->nd14 && loop->nd14->type != IROLinearOp2Arg) - loop->nd14 = NULL; - } -} - -static void ComputeIntWeight(IROLoop *loop, IROLinear *Int) { - loop->sizeBySomeMeasurement++; -} - -static IROLinear *IsTypconVar(IROLinear *nd) { - if (IS_LINEAR_MONADIC(nd, ETYPCON) && IRO_IsVariable(nd->u.monadic)) - return nd->u.monadic; - else - return NULL; -} - -IROLoop *ExtractLoopInfo(IRONode *fnode) { - Boolean flag30; - Boolean flag29; - Boolean flag28; - UInt32 counter27; - IROLoopInd *ind23; - Object *obj; - IROLinear *nd21; - IRONode *scanfnode; - IROLinear *left19; - IROLinear *right18; - IROLinear *tmp18; - IROLinear *scannd; - IROLinear *tmp; - VarRecord *var; - IROLoopInd *scanind; - IROLinear *left; - IROLinear *right; - UInt32 counter2; - UInt32 i; - IROLoop *loop; - - flag30 = 0; - flag29 = 0; - flag28 = 0; - counter27 = 0; - LoopNode = fnode; - - loop = oalloc(sizeof(IROLoop)); - loop->fnode = fnode; - nd21 = LoopNode->last->u.label.x4; - loop->nd18 = nd21; - loop->flags = 0; - loop->x8 = 0; - loop->nd14 = NULL; - loop->induction = NULL; - loop->index20 = -1; - loop->index24 = -1; - loop->sizeBySomeMeasurement = 0; - - if (nd21->type == IROLinearOp2Arg && IS_TYPE_INT(nd21->rtype)) { - ind23 = NULL; - left19 = nd21->u.diadic.left; - right18 = nd21->u.diadic.right; - if (IRO_IsVariable(left19) || (left19 = IsTypconVar(left19))) { - if ((var = IRO_FindVar(left19->u.monadic->u.node->data.objref, 0, 1))) { - scanind = FirstInd; - while (scanind && scanind->var != var) - scanind = scanind->next; - if (scanind) { - ind23 = scanind; - loop->flags |= LoopFlags_1; - loop->induction = scanind; - } - } - } - - if (IRO_IsVariable(right18) || (right18 = IsTypconVar(right18))) { - if ((var = IRO_FindVar(right18->u.monadic->u.node->data.objref, 0, 1))) { - scanind = FirstInd; - while (scanind && scanind->var != var) - scanind = scanind->next; - if (scanind) { - ind23 = scanind; - loop->flags &= ~LoopFlags_1; - loop->induction = scanind; - } - } - } - - if (ind23 && ind23->addConst > 0) { - if (loop->flags & LoopFlags_1) { - if ( - loop->nd18->type != IROLinearOp2Arg || - !(loop->nd18->nodetype == ELESS || loop->nd18->nodetype == EGREATER || loop->nd18->nodetype == ELESSEQU || loop->nd18->nodetype == EGREATEREQU) || - !loop->nd18->u.diadic.left || - !loop->nd18->u.diadic.left->rtype || - !IS_TYPE_INT(loop->nd18->u.diadic.left->rtype) || - !loop->nd18->u.diadic.right || - !loop->nd18->u.diadic.right->rtype || - !IS_TYPE_INT(loop->nd18->u.diadic.right->rtype) - ) { - loop->flags |= LP_IFEXPR_NON_CANONICAL; - return loop; - } - } else { - if ( - loop->nd18->type == IROLinearOp2Arg && - (loop->nd18->nodetype == EGREATER || loop->nd18->nodetype == EGREATEREQU) && - (left = loop->nd18->u.diadic.left) && - left->rtype && - IS_TYPE_INT(left->rtype) && - (right = loop->nd18->u.diadic.right) && - right->rtype && - IS_TYPE_INT(right->rtype) - ) { - loop->nd18->u.diadic.left = right; - loop->nd18->u.diadic.right = left; - if (loop->nd18->nodetype == EGREATER) - loop->nd18->nodetype = ELESS; - else if (loop->nd18->nodetype == EGREATEREQU) - loop->nd18->nodetype = ELESSEQU; - loop->flags |= LoopFlags_1; - } else if ( - loop->nd18->type == IROLinearOp2Arg && - (loop->nd18->nodetype == ELESS || loop->nd18->nodetype == ELESSEQU) && - (left = loop->nd18->u.diadic.left) && - left->rtype && - IS_TYPE_INT(left->rtype) && - (right = loop->nd18->u.diadic.right) && - right->rtype && - IS_TYPE_INT(right->rtype) - ) { - loop->nd18->u.diadic.left = right; - loop->nd18->u.diadic.right = left; - if (loop->nd18->nodetype == ELESS) - loop->nd18->nodetype = EGREATER; - else if (loop->nd18->nodetype == ELESSEQU) - loop->nd18->nodetype = EGREATEREQU; - loop->flags |= LoopFlags_1; - } else { - loop->flags |= LP_IFEXPR_NON_CANONICAL; - return loop; - } - } - } else { - loop->flags |= LP_INDUCTION_NOT_FOUND; - return loop; - } - } else if (nd21->type == IROLinearOp1Arg && IS_TYPE_INT(nd21->rtype)) { - if (nd21->nodetype == EPREINC || nd21->nodetype == EPOSTINC || nd21->nodetype == EPREDEC || nd21->nodetype == EPOSTDEC) { - if (IRO_IsVariable(nd21->u.monadic)) { - if ((var = IRO_FindVar(nd21->u.monadic->u.monadic->u.node->data.objref, 0, 1))) { - scanind = FirstInd; - while (scanind && scanind->var != var) - scanind = scanind->next; - if (scanind) { - ind23 = scanind; - loop->flags |= LoopFlags_10000; - loop->induction = scanind; - } else { - loop->flags |= LP_INDUCTION_NOT_FOUND; - return loop; - } - } else { - loop->flags |= LP_INDUCTION_NOT_FOUND; - return loop; - } - } else { - loop->flags |= LP_INDUCTION_NOT_FOUND; - return loop; - } - } else { - loop->flags |= LP_INDUCTION_NOT_FOUND; - return loop; - } - } else { - loop->flags |= LP_IFEXPR_NON_CANONICAL; - return loop; - } - - counter2 = 0; - scanind = FirstInd; - while (scanind) { - scanind = scanind->next; - counter2++; - } - - if (counter2 > 1) - loop->flags |= LP_HAS_MULTIPLE_INDUCTIONS; - - if ((scanind = loop->induction)) { - nd21 = scanind->nd; - if (nd21->type == IROLinearOp2Arg) { - if (IS_LINEAR_DIADIC_2(loop->nd18, ELESS, ELESSEQU)) { - if (nd21->nodetype == EADDASS) { - if (scanind->addConst == 1) - loop->flags |= LP_LOOP_STEP_ISADD; - if (scanind->addConst > 0) - loop->flags |= LP_LOOP_STEP_ISPOS; - } else if (nd21->nodetype == EASS && - IS_LINEAR_DIADIC(nd21->u.diadic.right, EADD) && - IRO_IsIntConstant(tmp18 = nd21->u.diadic.right->u.diadic.right) && - CTool_EndianReadWord32(&tmp18->u.node->data.intval.hi) == 0) { - if (CInt64_GetULong(&tmp18->u.node->data.intval) == 1) - loop->flags |= LP_LOOP_STEP_ISADD; - if (CInt64_GetULong(&tmp18->u.node->data.intval) > 0) - loop->flags |= LP_LOOP_STEP_ISPOS; - } - } - } else if (nd21->type == IROLinearOp1Arg) { - if (nd21->nodetype == EPREINC || nd21->nodetype == EPOSTINC) { - if (scanind->addConst == 1) - loop->flags |= LP_LOOP_STEP_ISADD; - if (scanind->addConst > 0) - loop->flags |= LP_LOOP_STEP_ISPOS; - } - if (nd21->nodetype == EPREDEC || nd21->nodetype == EPOSTDEC) { - if (scanind->addConst == 1) - loop->flags |= LoopFlags_2000; - if (scanind->addConst > 0) - loop->flags |= LP_LOOP_STEP_ISNEG; - } - } - loop->index24 = nd21->index; - loop->index20 = IRO_FindStart(nd21)->index; - } - - if (ind23) { - tmp = IRO_FindStart(fnode->last->u.diadic.right); - loop->flags |= LoopFlags_200; - if (loop->flags & LoopFlags_10000) { - for (scannd = loop->fnode->first; scannd && scannd != tmp; scannd = scannd->next) { - if (scannd->type != IROLinearLabel && scannd->type != IROLinearNop) - loop->flags &= ~LoopFlags_200; - } - } else { - for (scannd = ind23->nd->next; scannd && scannd != tmp; scannd = scannd->next){ - if (scannd->type != IROLinearLabel && scannd->type != IROLinearNop) - loop->flags &= ~LoopFlags_200; - } - for (scannd = loop->fnode->first; scannd && scannd != tmp; scannd = scannd->next){ - if ((scannd->index < loop->index20 || scannd->index > loop->index24) && scannd->type != IROLinearLabel && scannd->type != IROLinearNop) - loop->flags &= ~LoopFlags_200; - } - } - } - - for (scanfnode = IRO_FirstNode; scanfnode; scanfnode = scanfnode->nextnode) { - if (Bv_IsBitSet(scanfnode->index, InLoop) && scanfnode != fnode && (scannd = scanfnode->first)) { - while (1) { - if (scannd->type == IROLinearFunccall) - flag30 = 1; - if (scannd->type == IROLinearGoto) - flag28++; - if (flag28 >= 1) - flag29 = 1; - if (scannd->type == IROLinearIf || scannd->type == IROLinearIfNot || scannd->type == IROLinearSwitch || scannd->type == IROLinearReturn) - flag29 = 1; - - if (scannd->type == IROLinearAsm) - loop->flags |= LP_LOOP_HAS_ASM; - - if (!(scannd->flags & IROLF_Reffed) && scannd->type != IROLinearNop && scannd->type != IROLinearLabel) { - if (!IRO_IsAssignOp[scannd->nodetype]) { - loop->flags |= LoopFlags_8; - } else if (scannd->index < loop->index20 || scannd->index > loop->index24) { - counter27++; - if (IsAssignmentReductionCandidate(scannd) && counter27 == 1) - loop->flags |= LoopFlags_40000; - if (counter27 > 1) - loop->flags &= ~LoopFlags_40000; - } - } - - if (scannd->index < loop->index20 || scannd->index > loop->index24) { - if (IS_LINEAR_ENODE(scannd, EOBJREF)) { - obj = scannd->u.node->data.objref; - if ((scannd->flags & IROLF_Ind) && obj && obj == loop->induction->var->object) { - if (!(scannd->flags & IROLF_Assigned) && (scannd->flags & IROLF_Used)) { - IRO_Dump("Induction Used in loop\n"); - loop->flags |= LoopFlags_800; - } - } - } - - if (IS_LINEAR_DIADIC(scannd, ESHR) && - (obj = IRO_IsVariable(scannd->u.diadic.left)) && - IRO_IsIntConstant(scannd->u.diadic.right)) { - for (scanind = FirstInd; scanind; scanind = scanind->next) { - if (scanind->var->object == obj) { - IRO_Dump("Induction has DIV: %s\n", obj->name->name); - scanind->flags |= LoopInd_HasDiv; - } - } - } - - if (IS_LINEAR_DIADIC(scannd, EAND) && - (obj = IRO_IsVariable(scannd->u.diadic.left)) && - IRO_IsIntConstant(scannd->u.diadic.right)) { - for (scanind = FirstInd; scanind && obj; scanind = scanind->next) { - if (scanind->var->object == obj) { - IRO_Dump("Induction has MOD: %s\n", obj->name->name); - scanind->flags |= LoopInd_HasMod; - } - } - } - } - - ComputeIntWeight(loop, scannd); - if (scannd == scanfnode->last) - break; - scannd = scannd->next; - } - } - - if (flag30) - loop->flags |= LP_LOOP_HAS_CALLS; - if (flag29) - loop->flags |= LP_LOOP_HAS_CNTRLFLOW; - - for (i = 0; i < scanfnode->numsucc && scanfnode != fnode; i++) { - if (Bv_IsBitSet(scanfnode->index, InLoop) && !Bv_IsBitSet(scanfnode->succ[i], InLoop)) { - IRO_Dump("Node %d has an out of loop successor %d\n", scanfnode->index, scanfnode->succ[i]); - IRO_DumpBits("Loop includes: ", InLoop); - IRO_Dump("loop has multiple exits\n"); - loop->flags |= LoopFlags_1000; - } - } - } - - return loop; -} - -CLabel *BuildLabel(IROList *list) { - IROLinear *nd; - - nd = IRO_NewLinear(IROLinearLabel); - nd->index = IRO_NumLinear++; - nd->u.label.label = IRO_NewLabel(); - nd->flags |= IROLF_1; - IRO_AddToList(nd, list); - return nd->u.label.label; -} - -static void MoveInvarianceInAddressExpr(void) { - IRONode *fnode; - IROLinear *nd; - IROLinear *start; - IROList list; - - IRO_FirstExpr = IRO_LastExpr = NULL; - IRO_NumExprs = 0; - - for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) { - if (Bv_IsBitSet(fnode->index, InLoop)) { - for (nd = fnode->first; nd; nd = nd->next) { - if (nd->type == IROLinearOp1Arg && - (nd->nodetype == EINDIRECT || nd->nodetype == EINDIRECT) && - IS_LINEAR_DIADIC(nd->u.monadic, EADD)) { - RearrangeInvarianceInAddressExpr(nd->u.monadic, &list); - start = IRO_FindStart(nd->u.monadic); - IRO_LocateFather_Cut_And_Paste(nd->u.monadic, list.tail); - IRO_Paste(list.head, list.tail, start); - } - - if (nd == fnode->last) - break; - } - } - } - - IRO_UpdateFlagsOnInts(); -} - -static void AddAddendLinear(IROLinear *nd) { - IROElmList *list; - - if (IS_LINEAR_DIADIC(nd, EADD)) { - AddAddendLinear(nd->u.diadic.left); - AddAddendLinear(nd->u.diadic.right); - } else { - list = oalloc(sizeof(IROElmList)); - list->element = nd; - list->next = NULL; - if (FirstAddendLinear) - LastAddendLinear->next = list; - else - FirstAddendLinear = list; - LastAddendLinear = list; - } -} - -static IROLinear *RearrangeInvarianceInAddressExpr(IROLinear *nd, IROList *list) { - IROLinear *result; - IROElmList *scanlist; - IROElmList *elist; - IROLinear *scannd; - - IRO_InitList(list); - FirstAddendLinear = LastAddendLinear = NULL; - AddAddendLinear(nd->u.diadic.left); - AddAddendLinear(nd->u.diadic.right); - - elist = NULL; - result = NULL; - for (scanlist = FirstAddendLinear; scanlist; scanlist = scanlist->next) { - scannd = scanlist->element; - if (!IRO_IsIntConstant(scannd) && (scannd->flags & IROLF_LoopInvariant)) { - if (result) { - IROLinear *tmp = IRO_NewLinear(IROLinearOp2Arg); - tmp->index = ++IRO_NumLinear; - tmp->nodetype = EADD; - tmp->u.diadic.left = result; - tmp->u.diadic.right = IRO_DuplicateExpr(scannd, list); - IRO_AddToList(tmp, list); - tmp->flags |= IROLF_LoopInvariant; - tmp->flags |= IROLF_Reffed; - tmp->rtype = result->rtype; - result = tmp; - } else { - result = IRO_DuplicateExpr(scannd, list); - } - - if (elist) - elist->next = scanlist->next; - else - FirstAddendLinear = scanlist->next; - } else { - elist = scanlist; - } - } - - for (scanlist = FirstAddendLinear, elist = NULL; scanlist; scanlist = scanlist->next) { - scannd = scanlist->element; - if (!IRO_IsIntConstant(scannd)) { - if (result) { - IROLinear *tmp = IRO_NewLinear(IROLinearOp2Arg); - tmp->index = ++IRO_NumLinear; - tmp->nodetype = EADD; - tmp->u.diadic.left = result; - tmp->u.diadic.right = IRO_DuplicateExpr(scannd, list); - IRO_AddToList(tmp, list); - tmp->flags |= IROLF_Reffed; - tmp->rtype = result->rtype; - result = tmp; - } else { - result = IRO_DuplicateExpr(scannd, list); - } - - if (elist) - elist->next = scanlist->next; - else - FirstAddendLinear = scanlist->next; - } else { - elist = scanlist; - } - } - - for (scanlist = FirstAddendLinear; scanlist; scanlist = scanlist->next) { - scannd = scanlist->element; - if (result) { - IROLinear *tmp = IRO_NewLinear(IROLinearOp2Arg); - tmp->index = ++IRO_NumLinear; - tmp->nodetype = EADD; - tmp->u.diadic.left = result; - tmp->u.diadic.right = scannd; - tmp->u.diadic.right = IRO_DuplicateExpr(scannd, list); - IRO_AddToList(tmp, list); - tmp->flags |= IROLF_Reffed; - tmp->rtype = result->rtype; - result = tmp; - } else { - result = IRO_DuplicateExpr(scannd, list); - } - } - - return result; -} - -static IROLinear *FindAddendForReductionPattern(IROLinear *a, IROLinear *b, Boolean *resultFlag) { - IROLinear *left; - IROLinear *right; - IROLinear *node28; - Boolean subflag; - - left = b->u.diadic.left; - right = b->u.diadic.right; - if (b->nodetype == EADD || b->nodetype == ESUB) { - node28 = left; - while (IS_LINEAR_MONADIC(node28, ETYPCON)) - node28 = node28->u.monadic; - - if (IS_LINEAR_MONADIC(node28, EINDIRECT) && (node28->u.monadic->flags & IROLF_LoopInvariant) && IRO_ExprsSame(a, node28)) { - *resultFlag = 1; - return left; - } - - if (IS_LINEAR_DIADIC_2(node28, EADD, ESUB)) { - if ((node28 = FindAddendForReductionPattern(a, node28, &subflag))) { - *resultFlag = 1; - return node28; - } - } - } - - *resultFlag = 0; - if (b->nodetype == EADD) { - node28 = right; - while (IS_LINEAR_MONADIC(node28, ETYPCON)) - node28 = node28->u.monadic; - - if (IS_LINEAR_MONADIC(node28, EINDIRECT) && (node28->u.monadic->flags & IROLF_LoopInvariant) && IRO_ExprsSame(a, node28)) { - return right; - } - - if (IS_LINEAR_DIADIC_2(node28, EADD, ESUB)) { - if ((node28 = FindAddendForReductionPattern(a, node28, &subflag))) { - return node28; - } - } - } - - return NULL; -} - -static void ReorderOperandsForReductionPattern(IROLinear *a, IROLinear *b) { - IROLinear *left; - IROLinear *right; - IROLinear *addend; - IROLinear *tmp; - Boolean flag; - - left = b->u.diadic.left; - right = b->u.diadic.right; - - if (b->nodetype == EADD && (addend = FindAddendForReductionPattern(a, b, &flag)) && addend != left) { - if (flag && IS_LINEAR_DIADIC_2(left, EADD, ESUB) && addend->rtype == right->rtype) { - tmp = left; - b->u.diadic.left = right; - left = right; - b->u.diadic.right = tmp; - right = tmp; - flag = 0; - } - - if (!flag && IS_LINEAR_DIADIC_2(right, EADD, ESUB) && addend->rtype == left->rtype) { - if (IRO_LocateFather_Cut_And_Paste_Without_Nopping(addend, left)) - b->u.diadic.left = addend; - } - } -} - -static UInt32 IsAssignmentReductionCandidate(IROLinear *nd) { - IROLinear *left; - IROLinear *right; - IROLinear *tmp; - - if (nd->type == IROLinearOp2Arg) { - if (nd->nodetype == EASS) { - left = nd->u.diadic.left; - right = nd->u.diadic.right; - if (IS_LINEAR_MONADIC(left, EINDIRECT) && (left->u.monadic->flags & IROLF_LoopInvariant)) { - if (IS_LINEAR_MONADIC(right, ETYPCON) && - right->rtype->type == right->u.monadic->rtype->type && - IS_TYPE_INT(right->rtype) && - right->rtype->size < right->u.monadic->rtype->size) - right = right->u.monadic; - - if (IS_LINEAR_DIADIC_2(right, EADD, ESUB)) { - ReorderOperandsForReductionPattern(left, right); - tmp = right->u.diadic.left; - if (IS_LINEAR_MONADIC(tmp, ETYPCON)) - tmp = tmp->u.monadic; - if (IS_LINEAR_MONADIC(tmp, EINDIRECT) && - (tmp->u.monadic->flags & IROLF_LoopInvariant) && - IRO_ExprsSame(left, tmp) && - right->u.diadic.right->type == IROLinearOp2Arg) { - if (right->u.diadic.right->nodetype == EADD) - return 1; - if (right->u.diadic.right->nodetype == ESUB) - return 1; - if (right->u.diadic.right->nodetype == EMUL) - return 1; - if (right->u.diadic.right->nodetype == EDIV) - return 1; - } - } - } - } else if (nd->nodetype == EADDASS || nd->nodetype == ESUBASS) { - left = nd->u.diadic.left; - right = nd->u.diadic.right; - - if (IS_LINEAR_MONADIC(right, ETYPCON) && - right->rtype->type == right->u.monadic->rtype->type && - IS_TYPE_INT(right->rtype) && - right->rtype->size < right->u.monadic->rtype->size) - right = right->u.monadic; - - if (IS_LINEAR_MONADIC(left, EINDIRECT) && - (left->u.monadic->flags & IROLF_LoopInvariant) && - right->type == IROLinearOp2Arg) { - if (right->nodetype == EADD) - return 1; - if (right->nodetype == ESUB) - return 1; - if (right->nodetype == EMUL) - return 1; - if (right->nodetype == EDIV) - return 1; - } - } - } - - return 0; -} - |