diff options
Diffstat (limited to 'compiler_and_linker/unsorted/IroUnrollLoop.c')
-rw-r--r-- | compiler_and_linker/unsorted/IroUnrollLoop.c | 2305 |
1 files changed, 0 insertions, 2305 deletions
diff --git a/compiler_and_linker/unsorted/IroUnrollLoop.c b/compiler_and_linker/unsorted/IroUnrollLoop.c deleted file mode 100644 index 45b774e..0000000 --- a/compiler_and_linker/unsorted/IroUnrollLoop.c +++ /dev/null @@ -1,2305 +0,0 @@ -#include "compiler/IroUnrollLoop.h" -#include "compiler/CError.h" -#include "compiler/IroFlowgraph.h" -#include "compiler/IroLinearForm.h" -#include "compiler/IroUtil.h" -#include "compiler/LoopDetection.h" -#include "compiler/IroLoop.h" -#include "compiler/IroDump.h" -#include "compiler/IroVars.h" -#include "compiler/CFunc.h" -#include "compiler/CMachine.h" - -#ifdef __MWERKS__ -#pragma options align=mac68k -#endif -typedef struct LoopList { - UInt8 flags; - BitVector *bv; - struct LoopList *next; - IRONode *fnode; - int xE; -} LoopList; -#ifdef __MWERKS__ -#pragma options align=reset -#endif - -// forward decls -static void IRO_FindLoops_Unroll(void); -static void LoopUnroll(int count, IRONode *fnode); -static int IsLoopUnrollable(IROLoop *loop); -static int IsDifferenceOfTermsConstant(IROAddrRecord *lowerRec, IROAddrRecord *upperRec, int isUnsigned, CInt64 *pval); -static IROLinear *BuildOrigIterationCount_DoWhile(IROList *list, IROLoop *loop); -static IROLinear *BuildPreAlignTemp(IROLoopInd *ind, UInt32 unrollFactor, IROList *list); -static IROLinear *BuildNewFinalvalue_DoWhile(IROLinear *iterCount, UInt32 unrollFactor, IROList *list, IROLoop *loop); -static IROLinear *BuildUnrolledFinalvalue_DoWhile(IROLinear *iterCount, UInt32 unrollFactor, IROList *list, IROLoop *loop); - -void IRO_LoopUnroller(void) { - VectorPhaseCalledFromUnroll = 1; - IRO_FindLoops_Unroll(); - IRO_CheckForUserBreak(); -} - -static void IRO_FindLoops_Unroll(void) { - IRONode *fnode; - IRONode *pred; - UInt16 i; - UInt16 flag; - LoopList *list; - LoopList *list2; - - fnode = IRO_FirstNode; - LoopList_First = NULL; - - while (fnode) { - 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) { - if (!LoopList_First) { - list = oalloc(sizeof(LoopList)); - list->next = NULL; - } else { - list = oalloc(sizeof(LoopList)); - list->next = LoopList_First; - } - LoopList_First = list; - - Bv_AllocVector(&list->bv, IRO_NumNodes + 1); - list->flags |= 1; - Bv_Copy(InLoop, list->bv); - list->fnode = fnode; - list->xE = 0; - } - - fnode = fnode->nextnode; - } - - list = LoopList_First; - Bv_AllocVector(&LoopTemp, IRO_NumNodes + 1); - while (list) { - for (list2 = LoopList_First; list2; list2 = list2->next) { - if (list2 != list) { - IRO_Dump(" header = %d \n", list2->fnode->index); - IRO_Dump(" l1 bit vector=\n"); - IRO_DumpBits("", list2->bv); - IRO_Dump(" l bit vector=\n"); - IRO_DumpBits("", list->bv); - if (Bv_IsSubset(list->bv, list2->bv)) - list2->flags &= ~1; - } - } - list = list->next; - } - - for (list = LoopList_First; list; list = list->next) { - if (list->flags & 1) { - IRONode *listfnode; - Bv_Copy(list->bv, InLoop); - listfnode = list->fnode; - IRO_Dump("IRO_FindLoops_Unroll:Found loop with header %d\n", listfnode->index); - IRO_DumpBits("Loop includes: ", InLoop); - LoopUnroll(copts.unrollfactor, listfnode); - IRO_UpdateFlagsOnInts(); - } - } -} - -static int CheckConstant(CInt64 a, CInt64 b, CInt64 *result) { - CInt64 shl = cint64_zero; - CInt64 work = cint64_zero; - CInt64 and = cint64_zero; - CInt64 i; - - for (i = cint64_zero; CInt64_Less(i, a); i = CInt64_Add(i, cint64_one)) { - shl = CInt64_Shl(b, i); - and = CInt64_And(shl, work); - if (CInt64_NotEqual(and, cint64_zero)) - return 0; - work = CInt64_Or(shl, work); - } - - *result = work; - return 1; -} - -typedef struct LoopPattern { - IROLinear *nd0; - IROLinear *nd4; - Type *type; - IROLinear *ndC; - IROLinear *nd10; - CInt64 val14; - CInt64 val1C; -} LoopPattern; - -static void UnrollWhileLoopBody(IRONode *header, IRONode *fnode2, IRONode *fnode3, IROLoop *loop, LoopPattern *pattern, UInt32 unrollFactor) { - IRONode *scan; - int pass; - IROLinear *firstnode; - IROLinear *lastnd; - IROLinear *nd; - IROLinear *nd1; - IROLinear *nd2; - IROLinear *nd3; - IROLinear *nd4; - IROLinear *nd5; - IROLinear *nd6; - IROLinear *nd8; - IROLinear *nd7; - ENode *expr; - IROList list; - CInt64 zero; - CInt64 shiftval; - - CInt64_SetLong(&zero, 0); - - pass = 0; - - do { - firstnode = NULL; - for (scan = fnode3; scan && scan != header; scan = scan->nextnode) { - IRO_InitList(&list); - lastnd = scan->last; - nd = scan->first; - while (1) { - if (nd->stmt) - nd->stmt->flags |= StmtFlag_10; - - if ( - (nd->index < loop->index20 || nd->index > loop->index24) && - nd->type != IROLinearLabel && - nd->type != IROLinearNop && - !(nd->flags & IROLF_Reffed) - ) - { - CError_ASSERT(345, nd->nodetype == EORASS || nd->nodetype == EANDASS || nd->nodetype == EXORASS); - - IRO_DuplicateExpr(pattern->nd0, &list); - nd1 = list.tail; - - shiftval = cint64_one; - shiftval = CInt64_Shl(shiftval, pattern->val1C); - - nd2 = IRO_NewLinear(IROLinearOperand); - nd2->index = ++IRO_NumLinear; - nd2->rtype = pattern->nd0->rtype; - expr = IRO_NewENode(EINTCONST); - expr->rtype = pattern->nd0->rtype; - CInt64_SetLong(&expr->data.intval, pass * CInt64_GetULong(&shiftval)); - nd2->u.node = expr; - IRO_AddToList(nd2, &list); - - IRO_DuplicateExpr(pattern->nd4, &list); - - nd3 = IRO_NewLinear(IROLinearOp2Arg); - nd3->index = ++IRO_NumLinear; - nd3->nodetype = EADD; - nd3->rtype = pattern->type; - nd3->u.diadic.left = list.tail; - nd3->u.diadic.right = nd2; - IRO_AddToList(nd3, &list); - - nd4 = IRO_NewLinear(IROLinearOp2Arg); - nd4->index = ++IRO_NumLinear; - nd4->nodetype = EADD; - nd4->rtype = pattern->type; - nd4->u.diadic.left = nd3; - nd4->u.diadic.right = nd1; - IRO_AddToList(nd4, &list); - - nd5 = IRO_NewLinear(IROLinearOp1Arg); - nd5->index = ++IRO_NumLinear; - nd5->nodetype = EINDIRECT; - nd5->rtype = nd->rtype; - nd5->u.monadic = nd4; - IRO_AddToList(nd5, &list); - - nd6 = IRO_NewLinear(IROLinearOp2Arg); - *nd6 = *nd; - nd6->index = ++IRO_NumLinear; - nd6->u.diadic.left = list.tail; - nd6->next = NULL; - - nd7 = IRO_NewLinear(IROLinearOperand); - nd7->index = ++IRO_NumLinear; - nd7->rtype = pattern->ndC->rtype; - expr = IRO_NewENode(EINTCONST); - expr->rtype = pattern->ndC->rtype; - nd7->u.node = expr; - nd7->next = NULL; - expr->data.intval = pattern->val14; - - if ( - IS_LINEAR_DIADIC(nd, EANDASS) && - CInt64_Equal(pattern->val14, cint64_zero) - ) - { - nd6->nodetype = EASS; - } else if ( - IS_LINEAR_DIADIC(nd, EORASS) && - !CTool_EndianReadWord32(&pattern->val14.hi) - ) - { - UInt32 tmp = CInt64_GetULong(&pattern->val14); - if ( - (nd->rtype->size == 1 && tmp == 0xFF) || - (nd->rtype->size == 2 && tmp == 0xFFFF) || - (nd->rtype->size == 4 && tmp == 0xFFFFFFFF) - ) - { - nd6->nodetype = EASS; - } - } - - IRO_AddToList(nd7, &list); - - if (IS_LINEAR_MONADIC(pattern->nd10, ETYPCON)) { - nd8 = IRO_NewLinear(IROLinearOp1Arg); - *nd8 = *pattern->nd10; - nd8->index = ++IRO_NumLinear; - nd8->u.monadic = nd7; - nd8->next = NULL; - IRO_AddToList(nd8, &list); - } else { - nd8 = nd7; - } - nd6->u.diadic.right = nd8; - IRO_AddToList(nd6, &list); - - if (!firstnode) - firstnode = list.head; - } - - if (nd == lastnd) - break; - nd = nd->next; - } - - if (list.head && list.tail) - IRO_Paste(list.head, list.tail, fnode2->last); - } - } while (++pass < 8); -} - -static int PatternMatchLoop(IRONode *fnode, IROLoop *loop, IROLoopInd *ind, UInt32 *unrollFactor, SInt32 *result1, SInt32 *result2, LoopPattern *pattern) { - IROLinear *scan; - IROLinear *varnode; - IROLinear *nd1; - IROLinear *nd2; - IROLinear *left1; - IROLinear *left2; - IROLinear *right1; - IROLinear *right2; - Object *obj1; - Object *obj2; - CInt64 shl; - CInt64 val; - - *result1 = 0; - *result2 = 0; - - if ((scan = fnode->first)) { - while (1) { - if ( - (scan->index < loop->index20 || scan->index > loop->index24) && - !(scan->flags & IROLF_Reffed) && - scan->type != IROLinearNop && - scan->type != IROLinearLabel - ) - { - if (IS_LINEAR_DIADIC_3(scan, EORASS, EXORASS, EANDASS)) { - (*result2)++; - if (IS_LINEAR_MONADIC(scan->u.diadic.left, EINDIRECT)) { - varnode = scan->u.diadic.left->u.monadic; - if (IS_LINEAR_DIADIC(varnode, EADD)) { - pattern->nd4 = varnode->u.diadic.left; - pattern->type = varnode->rtype; - if (IRO_IsVariable(varnode->u.diadic.left)) { - pattern->nd0 = varnode->u.diadic.right; - if ( - IS_LINEAR_DIADIC(pattern->nd0, ESHL) && - IRO_IsConstant(pattern->nd0->u.diadic.right) - ) - { - pattern->val1C = pattern->nd0->u.diadic.right->u.node->data.intval; - nd1 = pattern->nd0->u.diadic.left; - } else { - return 0; - } - } else { - return 0; - } - } else { - return 0; - } - } else { - return 0; - } - - pattern->nd10 = scan->u.diadic.right; - - if (IS_LINEAR_MONADIC(pattern->nd10, ETYPCON)) { - if (IS_LINEAR_DIADIC(scan, EANDASS)) { - if (IS_LINEAR_MONADIC(pattern->nd10->u.monadic, EBINNOT)) { - pattern->ndC = pattern->nd10->u.monadic->u.monadic; - } else { - return 0; - } - } else { - pattern->ndC = pattern->nd10->u.monadic; - } - - if (IS_LINEAR_DIADIC(pattern->ndC, ESHL) && IRO_IsConstant(pattern->ndC->u.diadic.left)) { - val = pattern->ndC->u.diadic.left->u.node->data.intval; - nd2 = pattern->ndC->u.diadic.right; - } else { - return 0; - } - } else if (IS_LINEAR_DIADIC(pattern->nd10, ESHL) && IS_LINEAR_DIADIC_2(scan, EORASS, EXORASS)) { - pattern->ndC = pattern->nd10; - if (IRO_IsConstant(pattern->ndC->u.diadic.left)) { - val = pattern->ndC->u.diadic.left->u.node->data.intval; - nd2 = pattern->ndC->u.diadic.right; - } else { - return 0; - } - } else if (IS_LINEAR_MONADIC(pattern->nd10, EBINNOT) && IS_LINEAR_DIADIC(scan, EANDASS)) { - pattern->ndC = pattern->nd10->u.monadic; - if (IS_LINEAR_DIADIC(pattern->ndC, ESHL) && IRO_IsConstant(pattern->ndC->u.diadic.left)) { - val = pattern->ndC->u.diadic.left->u.node->data.intval; - nd2 = pattern->ndC->u.diadic.right; - } else { - return 0; - } - } else { - return 0; - } - - if (IS_LINEAR_DIADIC(nd2, EAND) && IS_LINEAR_DIADIC(nd1, ESHR)) { - left1 = nd1->u.diadic.left; - left2 = nd2->u.diadic.left; - obj1 = IRO_IsVariable(left1); - obj2 = IRO_IsVariable(left2); - if (obj1 == obj2 && obj1 == ind->var->object) { - right1 = nd1->u.diadic.right; - right2 = nd2->u.diadic.right; - if (IRO_IsConstant(right1) && IRO_IsConstant(right2)) { - shl = cint64_one; - shl = CInt64_Shl(shl, right1->u.node->data.intval); - shl = CInt64_Sub(shl, cint64_one); - if (CInt64_Equal(shl, right2->u.node->data.intval)) { - if (CTool_EndianReadWord32(&shl.hi) == 0) { - *unrollFactor = CInt64_GetULong(&shl) + 1; - if (CheckConstant(CInt64_Add(shl, cint64_one), val, &pattern->val14)) { - (*result1)++; - if (IS_LINEAR_DIADIC(scan, EANDASS)) - pattern->val14 = CInt64_Not(pattern->val14); - } - } else { - return 0; - } - } else { - return 0; - } - } else { - return 0; - } - } else { - return 0; - } - } else { - return 0; - } - } else { - return 0; - } - } - - if (scan == fnode->last) - break; - scan = scan->next; - } - } - - return 1; -} - -static UInt32 UnrollWhileLoop(IRONode *header, IRONode *fnode2, IRONode *fnode3, IROLoop *loop, UInt32 unrollFactor) { - IROLoopInd *ind; - IRONode *scan; - CLabel *lastlabel; - IROLinear *lastlabelnode; - IROLinear *earlyLoopExitTest; - CLabel *earlyLoopExitTestLabel; - IROLinear *origIterationCount; - IROLinear *unrolledFinalValue; - IROLinear *preAlignTemp; - IROLinear *newFinalValue; - IROLinear *savedHead60; - IROLinear *unrolledBodyEntryTest; - CLabel *label; - IROLinear *savedHead2; - IROLinear *loophead25; - IROLinear *loopend; - IROLinear *loopscan; - IROLinear *indvar; - IROLinear *less; - IROLinear *loopExitTest; - IROLinear *saveTail; - CLabel *label2; - IROLinear *gotond; - CLabel *label3; - IROLinear *savedHead3; - IROLinear *updIndInc; - IROLinear *label2nd; - IROLinear *less2; - IROLinear *saveTail2; - IROLinear *less3; - IROLinear *wtf; - IROLinear *constnd; - IROLinear *ass; - IROLinear *nd18; - IRONode *fn19; - IRONode *newfnode1; - IRONode *newfnode2; - IRONode *newfnode3; - IRONode *newfnode4; - IRONode *newfnode5; - IRONode *newfnode6; - IRONode *newfnode7; - IRONode *newfnode8; - IROLinear *lastnd; - ENode *expr; - SInt32 result1; - SInt32 result2; - LoopPattern pattern; - IROList list; - - IRO_Dump("while(n--) loop \n"); - - if (loop->flags & LoopFlags_800) { - IRO_Dump("loop not unrolled because induction used in loop \n"); - return 0; - } - if (loop->flags & LoopFlags_1000) { - IRO_Dump("loop not unrolled because loop has multiple exits \n"); - return 0; - } - - if (!(loop->flags & LP_HAS_MULTIPLE_INDUCTIONS)) - return 0; - - for (ind = FirstInd; ind; ind = ind->next) { - if ((ind->flags & LoopInd_HasMod) && (ind->flags & LoopInd_HasDiv)) - break; - } - - if (!ind) { - IRO_Dump("Could not find loop with and induction with MOD and DIV operation\n"); - return 0; - } - - if (!IRO_IsUnsignedType(ind->nd->rtype)) - return 0; - - if (ind->nd->type == IROLinearOp2Arg) { - if (ind->nd->nodetype == EADDASS && IRO_IsConstant(ind->nd->u.diadic.right)) { - if (ind->addConst != 1) - return 0; - } else if (ind->nd->nodetype == EASS) { - if ( - ind->nd->u.diadic.right->type != IROLinearOp2Arg || - ind->nd->u.diadic.right->nodetype != EADD || - !IRO_IsConstant(ind->nd->u.diadic.right->u.diadic.right) - ) - return 0; - - if (ind->addConst != 1) - return 0; - } else { - return 0; - } - } else if (ind->nd->type == IROLinearOp1Arg && ind->nd->nodetype != EPREINC && ind->nd->nodetype != EPOSTINC) { - return 0; - } - - loop->induction = ind; - loop->index24 = ind->nd->index; - loop->index20 = IRO_FindStart(ind->nd)->index; - - scan = IRO_FirstNode; - memset(&pattern, 0, sizeof(pattern)); - while (scan) { - if (Bv_IsBitSet(scan->index, InLoop) && scan != header) { - if (!PatternMatchLoop(scan, loop, ind, &unrollFactor, &result1, &result2, &pattern)) - return 0; - } - scan = scan->nextnode; - } - - if (result1 > 1 || result2 > 1) - return 0; - - lastlabel = fnode2->last->u.label.label; - lastlabelnode = IRO_FindLabelNode(fnode2->last->u.label.label, fnode2->last); - - IRO_InitList(&list); - IRO_DuplicateExprRange(lastlabelnode->next, LoopNode->last->u.label.x4->u.diadic.left, &list); - IRO_DuplicateExpr(LoopNode->last->u.label.x4, &list); - IRO_Paste(list.head, list.tail, fnode2->last); - lastlabelnode = list.tail; - - IRO_InitList(&list); - earlyLoopExitTest = BuildEarlyLoopExitTest(LoopNode->last->type, &list); - earlyLoopExitTestLabel = IRO_NewLabel(); - earlyLoopExitTest->u.label.label = earlyLoopExitTestLabel; - earlyLoopExitTest->u.label.x4 = lastlabelnode; - earlyLoopExitTest->u.label.x4->flags |= IROLF_Reffed; - earlyLoopExitTest->rtype = LoopNode->last->rtype; - IRO_Paste(list.head, list.tail, fnode2->last); - - IRO_InitList(&list); - origIterationCount = BuildOrigIterationCount_DoWhile(&list, loop); - IRO_Paste(list.head, list.tail, fnode2->last); - savedHead60 = list.head; - - IRO_InitList(&list); - preAlignTemp = BuildPreAlignTemp(ind, unrollFactor, &list); - IRO_Paste(list.head, list.tail, fnode2->last); - - IRO_InitList(&list); - unrolledFinalValue = BuildUnrolledFinalvalue_DoWhile(origIterationCount, unrollFactor, &list, loop); - IRO_Paste(list.head, list.tail, fnode2->last); - - IRO_InitList(&list); - newFinalValue = BuildNewFinalvalue_DoWhile(origIterationCount, unrollFactor, &list, loop); - IRO_Paste(list.head, list.tail, fnode2->last); - - IRO_InitList(&list); - BuildUnrolledBodyEntryTest(&list, origIterationCount, unrollFactor, lastlabel); - IRO_Paste(list.head, list.tail, fnode2->last); - unrolledBodyEntryTest = list.tail; - - IRO_InitList(&list); - label = BuildLabel(&list); - IRO_Paste(list.head, list.tail, fnode2->last); - - savedHead2 = list.head; - loophead25 = NULL; - for (scan = fnode3; scan && scan != header; scan = scan->nextnode) { - IRO_InitList(&list); - loopend = scan->last; - loopscan = scan->first; - while (1) { - if (loopscan->stmt) - loopscan->stmt->flags |= StmtFlag_10; - if (loopscan->type != IROLinearLabel && !(loopscan->flags & IROLF_Reffed)) { - IRO_DuplicateExpr(loopscan, &list); - if (!loophead25) - loophead25 = list.head; - } - if (loopscan == loopend) - break; - loopscan = loopscan->next; - } - - if (list.head && list.tail) - IRO_Paste(list.head, list.tail, fnode2->last); - } - - IRO_InitList(&list); - - if (ind->nd->type == IROLinearOp1Arg) - IRO_DuplicateExpr(ind->nd->u.monadic, &list); - else - IRO_DuplicateExpr(ind->nd->u.diadic.left, &list); - list.tail->flags &= ~IROLF_Assigned; - indvar = list.tail; - - IRO_DuplicateExpr(preAlignTemp, &list); - list.tail->flags &= ~IROLF_Assigned; - - less = IRO_NewLinear(IROLinearOp2Arg); - less->nodetype = ELESS; - less->rtype = TYPE(&stbool); - less->index = ++IRO_NumLinear; - less->next = NULL; - less->u.diadic.left = indvar; - less->u.diadic.right = list.tail; - IRO_AddToList(less, &list); - less->flags |= IROLF_Reffed; - - loopExitTest = BuildLoopExitTest(LoopNode->last->type, &list); - loopExitTest->u.label.label = label; - loopExitTest->u.label.x4 = less; - loopExitTest->u.label.x4->flags |= IROLF_Reffed; - loopExitTest->rtype = LoopNode->last->rtype; - IRO_Paste(list.head, list.tail, fnode2->last); - saveTail = list.tail; - - IRO_InitList(&list); - label2 = IRO_NewLabel(); - gotond = IRO_NewLinear(IROLinearOp1Arg); - gotond->index = ++IRO_NumLinear; - gotond->type = IROLinearGoto; - gotond->u.label.label = label2; - IRO_AddToList(gotond, &list); - IRO_Paste(list.head, list.tail, fnode2->last); - - IRO_InitList(&list); - label3 = BuildLabel(&list); - IRO_Paste(list.head, list.tail, fnode2->last); - savedHead3 = list.head; - - UnrollWhileLoopBody(header, fnode2, fnode3, loop, &pattern, unrollFactor); - updIndInc = UpdateInductionIncrement(loop, 8 * unrollFactor, fnode2->last); - - IRO_InitList(&list); - label2nd = IRO_NewLinear(IROLinearLabel); - label2nd->index = IRO_NumLinear++; - label2nd->u.label.label = label2; - label2nd->flags |= IROLF_1; - IRO_AddToList(label2nd, &list); - IRO_Paste(list.head, list.tail, fnode2->last); - - IRO_InitList(&list); - - if (ind->nd->type == IROLinearOp1Arg) - IRO_DuplicateExpr(ind->nd->u.monadic, &list); - else - IRO_DuplicateExpr(ind->nd->u.diadic.left, &list); - list.tail->flags &= ~IROLF_Assigned; - indvar = list.tail; - - IRO_DuplicateExpr(unrolledFinalValue, &list); - list.tail->flags &= ~IROLF_Assigned; - - less2 = IRO_NewLinear(IROLinearOp2Arg); - less2->nodetype = ELESS; - less2->rtype = TYPE(&stbool); - less2->index = ++IRO_NumLinear; - less2->next = NULL; - less2->u.diadic.left = indvar; - less2->u.diadic.right = list.tail; - IRO_AddToList(less2, &list); - less2->flags |= IROLF_Reffed; - - loopExitTest = BuildLoopExitTest(LoopNode->last->type, &list); - loopExitTest->u.label.label = label3; - loopExitTest->u.label.x4 = less2; - loopExitTest->u.label.x4->flags |= IROLF_Reffed; - loopExitTest->rtype = LoopNode->last->rtype; - IRO_Paste(list.head, list.tail, fnode2->last); - saveTail2 = list.tail; - - IRO_InitList(&list); - - if (ind->nd->type == IROLinearOp1Arg) - IRO_DuplicateExpr(ind->nd->u.monadic, &list); - else - IRO_DuplicateExpr(ind->nd->u.diadic.left, &list); - list.tail->flags &= ~IROLF_Assigned; - indvar = list.tail; - - IRO_DuplicateExpr(newFinalValue, &list); - list.tail->flags &= ~IROLF_Assigned; - - less3 = IRO_NewLinear(IROLinearOp2Arg); - less3->nodetype = ELESS; - less3->rtype = TYPE(&stbool); - less3->index = ++IRO_NumLinear; - less3->next = NULL; - less3->u.diadic.left = indvar; - less3->u.diadic.right = list.tail; - IRO_AddToList(less3, &list); - less3->flags |= IROLF_Reffed; - - wtf = LoopNode->last->u.label.x4; - IRO_Paste(list.head, list.tail, LoopNode->last); - LoopNode->last->u.label.x4 = list.tail; - - IRO_InitList(&list); - - constnd = IRO_NewLinear(IROLinearOperand); - constnd->index = ++IRO_NumLinear; - expr = IRO_NewENode(EINTCONST); - expr->rtype = wtf->u.diadic.left->rtype; - expr->data.intval = cint64_zero; - constnd->u.node = expr; - constnd->rtype = expr->rtype; - IRO_AddToList(constnd, &list); - constnd->flags |= IROLF_Reffed; - - IRO_DuplicateExpr(wtf->u.diadic.left, &list); - - ass = IRO_NewLinear(IROLinearOp2Arg); - ass->nodetype = EASS; - ass->rtype = list.tail->rtype; - ass->index = ++IRO_NumLinear; - ass->next = NULL; - ass->u.diadic.left = list.tail; - ass->u.diadic.right = constnd; - IRO_AddToList(ass, &list); - ass->flags |= IROLF_Assigned; - - IRO_NopOut(wtf); - - fn19 = fnode2->nextnode; - nd18 = fnode2->last; - fnode2->last = earlyLoopExitTest; - - newfnode1 = IRO_NewFlowGraphNode(); - newfnode1->first = savedHead60; - newfnode1->last = unrolledBodyEntryTest; - fnode2->nextnode = newfnode1; - - newfnode2 = IRO_NewFlowGraphNode(); - newfnode2->first = savedHead2; - newfnode2->last = saveTail; - savedHead2->u.label.label->stmt = (Statement *) newfnode2; - newfnode1->nextnode = newfnode2; - - newfnode3 = IRO_NewFlowGraphNode(); - newfnode3->first = gotond; - newfnode3->last = gotond; - newfnode2->nextnode = newfnode3; - - newfnode4 = IRO_NewFlowGraphNode(); - newfnode4->first = savedHead3; - newfnode4->last = updIndInc; - savedHead3->u.label.label->stmt = (Statement *) newfnode4; - newfnode3->nextnode = newfnode4; - - newfnode5 = IRO_NewFlowGraphNode(); - newfnode5->first = label2nd; - newfnode5->last = saveTail2; - label2nd->u.label.label->stmt = (Statement *) newfnode5; - newfnode4->nextnode = newfnode5; - - newfnode6 = IRO_NewFlowGraphNode(); - newfnode6->first = nd18; - newfnode6->last = nd18; - newfnode5->nextnode = newfnode6; - newfnode6->nextnode = fn19; - - newfnode7 = oalloc(sizeof(IRONode)); - memset(newfnode7, 0, sizeof(IRONode)); - newfnode7->index = IRO_NumNodes; - IRO_NumNodes++; - - newfnode7->first = list.head; - newfnode7->last = list.tail; - - list.tail->next = LoopNode->last->next; - LoopNode->last->next = list.head; - - newfnode7->nextnode = LoopNode->nextnode; - LoopNode->nextnode = newfnode7; - - newfnode8 = oalloc(sizeof(IRONode)); - memset(newfnode8, 0, sizeof(IRONode)); - newfnode8->index = IRO_NumNodes; - IRO_NumNodes++; - - lastnd = IRO_NewLinear(IROLinearLabel); - lastnd->index = IRO_NumLinear++; - lastnd->next = NULL; - lastnd->u.label.label = earlyLoopExitTestLabel; - lastnd->flags |= IROLF_1; - earlyLoopExitTestLabel->stmt = (Statement *) newfnode8; - - newfnode8->first = lastnd; - newfnode8->last = lastnd; - - lastnd->next = newfnode7->last->next; - newfnode7->last->next = lastnd; - - newfnode8->nextnode = newfnode7->nextnode; - newfnode7->nextnode = newfnode8; - - return 1; -} - -void IRO_IterateForLoopBody(IRONode *start, IRONode *end, IROLoop *loop, IROLinear *destnode, SInt32 addConst, CInt64 *val, Boolean funkyFlag) { - IROLinear *first = NULL; - IROLinear *last = NULL; - IRONode *fnode; - IROLinear *lastnd; - IROLinear *nd; - IROList list; - - for (fnode = start; fnode && fnode != end; fnode = fnode->nextnode) { - IRO_InitList(&list); - - lastnd = fnode->last; - nd = fnode->first; - while (1) { - if (nd->stmt) - nd->stmt->flags |= StmtFlag_10; - - if ( - (nd->index < loop->index20 || nd->index > loop->index24) && - nd->type != IROLinearLabel && - !(nd->flags & IROLF_Reffed) - ) - { - IRO_DuplicateExpr(nd, &list); - if (!first) - first = list.head; - last = list.tail; - } - - if (nd == lastnd) - break; - nd = nd->next; - } - - if (list.head && list.tail) - IRO_Paste(list.head, list.tail, destnode); - } - - if (funkyFlag) { - *val = CInt64_Add(*val, IRO_MakeLong(loop->induction->addConst)); - ChangeInductionReference(first, last, *val, loop); - } -} - -void IRO_LinearizeForLoopPostLoop(IRONode *fnode1, IRONode *fnode2, IROLoop *loop, IRONode *fnode3, UInt32 unrollFactor) { - IRONode *newfnode; - IROLinear *newnd; - SInt32 i; - CInt64 val; - - newfnode = oalloc(sizeof(IRONode)); - memset(newfnode, 0, sizeof(IRONode)); - newfnode->index = IRO_NumNodes; - IRO_NumNodes++; - - newnd = IRO_NewLinear(IROLinearNop); - newnd->index = IRO_NumLinear++; - newnd->next = NULL; - newnd->flags |= IROLF_1; - - newfnode->first = newfnode->last = newnd; - - newfnode->nextnode = fnode3->nextnode; - fnode3->nextnode = newfnode; - - newnd->next = fnode3->last->next; - fnode3->last->next = newnd; - - val = cint64_zero; - for (i = 0; i < unrollFactor; i++) - IRO_IterateForLoopBody(fnode2, fnode1, loop, newfnode->last, loop->induction->addConst, &val, i > 0); - UpdateInductionIncrement(loop, unrollFactor, newfnode->last); -} - -static UInt32 UnrollForLoop(IRONode *header, IRONode *fnode2, IRONode *fnode3, IROLoop *loop, UInt32 unrollFactor) { - IROLinear *lastlabelnode; - IROLinear *earlyLoopExitTest; - IROLinear *origIterationCount; - IROLinear *saveHead1; - IROLinear *newFinalValue; - IROLinear *unrolledBodyEntryTest; - IROLinear *gotoNd; - IROLinear *saveHead2; - IROLinear *updIndInc; - IROLinear *labelNd; - IROLinear *saveTail2; - IROLinear *ndCopy; - IROLinear *saveTail3; - IROLinear *loopExitTest; - IROLinear *lastnd; - IROLinear *labelNd2; - IROLinear *saveTail4; - IROLinear *labelNd3; - IROLinear *scan; - IRONode *nd18; - IRONode *newfnode1; - IRONode *newfnode2; - IRONode *newfnode3; - IRONode *newfnode4; - IRONode *newfnode5; - IRONode *newfnode6; - CLabel *lastlabel; - CLabel *earlyLoopExitTestLabel; - CLabel *label; - CLabel *label2; - SInt32 i; - - IROList list; - CInt64 iterCount; - int isConstant; - UInt32 needOrigLoop = 0; - UInt32 needUnrollBodyTest = 0; - UInt32 resetUnrolledFinalValue = 0; - SInt32 leftOver; - CInt64 val; - - lastlabelnode = IRO_FindLabelNode(fnode2->last->u.label.label, fnode2->last); - lastlabel = IRO_NewLabel(); - - IRO_InitList(&list); - IRO_DuplicateExprRange(lastlabelnode->next, LoopNode->last->u.label.x4, &list); - IRO_DuplicateExpr(LoopNode->last->u.label.x4, &list); - IRO_Paste(list.head, list.tail, fnode2->last); - lastlabelnode = list.tail; - - IRO_InitList(&list); - earlyLoopExitTest = BuildEarlyLoopExitTest(LoopNode->last->type, &list); - earlyLoopExitTestLabel = IRO_NewLabel(); - earlyLoopExitTest->u.label.label = earlyLoopExitTestLabel; - earlyLoopExitTest->u.label.x4 = lastlabelnode; - earlyLoopExitTest->u.label.x4->flags |= IROLF_Reffed; - earlyLoopExitTest->rtype = LoopNode->last->rtype; - IRO_Paste(list.head, list.tail, fnode2->last); - - isConstant = IsIterationCountConstant(loop, &iterCount); - needOrigLoop = 1; - needUnrollBodyTest = 1; - resetUnrolledFinalValue = 0; - if (isConstant) - IRO_TestConstantIterationCount(loop, &iterCount, 1, &unrollFactor, &leftOver, &needOrigLoop, &needUnrollBodyTest, &resetUnrolledFinalValue); - - IRO_InitList(&list); - origIterationCount = BuildOrigIterationCount(&list, loop); - IRO_Paste(list.head, list.tail, fnode2->last); - saveHead1 = list.head; - - IRO_InitList(&list); - newFinalValue = BuildNewFinalvalue(origIterationCount, unrollFactor, &list, loop); - IRO_Paste(list.head, list.tail, fnode2->last); - - IRO_InitList(&list); - BuildUnrolledBodyEntryTest(&list, origIterationCount, unrollFactor, lastlabel); - IRO_Paste(list.head, list.tail, fnode2->last); - unrolledBodyEntryTest = list.tail; - - label = IRO_NewLabel(); - IRO_InitList(&list); - gotoNd = IRO_NewLinear(IROLinearOp1Arg); - gotoNd->index = ++IRO_NumLinear; - gotoNd->type = IROLinearGoto; - gotoNd->u.label.label = label; - IRO_AddToList(gotoNd, &list); - IRO_Paste(list.head, list.tail, fnode2->last); - - IRO_InitList(&list); - label2 = BuildLabel(&list); - IRO_Paste(list.head, list.tail, fnode2->last); - saveHead2 = list.head; - - val = cint64_zero; - for (i = 0; i < unrollFactor; i++) - IRO_IterateForLoopBody(fnode3, header, loop, fnode2->last, loop->induction->addConst, &val, i > 0); - updIndInc = UpdateInductionIncrement(loop, unrollFactor, fnode2->last); - - IRO_InitList(&list); - labelNd = IRO_NewLinear(IROLinearLabel); - labelNd->index = IRO_NumLinear++; - labelNd->u.label.label = label; - labelNd->flags |= IROLF_1; - IRO_AddToList(labelNd, &list); - IRO_Paste(list.head, list.tail, fnode2->last); - - IRO_InitList(&list); - - IRO_DuplicateExpr(LoopNode->last->u.label.x4->u.diadic.left, &list); - saveTail2 = list.tail; - - if (resetUnrolledFinalValue) - IRO_DuplicateExpr(loop->nd18->u.diadic.right, &list); - else - IRO_DuplicateExpr(newFinalValue, &list); - - ndCopy = IRO_NewLinear(LoopNode->last->u.label.x4->type); - *ndCopy = *LoopNode->last->u.label.x4; - ndCopy->index = ++IRO_NumLinear; - ndCopy->next = NULL; - ndCopy->expr = NULL; - ndCopy->u.diadic.left = saveTail2; - ndCopy->u.diadic.right = list.tail; - IRO_AddToList(ndCopy, &list); - - IRO_Paste(list.head, list.tail, fnode2->last); - saveTail3 = list.tail; - - IRO_InitList(&list); - loopExitTest = BuildLoopExitTest(LoopNode->last->type, &list); - loopExitTest->u.label.label = label2; - loopExitTest->u.label.x4 = saveTail3; - loopExitTest->u.label.x4->flags |= IROLF_Reffed; - loopExitTest->rtype = LoopNode->last->rtype; - IRO_Paste(list.head, list.tail, fnode2->last); - saveTail4 = list.tail; - - IRO_InitList(&list); - labelNd2 = IRO_NewLinear(IROLinearLabel); - labelNd2->index = IRO_NumLinear++; - labelNd2->u.label.label = lastlabel; - labelNd2->flags |= IROLF_1; - IRO_AddToList(labelNd2, &list); - IRO_Paste(list.head, list.tail, fnode2->last); - - lastnd = fnode2->last; - nd18 = fnode2->nextnode; - fnode2->last = earlyLoopExitTest; - - newfnode1 = IRO_NewFlowGraphNode(); - newfnode1->first = saveHead1; - newfnode1->last = unrolledBodyEntryTest; - fnode2->nextnode = newfnode1; - - newfnode2 = IRO_NewFlowGraphNode(); - newfnode2->first = gotoNd; - newfnode2->last = gotoNd; - newfnode1->nextnode = newfnode2; - - newfnode3 = IRO_NewFlowGraphNode(); - newfnode3->first = saveHead2; - newfnode3->last = updIndInc; - - saveHead2->u.label.label->stmt = (Statement *) newfnode3; - if (newfnode2) - newfnode2->nextnode = newfnode3; - else - newfnode1->nextnode = newfnode3; - - newfnode4 = IRO_NewFlowGraphNode(); - newfnode4->first = labelNd; - newfnode4->last = saveTail4; - labelNd->u.label.label->stmt = (Statement *) newfnode4; - newfnode3->nextnode = newfnode4; - - newfnode5 = IRO_NewFlowGraphNode(); - newfnode5->first = labelNd2; - newfnode5->last = lastnd; - newfnode4->nextnode = newfnode5; - newfnode5->nextnode = nd18; - - newfnode6 = oalloc(sizeof(IRONode)); - memset(newfnode6, 0, sizeof(IRONode)); - newfnode6->index = IRO_NumNodes; - IRO_NumNodes++; - - labelNd3 = IRO_NewLinear(IROLinearLabel); - labelNd3->index = IRO_NumLinear++; - labelNd3->next = NULL; - labelNd3->u.label.label = earlyLoopExitTestLabel; - labelNd3->flags |= IROLF_1; - earlyLoopExitTestLabel->stmt = (Statement *) newfnode6; - - newfnode6->first = labelNd3; - newfnode6->last = labelNd3; - - labelNd3->next = LoopNode->last->next; - LoopNode->last->next = labelNd3; - - newfnode6->nextnode = LoopNode->nextnode; - LoopNode->nextnode = newfnode6; - - if (!needOrigLoop) { - NoOpBlock(newfnode5); - NoOpBlock(header); - NoOpBlock(fnode3); - NoOpBlock(loop->induction->fnode); - IRO_NopOut(newfnode1->last->u.label.x4); - newfnode1->last->type = IROLinearNop; - } - - if (!needUnrollBodyTest) { - IRO_NopOut(earlyLoopExitTest->u.label.x4); - earlyLoopExitTest->type = IROLinearNop; - - IRO_NopOut(newfnode4->last->u.label.x4); - newfnode4->last->type = IROLinearNop; - - if (newfnode2) - newfnode2->last->type = IROLinearNop; - - for (scan = newfnode1->first; scan; scan = scan->next) { - if (!(scan->flags & IROLF_Reffed)) - IRO_NopOut(scan); - if (scan == newfnode1->last) - break; - } - } - - return 1; -} - -static UInt32 UnrollStandardLoop(IRONode *header, IRONode *fnode2, IRONode *fnode3, int count) { - IROLoop *loop; - - ConditionalHeaderAtBottom = 1; - loop = ExtractLoopInfo(header); - loop->xC = fnode2; - loop->x10 = fnode3; - FindAssignmenttoInductionVar(loop, fnode2); - - if (!IsLoopUnrollable(loop)) { - IRO_Dump("LoopUnroll:loop with header %d not unrolled because IsLoopUnrollable failed\n", header->index); - return 0; - } - - if (loop->flags & LoopFlags_10000) - return UnrollWhileLoop(header, fnode2, fnode3, loop, count); - else - return UnrollForLoop(header, fnode2, fnode3, loop, count); -} - -static void LoopUnroll(int count, IRONode *header) { - VarRecord *var; - IRONode *tmp; - UInt16 i; - UInt16 j; - IRONode *prevpred; - IRONode *prevsucc; - int foundpred; - UInt32 predcount; - UInt32 success = 0; - - LoopNode = header; - FindMustReach(); - - for (var = IRO_FirstVar; var; var = var->next) - var->xA = 1; - - ComputeLoopKills(); - ComputeLoopInvariance(); - ComputeLoopInduction(); - - LoopNode = header; - ConditionalHeaderAtBottom = 0; - - prevpred = NULL; - foundpred = 0; - for (i = 0; i < LoopNode->numpred; i++) { - tmp = IRO_NodeTable[LoopNode->pred[i]]; - if (!Bv_IsBitSet(tmp->index, InLoop)) { - foundpred = 1; - if (tmp->nextnode == header) { - CError_ASSERT(2101, !prevpred || tmp == prevpred); - prevpred = tmp; - } - } - } - - if (!foundpred) { - IRO_Dump("No predecessor outside the loop\n"); - return; - } - - if (LoopNode->last->type == IROLinearIf || LoopNode->last->type == IROLinearIfNot) { - if (LoopNode->nextnode && !Bv_IsBitSet(LoopNode->nextnode->index, InLoop)) { - prevsucc = NULL; - for (i = 0; i < LoopNode->numsucc; i++) { - tmp = IRO_NodeTable[LoopNode->succ[i]]; - if (Bv_IsBitSet(tmp->index, InLoop)) { - CError_ASSERT(2159, !prevsucc); - prevsucc = tmp; - } - } - - prevpred = NULL; - predcount = 0; - for (j = 0; j < LoopNode->numpred; j++) { - tmp = IRO_NodeTable[LoopNode->pred[j]]; - if (!Bv_IsBitSet(tmp->index, InLoop)) { - prevpred = tmp; - predcount++; - } - } - - if ( - predcount == 1 && - prevpred->last->type == IROLinearGoto && - prevpred->nextnode == prevsucc && - prevsucc != LoopNode - ) - { - success = UnrollStandardLoop(header, prevpred, prevsucc, count); - } - } - } else { - IRO_Dump(" LoopUnroll:Loop with header = %d is not a conditional loop\n", header->index); - } - - if (!success) - return; - - IRO_NodeTable = oalloc(sizeof(IRONode *) * IRO_NumNodes); - memset(IRO_NodeTable, 0, sizeof(IRONode *) * IRO_NumNodes); - for (tmp = IRO_FirstNode; tmp; tmp = tmp->nextnode) - IRO_NodeTable[tmp->index] = tmp; - IRO_ComputeSuccPred(); - IRO_ComputeDom(); - if (success) - IRO_Dump(" LoopUnroll:Loop with header = %d Unrolled\n", header->index); -} - -static int IsLoopUnrollable(IROLoop *loop) { - CInt64 tmp; - - if (loop->flags & LP_LOOP_HAS_ASM) { - IRO_Dump("IsLoopUnrollable:No due to LP_LOOP_HAS_ASM \n"); - return 0; - } - if (loop->flags & LP_IFEXPR_NON_CANONICAL) { - IRO_Dump("IsLoopUnrollable:No due to LP_IFEXPR_NON_CANONICAL \n"); - return 0; - } - if (loop->flags & LP_LOOP_HAS_CALLS) { - IRO_Dump("IsLoopUnrollable:No due to LP_LOOP_HAS_CALLS \n"); - return 0; - } - if (loop->flags & LP_LOOP_HAS_CNTRLFLOW) { - IRO_Dump("IsLoopUnrollable:No due to LP_LOOP_HAS_CNTRLFLOW \n"); - return 0; - } - if (loop->flags & LP_INDUCTION_NOT_FOUND) { - IRO_Dump("IsLoopUnrollable:No due to LP_INDUCTION_NOT_FOUND \n"); - return 0; - } - if (loop->flags & LP_LOOP_HDR_HAS_SIDEEFFECTS) { - IRO_Dump("IsLoopUnrollable:No due to LP_LOOP_HDR_HAS_SIDEEFFECTS \n"); - return 0; - } - if (!(loop->flags & LoopFlags_200)) { - IRO_Dump("IsLoopUnrollable:No because header does not follow induction update \n"); - return 0; - } - - if (!(loop->flags & LoopFlags_10000)) { - IROLinear *upperBound = loop->nd18->u.diadic.right; - if (!IRO_IsIntConstant(upperBound) && !(upperBound->flags & IROLF_LoopInvariant)) { - IRO_Dump("IsLoopUnrollable:No because Loop Upper Bound is Variant in the loop\n"); - return 0; - } - if (!loop->nd14) { - IRO_Dump("IsLoopUnrollable:No because there is no initialization of loop index in PreHeader\n"); - return 0; - } - if (!IRO_IsVariable(loop->nd14->u.diadic.left)) { - IRO_Dump("IsLoopUnrollable:No because initial value of induction stored thru pointer\n"); - return 0; - } - - if (!IRO_IsUnsignedType(loop->nd14->rtype)) { - if (IRO_IsIntConstant(loop->nd14->u.diadic.right)) { - if (!CInt64_GreaterEqual(loop->nd14->u.diadic.right->u.node->data.intval, cint64_zero)) { - IRO_Dump("IsLoopUnrollable:No because initial value of induction is signed but init < 0\n"); - return 0; - } - } else if (IsIterationCountConstant(loop, &tmp)) { - IRO_Dump("IsLoopUnrollable:Yes, the limits substract out to be constants\n"); - } else { - IRO_Dump("IsLoopUnrollable:No because initial value of induction is signed and not constant\n"); - return 0; - } - } - - if (!(loop->flags & LP_LOOP_STEP_ISADD)) { - IRO_Dump("IsLoopUnrollable:No because LP_LOOP_STEP_ISADD is not set i.e induciton is not updated by 1\n"); - return 0; - } - - } else { - if (!IRO_IsUnsignedType(loop->nd18->u.diadic.left->rtype)) { - IRO_Dump("IsLoopUnrollable:No because the while loop induction is signed\n"); - return 0; - } - if (!(loop->flags & LoopFlags_2000)) { - IRO_Dump("IsLoopUnrollable:No because the while loop operator is not of decrement form\n"); - return 0; - } - } - - if (loop->sizeBySomeMeasurement > copts.unrollinstrfactor) { - IRO_Dump("IsLoopUnrollable:No because loop size greater than threshold\n"); - return 0; - } - - return 1; -} - -IROLinear *BuildEarlyLoopExitTest(IROLinearType type, IROList *list) { - IROLinear *nd = IRO_NewLinear(IROLinearOp1Arg); - nd->index = ++IRO_NumLinear; - if (type == IROLinearIf) - nd->type = IROLinearIfNot; - else - nd->type = IROLinearIf; - IRO_AddToList(nd, list); - return nd; -} - -IROLinear *BuildLoopExitTest(IROLinearType type, IROList *list) { - IROLinear *nd = IRO_NewLinear(IROLinearOp1Arg); - nd->index = ++IRO_NumLinear; - nd->type = type; - IRO_AddToList(nd, list); - return nd; -} - -int IsIterationCountConstant(IROLoop *loop, CInt64 *pval) { - IROLinear *lowerBound; - IROLinear *upperBound; - Type *type; - int isUnsigned; - IROAddrRecord *lowerRec; - IROAddrRecord *upperRec; - CInt64 lowerval; - CInt64 upperval; - CInt64 incval; - CInt64 negOne; - - lowerBound = loop->nd14->u.diadic.right; - if (loop->flags & LoopFlags_1) { - upperBound = loop->nd18->u.diadic.right; - type = loop->nd18->u.diadic.right->rtype; - } else { - upperBound = loop->nd18->u.diadic.left; - type = loop->nd18->u.diadic.left->rtype; - } - - isUnsigned = IRO_IsUnsignedType(type); - - if (IRO_IsIntConstant(lowerBound) && IRO_IsIntConstant(upperBound)) { - lowerval = lowerBound->u.node->data.intval; - upperval = upperBound->u.node->data.intval; - if (isUnsigned) { - if (CInt64_LessEqualU(upperval, lowerval)) - return 0; - } else { - if (CInt64_LessEqual(upperval, lowerval)) - return 0; - } - - CInt64_SetLong(&incval, loop->induction->addConst); - CInt64_SetLong(&negOne, -1); - *pval = CInt64_Sub(upperval, lowerval); - *pval = CInt64_Add(*pval, incval); - - if (IS_LINEAR_DIADIC(loop->nd18, ELESS)) - *pval = CInt64_Add(*pval, negOne); - - CError_ASSERT(2486, !CInt64_IsZero(&incval)); - - if (isUnsigned) - *pval = CInt64_DivU(*pval, incval); - else - *pval = CInt64_Div(*pval, incval); - - if (CInt64_Equal(*pval, cint64_zero)) - return 0; - - if (isUnsigned) { - CError_ASSERT(2508, !CInt64_LessEqualU(*pval, cint64_zero)); - } else { - CError_ASSERT(2517, !CInt64_LessEqual(*pval, cint64_zero)); - } - - return 1; - } - - lowerRec = IRO_InitAddrRecordPointer(lowerBound); - upperRec = IRO_InitAddrRecordPointer(upperBound); - - if (IS_LINEAR_DIADIC(lowerBound, EADD)) { - IRO_DecomposeAddressExpression(lowerBound, lowerRec); - } else if (IRO_IsIntConstant(lowerBound)) { - lowerRec->numInts++; - IRO_AddElmToList(lowerBound, &lowerRec->ints); - lowerRec->numObjRefs = 0; - lowerRec->numMisc = 0; - } else { - lowerRec->numMisc++; - IRO_AddElmToList(lowerBound, &lowerRec->misc); - lowerRec->numObjRefs = 0; - lowerRec->numInts = 0; - } - - if (IS_LINEAR_DIADIC(upperBound, EADD)) { - IRO_DecomposeAddressExpression(upperBound, upperRec); - } else if (IRO_IsIntConstant(upperBound)) { - upperRec->numInts++; - IRO_AddElmToList(upperBound, &upperRec->ints); - upperRec->numObjRefs = 0; - upperRec->numMisc = 0; - } else { - upperRec->numMisc++; - IRO_AddElmToList(upperBound, &upperRec->misc); - upperRec->numObjRefs = 0; - upperRec->numInts = 0; - } - - if (IsDifferenceOfTermsConstant(lowerRec, upperRec, isUnsigned, pval)) { - if (IS_LINEAR_DIADIC(loop->nd18, ELESSEQU)) - *pval = CInt64_Add(*pval, cint64_one); - return 1; - } - - return 0; -} - -static int IsDifferenceOfTermsConstant(IROAddrRecord *lowerRec, IROAddrRecord *upperRec, int isUnsigned, CInt64 *pval) { - UInt32 i; - CInt64 upperval; - CInt64 lowerval; - IROElmList *el; - IROLinear *nd; - - if (upperRec->numObjRefs == lowerRec->numObjRefs && upperRec->numObjRefs != 0) - return 0; - else if (upperRec->numObjRefs != lowerRec->numObjRefs) - return 0; - - if (upperRec->numMisc == lowerRec->numMisc && upperRec->numMisc != 0) { - for (i = 0; i < upperRec->numMisc; i++) { - // bug? surely this should index on i...? - if (!IRO_ExprsSame(lowerRec->misc->element, upperRec->misc->element)) - return 0; - } - } else if (upperRec->numMisc != lowerRec->numMisc) { - return 0; - } - - upperval = cint64_zero; - for (el = upperRec->ints; el; el = el->next) { - nd = el->element; - upperval = CMach_CalcIntDiadic(nd->rtype, upperval, '+', nd->u.node->data.intval); - } - - lowerval = cint64_zero; - for (el = lowerRec->ints; el; el = el->next) { - nd = el->element; - lowerval = CMach_CalcIntDiadic(nd->rtype, lowerval, '+', nd->u.node->data.intval); - } - - if (CInt64_Equal(upperval, lowerval)) - return 0; - - if (CInt64_Greater(upperval, lowerval)) { - *pval = CInt64_Sub(upperval, lowerval); - return 1; - } else { - return 0; - } -} - -void NoOpBlock(IRONode *fnode) { - IROLinear *last, *scan; - - for (scan = fnode->first, last = fnode->last; scan; scan = scan->next) { - scan->type = IROLinearNop; - if (scan == last) - break; - } -} - -void IRO_TestConstantIterationCount(IROLoop *loop, CInt64 *iterCount, SInt32 vectorStride, UInt32 *unrollFactor, SInt32 *leftOver, UInt32 *needOrigLoop, UInt32 *needUnrollBodyTest, UInt32 *resetUnrolledFinalValue) { - UInt32 isUnsigned; - CInt64 val; - CInt64 val3; - CInt64 mod; - CInt64 val2; - CInt64 loopvar3; - CInt64 loopvar1; - CInt64 loopvar2; - CInt64 strideVal; - - CError_ASSERT(2737, *unrollFactor); - - isUnsigned = IRO_IsUnsignedType( - (loop->flags & LoopFlags_1) ? loop->nd18->u.diadic.right->rtype :loop->nd18->u.diadic.left->rtype); - - CError_ASSERT(2756, vectorStride); - - strideVal = IRO_MakeLong(vectorStride); - if (isUnsigned ? CInt64_LessU(*iterCount, strideVal) : CInt64_Less(*iterCount, strideVal)) { - *needOrigLoop = 1; - *needUnrollBodyTest = 0; - *unrollFactor = 0; - *leftOver = CInt64_GetULong(iterCount); - } else { - switch (vectorStride) { - case 1: - val = *iterCount; - break; - case 2: - val = CInt64_ShrU(*iterCount, cint64_one); - break; - case 4: - val = CInt64_ShrU(*iterCount, IRO_MakeLong(2)); - break; - case 8: - val = CInt64_ShrU(*iterCount, IRO_MakeLong(3)); - break; - case 16: - val = CInt64_ShrU(*iterCount, IRO_MakeLong(4)); - break; - default: - val = CInt64_Div(*iterCount, strideVal); - } - - if (CInt64_LessU(val, IRO_MakeLong(*unrollFactor))) - *unrollFactor = CInt64_GetULong(&val); - - CInt64_SetLong(&val2, *unrollFactor); - switch (vectorStride) { - case 1: - val3 = cint64_zero; - break; - case 2: - val3 = CInt64_And(*iterCount, cint64_one); - break; - case 4: - val3 = CInt64_And(*iterCount, IRO_MakeLong(3)); - break; - case 8: - val3 = CInt64_And(*iterCount, IRO_MakeLong(7)); - break; - case 16: - val3 = CInt64_And(*iterCount, IRO_MakeLong(15)); - break; - default: - val3 = CInt64_Mod(*iterCount, strideVal); - } - - if (CInt64_LessEqualU(val, IRO_MakeLong(8))) { - *needUnrollBodyTest = vectorStride > 1; - *unrollFactor = CInt64_GetULong(&val); - *leftOver = CInt64_GetULong(&val3); - *needOrigLoop = *leftOver != 0; - *resetUnrolledFinalValue = !(*needOrigLoop && *needUnrollBodyTest); - } else { - loopvar1 = IRO_MakeLong(0x7FFFFFFF); - loopvar2 = IRO_MakeLong(0x7FFFFFFF); - do { - mod = CInt64_Mod(val, val2); - loopvar3 = CInt64_Add(CInt64_Mul(mod, strideVal), val3); - if (CInt64_Less(loopvar3, loopvar2)) { - loopvar2 = loopvar3; - loopvar1 = val2; - } - if (vectorStride > 1) - break; - val2 = CInt64_Add(val2, cint64_negone); - } while (CInt64_GreaterEqualU(CInt64_Mul(val2, val2), val)); - - *unrollFactor = CInt64_GetULong(&loopvar1); - *leftOver = CInt64_GetULong(&loopvar2); - *needOrigLoop = *leftOver != 0; - *needUnrollBodyTest = CInt64_Less(loopvar1, val) || vectorStride > 1; - *resetUnrolledFinalValue = !(*needOrigLoop && *needUnrollBodyTest); - } - } - - IRO_Dump( - "---- IterCount = %d, VectorStride = %d, UnrollFactor = %d, LeftOver = %d,\n" - "\tNeedOrigLoop = %d, NeedUnrollBodyTest = %d, ResetUnrolledFinalValue = %d\n", - CInt64_GetULong(iterCount), vectorStride, *unrollFactor, *leftOver, - *needOrigLoop, *needUnrollBodyTest, *resetUnrolledFinalValue - ); -} - -IROLinear *BuildOrigIterationCount(IROList *list, IROLoop *loop) { - IROLinear *upperBound; - IROLinear *nd29b; - IROLinear *lowerBound; - IROLinear *finalCount; - IROLinear *divisor; - Type *type; - IROLinear *nd25; - IROLinear *tmp; - Boolean isZeroBase; - Object *tempobj; - IROLinear *iterCount; - IROLinear *negone; - IROLinear *ass; - ENode *expr; - SInt32 powval; - - isZeroBase = 0; - lowerBound = loop->nd14->u.diadic.right; - if (IRO_IsIntConstant(lowerBound) && CInt64_Equal(lowerBound->u.node->data.intval, cint64_zero)) - isZeroBase = 1; - - if (!isZeroBase) - lowerBound = IRO_DuplicateExpr(lowerBound, list); - - if (loop->flags & LoopFlags_1) { - upperBound = IRO_DuplicateExpr(loop->nd18->u.diadic.right, list); - type = loop->nd18->u.diadic.right->rtype; - } else { - upperBound = IRO_DuplicateExpr(loop->nd18->u.diadic.left, list); - type = loop->nd18->u.diadic.left->rtype; - } - - CError_ASSERT(2924, loop->induction); - CError_ASSERT(2929, loop->induction->addConst); - - divisor = IRO_NewLinear(IROLinearOperand); - divisor->index = ++IRO_NumLinear; - divisor->rtype = type; - expr = IRO_NewENode(EINTCONST); - expr->rtype = type; - CInt64_SetLong(&expr->data.intval, loop->induction->addConst); - divisor->u.node = expr; - - if (isZeroBase) { - iterCount = upperBound; - } else { - iterCount = IRO_NewLinear(IROLinearOp2Arg); - iterCount->index = ++IRO_NumLinear; - iterCount->nodetype = ESUB; - iterCount->u.diadic.left = upperBound; - iterCount->u.diadic.right = lowerBound; - iterCount->rtype = type; - IRO_AddToList(iterCount, list); - } - - nd25 = IRO_DuplicateExpr(divisor, list); - - nd29b = IRO_NewLinear(IROLinearOp2Arg); - nd29b->index = ++IRO_NumLinear; - nd29b->nodetype = EADD; - nd29b->u.diadic.left = iterCount; - nd29b->u.diadic.right = nd25; - nd29b->rtype = type; - IRO_AddToList(nd29b, list); - - if (loop->nd18->type == IROLinearOp2Arg && loop->nd18->nodetype == ELESS) { - tmp = nd29b; - - negone = IRO_NewLinear(IROLinearOperand); - negone->index = ++IRO_NumLinear; - negone->rtype = type; - expr = IRO_NewENode(EINTCONST); - expr->rtype = type; - CInt64_SetLong(&expr->data.intval, -1); - negone->u.node = expr; - IRO_AddToList(negone, list); - - nd29b = IRO_NewLinear(IROLinearOp2Arg); - nd29b->index = ++IRO_NumLinear; - nd29b->nodetype = EADD; - nd29b->u.diadic.left = tmp; - nd29b->u.diadic.right = negone; - nd29b->rtype = type; - IRO_AddToList(nd29b, list); - } - - if (CInt64_Equal(divisor->u.node->data.intval, cint64_one)) { - finalCount = nd29b; - } else { - if (divisor->rtype->size <= 4 && IS_TYPE_INT(divisor->rtype) && IRO_IsPow2(divisor, &powval)) { - finalCount = IRO_NewLinear(IROLinearOp2Arg); - finalCount->index = ++IRO_NumLinear; - finalCount->nodetype = ESHL; - finalCount->u.diadic.left = nd29b; - finalCount->u.diadic.right = divisor; - CInt64_SetLong(&divisor->u.node->data.intval, powval); - finalCount->rtype = type; - IRO_AddToList(divisor, list); - IRO_AddToList(finalCount, list); - } else { - finalCount = IRO_NewLinear(IROLinearOp2Arg); - finalCount->index = ++IRO_NumLinear; - finalCount->nodetype = EDIV; - finalCount->u.diadic.left = nd29b; - finalCount->u.diadic.right = divisor; - finalCount->rtype = type; - IRO_AddToList(divisor, list); - IRO_AddToList(finalCount, list); - } - } - - tempobj = create_temp_object(type); - IRO_FindVar(tempobj, 1, 1); - - ass = IRO_NewLinear(IROLinearOp2Arg); - ass->index = ++IRO_NumLinear; - ass->nodetype = EASS; - ass->u.diadic.left = IRO_TempReference(tempobj, list); - ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind; - ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind; - ass->u.diadic.right = finalCount; - ass->u.diadic.right->flags |= IROLF_Reffed; - ass->rtype = type; - IRO_AddToList(ass, list); - - return ass->u.diadic.left; -} - -static IROLinear *BuildOrigIterationCount_DoWhile(IROList *list, IROLoop *loop) { - IROLinear *finalCount; - IROLinear *count; - IROLinear *ass; - Type *type; - Object *tempobj; - ENode *expr; - - type = loop->nd18->u.diadic.left->rtype; - - count = IRO_NewLinear(IROLinearOperand); - count->index = ++IRO_NumLinear; - expr = IRO_NewENode(EINTCONST); - expr->rtype = type; - expr->data.intval = cint64_one; - count->u.node = expr; - count->rtype = type; - IRO_AddToList(count, list); - count->flags |= IROLF_Reffed; - - finalCount = IRO_NewLinear(IROLinearOp2Arg); - finalCount->index = ++IRO_NumLinear; - finalCount->nodetype = EADD; - finalCount->rtype = type; - finalCount->u.diadic.left = IRO_DuplicateExpr(loop->nd18->u.diadic.left, list); - finalCount->u.diadic.left->flags |= IROLF_Reffed; - finalCount->u.diadic.left->flags &= ~IROLF_Assigned; - finalCount->u.diadic.left->u.monadic->flags &= ~IROLF_Assigned; - finalCount->u.diadic.right = count; - IRO_AddToList(finalCount, list); - - tempobj = create_temp_object(type); - IRO_FindVar(tempobj, 1, 1); - - ass = IRO_NewLinear(IROLinearOp2Arg); - ass->index = ++IRO_NumLinear; - ass->nodetype = EASS; - ass->u.diadic.left = IRO_TempReference(tempobj, list); - ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind; - ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind; - ass->u.diadic.right = finalCount; - ass->rtype = type; - IRO_AddToList(ass, list); - - return ass->u.diadic.left; -} - -IROLinear *BuildNewFinalvalue(IROLinear *iterCount, UInt32 unrollFactor, IROList *list, IROLoop *loop) { - IROLinear *sub; - IROLinear *addvalue; - Type *type; - IROLinear *ass; - IROLinear *dupbound; - Object *tempobj; - ENode *expr; - - type = iterCount->rtype; - - addvalue = IRO_NewLinear(IROLinearOperand); - addvalue->index = ++IRO_NumLinear; - addvalue->rtype = type; - expr = IRO_NewENode(EINTCONST); - expr->rtype = type; - CInt64_SetLong(&expr->data.intval, loop->induction->addConst * unrollFactor); - addvalue->u.node = expr; - IRO_AddToList(addvalue, list); - - if (loop->flags & LoopFlags_1) - dupbound = IRO_DuplicateExpr(loop->nd18->u.diadic.right, list); - else - dupbound = IRO_DuplicateExpr(loop->nd18->u.diadic.left, list); - - sub = IRO_NewLinear(IROLinearOp2Arg); - sub->index = ++IRO_NumLinear; - sub->nodetype = ESUB; - sub->u.diadic.left = dupbound; - sub->u.diadic.right = addvalue; - sub->rtype = type; - IRO_AddToList(sub, list); - - tempobj = create_temp_object(type); - IRO_FindVar(tempobj, 1, 1); - - ass = IRO_NewLinear(IROLinearOp2Arg); - ass->index = ++IRO_NumLinear; - ass->nodetype = EASS; - ass->u.diadic.left = IRO_TempReference(tempobj, list); - ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind; - ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind; - ass->u.diadic.right = sub; - ass->u.diadic.right->flags |= IROLF_Reffed; - ass->rtype = type; - IRO_AddToList(ass, list); - - return ass->u.diadic.left; -} - -static IROLinear *BuildPreAlignTemp(IROLoopInd *ind, UInt32 unrollFactor, IROList *list) { - Type *type; - IROLinear *indnd; - IROLinear *factornd; - IROLinear *div; - IROLinear *constnd; - IROLinear *add; - IROLinear *mul; - IROLinear *ass; - Object *tempobj; - ENode *expr; - - indnd = ind->nd; - type = indnd->rtype; - - factornd = IRO_NewLinear(IROLinearOperand); - factornd->index = ++IRO_NumLinear; - factornd->rtype = type; - expr = IRO_NewENode(EINTCONST); - expr->rtype = type; - CInt64_SetLong(&expr->data.intval, unrollFactor); - factornd->u.node = expr; - IRO_AddToList(factornd, list); - - if (indnd->type == IROLinearOp1Arg) - IRO_DuplicateExpr(indnd->u.monadic, list); - else - IRO_DuplicateExpr(indnd->u.diadic.left, list); - - list->tail->flags &= ~IROLF_Assigned; - list->tail->u.monadic->flags &= ~IROLF_Assigned; - - div = IRO_NewLinear(IROLinearOp2Arg); - div->index = ++IRO_NumLinear; - div->nodetype = EDIV; - div->u.diadic.left = list->tail; - div->u.diadic.right = factornd; - div->rtype = type; - IRO_AddToList(div, list); - div->flags |= IROLF_Reffed; - - constnd = IRO_NewLinear(IROLinearOperand); - constnd->index = ++IRO_NumLinear; - expr = IRO_NewENode(EINTCONST); - expr->rtype = type; - expr->data.intval = cint64_one; - constnd->u.node = expr; - constnd->rtype = type; - IRO_AddToList(constnd, list); - constnd->flags |= IROLF_Reffed; - - add = IRO_NewLinear(IROLinearOp2Arg); - add->index = ++IRO_NumLinear; - add->nodetype = EADD; - add->u.diadic.left = div; - add->u.diadic.right = constnd; - add->rtype = type; - IRO_AddToList(add, list); - add->flags |= IROLF_Reffed; - - IRO_DuplicateExpr(factornd, list); - - mul = IRO_NewLinear(IROLinearOp2Arg); - mul->index = ++IRO_NumLinear; - mul->nodetype = EMUL; - mul->u.diadic.left = add; - mul->u.diadic.right = list->tail; - mul->rtype = type; - IRO_AddToList(mul, list); - mul->flags |= IROLF_Reffed; - - tempobj = create_temp_object(type); - IRO_FindVar(tempobj, 1, 1); - - ass = IRO_NewLinear(IROLinearOp2Arg); - ass->index = ++IRO_NumLinear; - ass->nodetype = EASS; - ass->u.diadic.left = IRO_TempReference(tempobj, list); - ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind; - ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind; - ass->u.diadic.right = mul; - ass->u.diadic.right->flags |= IROLF_Reffed; - ass->rtype = type; - IRO_AddToList(ass, list); - - return ass->u.diadic.left; -} - -static IROLinear *BuildNewFinalvalue_DoWhile(IROLinear *iterCount, UInt32 unrollFactor, IROList *list, IROLoop *loop) { - IROLinear *addvalue; - IROLinear *add; - IROLinear *mul; - IROLinear *ass; - Type *type; - Object *tempobj; - ENode *expr; - - type = iterCount->rtype; - - addvalue = IRO_NewLinear(IROLinearOperand); - addvalue->index = ++IRO_NumLinear; - addvalue->rtype = type; - expr = IRO_NewENode(EINTCONST); - expr->rtype = type; - CInt64_SetLong(&expr->data.intval, loop->induction->addConst); - addvalue->u.node = expr; - IRO_AddToList(addvalue, list); - addvalue->flags |= IROLF_Reffed; - - mul = IRO_NewLinear(IROLinearOp2Arg); - mul->index = ++IRO_NumLinear; - mul->nodetype = EMUL; - mul->u.diadic.left = IRO_DuplicateExpr(iterCount, list); - mul->u.diadic.right = addvalue; - mul->rtype = type; - IRO_AddToList(mul, list); - mul->flags |= IROLF_Reffed; - mul->u.diadic.left->flags &= ~IROLF_Assigned; - mul->u.diadic.left->u.diadic.left->flags &= ~IROLF_Assigned; - - if (loop->induction->nd->type == IROLinearOp1Arg) - IRO_DuplicateExpr(loop->induction->nd->u.monadic, list); - else - IRO_DuplicateExpr(loop->induction->nd->u.diadic.left, list); - list->tail->flags &= ~IROLF_Assigned; - list->tail->u.diadic.left->flags &= ~IROLF_Assigned; - - add = IRO_NewLinear(IROLinearOp2Arg); - add->index = ++IRO_NumLinear; - add->nodetype = EADD; - add->u.diadic.left = mul; - add->u.diadic.right = list->tail; - add->rtype = type; - IRO_AddToList(add, list); - add->flags |= IROLF_Reffed; - - tempobj = create_temp_object(type); - IRO_FindVar(tempobj, 1, 1); - - ass = IRO_NewLinear(IROLinearOp2Arg); - ass->index = ++IRO_NumLinear; - ass->nodetype = EASS; - ass->u.diadic.left = IRO_TempReference(tempobj, list); - ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind; - ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind; - ass->u.diadic.right = add; - ass->u.diadic.right->flags |= IROLF_Reffed; - ass->rtype = type; - IRO_AddToList(ass, list); - - return ass->u.diadic.left; -} - -static IROLinear *BuildUnrolledFinalvalue_DoWhile(IROLinear *iterCount, UInt32 unrollFactor, IROList *list, IROLoop *loop) { - IROLinear *addvalue_mult; - IROLinear *addvalue; - IROLinear *mul; - IROLinear *sub; - IROLinear *add; - IROLinear *ass; - Type *type; - Object *tempobj; - ENode *expr; - - type = iterCount->rtype; - - addvalue_mult = IRO_NewLinear(IROLinearOperand); - addvalue_mult->index = ++IRO_NumLinear; - addvalue_mult->rtype = type; - expr = IRO_NewENode(EINTCONST); - expr->rtype = type; - CInt64_SetLong(&expr->data.intval, loop->induction->addConst * unrollFactor); - addvalue_mult->u.node = expr; - IRO_AddToList(addvalue_mult, list); - addvalue_mult->flags |= IROLF_Reffed; - - addvalue = IRO_NewLinear(IROLinearOperand); - addvalue->index = ++IRO_NumLinear; - addvalue->rtype = type; - expr = IRO_NewENode(EINTCONST); - expr->rtype = type; - CInt64_SetLong(&expr->data.intval, loop->induction->addConst); - addvalue->u.node = expr; - IRO_AddToList(addvalue, list); - addvalue->flags |= IROLF_Reffed; - - mul = IRO_NewLinear(IROLinearOp2Arg); - mul->index = ++IRO_NumLinear; - mul->nodetype = EMUL; - mul->u.diadic.left = IRO_DuplicateExpr(iterCount, list); - mul->u.diadic.right = addvalue; - mul->rtype = type; - IRO_AddToList(mul, list); - mul->flags |= IROLF_Reffed; - mul->u.diadic.left->flags &= ~IROLF_Assigned; - mul->u.diadic.left->u.diadic.left->flags &= ~IROLF_Assigned; - - sub = IRO_NewLinear(IROLinearOp2Arg); - sub->index = ++IRO_NumLinear; - sub->nodetype = ESUB; - sub->u.diadic.left = mul; - sub->u.diadic.right = addvalue_mult; - sub->rtype = type; - IRO_AddToList(sub, list); - sub->flags |= IROLF_Reffed; - - if (loop->induction->nd->type == IROLinearOp1Arg) - IRO_DuplicateExpr(loop->induction->nd->u.monadic, list); - else - IRO_DuplicateExpr(loop->induction->nd->u.diadic.left, list); - list->tail->flags &= ~IROLF_Assigned; - list->tail->u.diadic.left->flags &= ~IROLF_Assigned; - - add = IRO_NewLinear(IROLinearOp2Arg); - add->index = ++IRO_NumLinear; - add->nodetype = EADD; - add->u.diadic.left = sub; - add->u.diadic.right = list->tail; - add->rtype = type; - IRO_AddToList(add, list); - add->flags |= IROLF_Reffed; - - tempobj = create_temp_object(type); - IRO_FindVar(tempobj, 1, 1); - - ass = IRO_NewLinear(IROLinearOp2Arg); - ass->index = ++IRO_NumLinear; - ass->nodetype = EASS; - ass->u.diadic.left = IRO_TempReference(tempobj, list); - ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind; - ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind; - ass->u.diadic.right = add; - ass->u.diadic.right->flags |= IROLF_Reffed; - ass->rtype = type; - IRO_AddToList(ass, list); - - return ass->u.diadic.left; -} - -void BuildUnrolledBodyEntryTest(IROList *list, IROLinear *iterCount, UInt32 unrollFactor, CLabel *label) { - Type *type; - IROLinear *ifnot; - IROLinear *comp; - IROLinear *var; - IROLinear *value; - ENode *expr; - - type = iterCount->rtype; - - value = IRO_NewLinear(IROLinearOperand); - value->index = ++IRO_NumLinear; - value->rtype = type; - expr = IRO_NewENode(EINTCONST); - expr->rtype = type; - CInt64_SetLong(&expr->data.intval, unrollFactor); - value->u.node = expr; - IRO_AddToList(value, list); - - var = IRO_DuplicateExpr(iterCount, list); - - comp = IRO_NewLinear(IROLinearOp2Arg); - comp->index = ++IRO_NumLinear; - comp->nodetype = EGREATER; - comp->u.diadic.left = var; - comp->u.diadic.right = value; - comp->u.diadic.right->flags |= IROLF_Reffed; - comp->rtype = type; - IRO_AddToList(comp, list); - - ifnot = IRO_NewLinear(IROLinearOp1Arg); - ifnot->index = ++IRO_NumLinear; - ifnot->type = IROLinearIfNot; - ifnot->u.label.x4 = comp; - ifnot->u.label.x4->flags |= IROLF_Reffed; - ifnot->rtype = type; - ifnot->u.label.label = label; - IRO_AddToList(ifnot, list); -} - -void ChangeInductionReference(IROLinear *first, IROLinear *last, CInt64 val, IROLoop *loop) { - IROLinear *nd; - IROLinear *value; - IROLinear *add; - UInt32 isUnsigned; - IROLinear *father; - Boolean flag; - IROLinear *father2; - IROLinear *father3; - Type *tmp; - UInt32 flag2; - Object *varobj; - IROLinear *next; - ENode *expr; - Type *type; - - CInt64 val2; - CInt64 val1; - IROList list; - - type = loop->induction->nd->rtype; - isUnsigned = IRO_IsUnsignedType(type); - - for (nd = first; nd; nd = next) { - next = nd->next; - - varobj = IRO_IsVariable(nd); - if (varobj && loop->induction->var->object == varobj) { - value = IRO_NewLinear(IROLinearOperand); - value->index = ++IRO_NumLinear; - value->rtype = type; - expr = IRO_NewENode(EINTCONST); - expr->rtype = type; - expr->data.intval = val; - value->u.node = expr; - - add = IRO_NewLinear(IROLinearOp2Arg); - add->index = ++IRO_NumLinear; - add->nodetype = EADD; - add->rtype = type; - - father = IRO_LocateFather(nd); - flag = 1; - if (father && IS_LINEAR_MONADIC(father, ETYPCON)) { - tmp = father->rtype; - father = IRO_LocateFather(father); - if (tmp->type != nd->rtype->type || tmp->size < nd->rtype->size) - flag = 0; - } - - flag2 = 0; - if ( - flag && - father && - IS_LINEAR_DIADIC_2(father, ESHL, EMUL) && - IRO_IsIntConstant(father->u.diadic.right) && - (father2 = IRO_LocateFather(father)) && - IS_LINEAR_DIADIC(father2, EADD) && - father2->u.diadic.right == father && - (father3 = IRO_LocateFather(father2)) - ) - { - IRO_InitList(&list); - val2 = father->u.diadic.right->u.node->data.intval; - if (father->nodetype == ESHL) - val2 = CInt64_Shl(cint64_one, val2); - - val1 = value->u.node->data.intval; - if (isUnsigned) - val1 = CInt64_MulU(val2, val1); - else - val1 = CInt64_Mul(val2, val1); - value->u.node->data.intval = val1; - - IRO_AddToList(value, &list); - IRO_AddToList(add, &list); - add->u.diadic.right = value; - IRO_Paste(list.head, list.tail, father3); - IRO_LocateFather_Cut_And_Paste_Without_Nopping(father2, add); - add->u.diadic.left = father2; - add->rtype = father2->rtype; - flag2 = 1; - } - - if (!flag2) { - add->u.diadic.right = value; - add->u.diadic.right->flags |= IROLF_Reffed; - value->next = add; - - add->u.diadic.left = nd; - IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, add); - add->flags |= IROLF_Reffed; - - nd->next = value; - add->next = next; - } - } - - if (nd == last) - break; - } -} - -IROLinear *UpdateInductionIncrement(IROLoop *loop, SInt32 value, IROLinear *before) { - IROLinear *ind_nd; - IROLinear *addvalue; - IROLinear *ass; - Type *type; - ENode *expr; - IROList list; - - IRO_InitList(&list); - ind_nd = loop->induction->nd; - type = ind_nd->rtype; - - addvalue = IRO_NewLinear(IROLinearOperand); - addvalue->index = ++IRO_NumLinear; - addvalue->rtype = type; - expr = IRO_NewENode(EINTCONST); - expr->rtype = type; - CInt64_SetLong(&expr->data.intval, value * loop->induction->addConst); - addvalue->u.node = expr; - IRO_AddToList(addvalue, &list); - - if (IS_LINEAR_MONADIC_2(ind_nd, EPREINC, EPOSTINC)) { - ind_nd = IRO_DuplicateExpr(ind_nd->u.monadic, &list); - - ass = IRO_NewLinear(IROLinearOp2Arg); - ass->index = ++IRO_NumLinear; - ass->nodetype = EADDASS; - ass->u.diadic.left = ind_nd; - ass->u.diadic.right = addvalue; - ass->rtype = type; - IRO_AddToList(ass, &list); - } else if (IS_LINEAR_MONADIC_2(ind_nd, EPREDEC, EPOSTDEC)) { - ind_nd = IRO_DuplicateExpr(ind_nd->u.monadic, &list); - - ass = IRO_NewLinear(IROLinearOp2Arg); - ass->index = ++IRO_NumLinear; - ass->nodetype = ESUBASS; - ass->u.diadic.left = ind_nd; - ass->u.diadic.right = addvalue; - ass->rtype = type; - IRO_AddToList(ass, &list); - } else if (IS_LINEAR_DIADIC(ind_nd, EADDASS)) { - ind_nd = IRO_DuplicateExpr(ind_nd->u.monadic, &list); - - ass = IRO_NewLinear(IROLinearOp2Arg); - ass->index = ++IRO_NumLinear; - ass->nodetype = EADDASS; - ass->u.diadic.left = ind_nd; - ass->u.diadic.right = addvalue; - ass->rtype = type; - IRO_AddToList(ass, &list); - } - - IRO_Paste(list.head, list.tail, before); - return list.tail; -} - -void GenInitialAssignment(IROLoop *loop, Object *var, IROList *list) { - Type *type; - IROLinear *nd; - - CError_ASSERT(3924, loop->nd14 && loop->nd14->type == IROLinearOp2Arg); - - type = loop->induction->nd->rtype; - - nd = IRO_NewLinear(IROLinearOp2Arg); - nd->index = ++IRO_NumLinear; - nd->nodetype = EASS; - nd->u.diadic.left = IRO_TempReference(var, list); - nd->u.diadic.right = IRO_DuplicateExpr(loop->nd14->u.diadic.right, list); - nd->rtype = type; - IRO_AddToList(nd, list); -} - -void GenNewInduction(void) { - CError_FATAL(3941); -} |