diff options
Diffstat (limited to 'compiler_and_linker/unsorted/LoopDetection.c')
-rw-r--r-- | compiler_and_linker/unsorted/LoopDetection.c | 885 |
1 files changed, 0 insertions, 885 deletions
diff --git a/compiler_and_linker/unsorted/LoopDetection.c b/compiler_and_linker/unsorted/LoopDetection.c deleted file mode 100644 index 6bb2d51..0000000 --- a/compiler_and_linker/unsorted/LoopDetection.c +++ /dev/null @@ -1,885 +0,0 @@ -#include "compiler/LoopDetection.h" -#include "compiler/CFunc.h" -#include "compiler/PCode.h" -#include "compiler/TOC.h" -#include "compiler/UseDefChains.h" -#include "compiler/CompilerTools.h" -#include "compiler/BitVectors.h" -#include "compiler/enode.h" -#include "compiler/objects.h" - -Loop *loopsinflowgraph; -int loopdetection_nblocks; -static UInt32 **dominators; -static BlockList *loopheaders; -static int nloopheaders; -static PCodeBlock **loopstack; -BitVector *LoopTemp; -struct LoopList *LoopList_First; - -static void computedominators(void) { - int i; - PCodeBlock *block; - int blockCount; - int flag; - UInt32 *myvec; - PCLink *link; - - blockCount = pcblockcount; - flag = 1; - - dominators = oalloc(sizeof(UInt32 *) * pcblockcount); - for (i = 0; i < pcblockcount; i++) - dominators[i] = oalloc(4 * ((blockCount + 31) >> 5)); - - myvec = oalloc(4 * ((blockCount + 31) >> 5)); - - bitvectorinitialize(dominators[pcbasicblocks->blockIndex], blockCount, 0); - //dominators[pcbasicblocks->blockIndex][0] |= 1; - bitvectorsetbit(0, dominators[pcbasicblocks->blockIndex]); - - for (block = pcbasicblocks->nextBlock; block; block = block->nextBlock) - bitvectorinitialize(dominators[block->blockIndex], blockCount, 0xFFFFFFFF); - - computedepthfirstordering(); - - while (flag) { - flag = 0; - for (i = 0; i < pcblockcount; i++) { - block = depthfirstordering[i]; - if (block && block->blockIndex != pcbasicblocks->blockIndex) { - bitvectorcopy(myvec, dominators[block->predecessors->block->blockIndex], blockCount); - for (link = block->predecessors->nextLink; link; link = link->nextLink) - bitvectorintersect(myvec, dominators[link->block->blockIndex], blockCount); - //myvec[block->blockIndex >> 5] |= 1 << (block->blockIndex & 31); - bitvectorsetbit(block->blockIndex, myvec); - - if (bitvectorchanged(dominators[block->blockIndex], myvec, blockCount)) - flag = 1; - } - } - } -} - -static BlockList *findloopheaders(void) { - PCodeBlock *block; - PCLink *link; - BlockList *list; - - loopheaders = NULL; - nloopheaders = 0; - - for (block = pcbasicblocks->nextBlock; block; block = block->nextBlock) { - for (link = block->predecessors; link; link = link->nextLink) { - //if ((1 << (block->blockIndex & 31)) & dominators[link->block->blockIndex][block->blockIndex >> 5]) - if (bitvectorgetbit(block->blockIndex, dominators[link->block->blockIndex])) - break; - } - - if (link) { - list = oalloc(sizeof(BlockList)); - list->block = block; - list->next = loopheaders; - loopheaders = list; - nloopheaders++; - } - } - - return loopheaders; -} - -void addblocktoloop(Loop *loop, PCodeBlock *block) { - BlockList *list = lalloc(sizeof(BlockList)); - - //loop->memberblocks[block->blockIndex >> 5] |= 1 << (block->blockIndex & 31); - bitvectorsetbit(block->blockIndex, loop->memberblocks); - - list->block = block; - list->next = loop->blocks; - loop->blocks = list; -} - -static void findnaturalloop(Loop *loop) { - BlockList *list; - BlockList *list2; - PCLink *link; - PCodeBlock *block; - int i; - - i = 0; - addblocktoloop(loop, loop->body); - for (link = loop->body->predecessors; link; link = link->nextLink) { - if (bitvectorgetbit(loop->body->blockIndex, dominators[link->block->blockIndex]) && link->block != loop->body) { - addblocktoloop(loop, link->block); - loopstack[i++] = link->block; - } - } - - while (i) { - link = loopstack[--i]->predecessors; - while (link) { - if (!bitvectorgetbit(link->block->blockIndex, loop->memberblocks)) { - addblocktoloop(loop, link->block); - loopstack[i++] = link->block; - } - link = link->nextLink; - } - } - - for (list = loop->blocks; list; list = list->next) { - block = list->block; - for (link = block->successors; link; link = link->nextLink) { - if (!bitvectorgetbit(link->block->blockIndex, loop->memberblocks)) { - bitvectorsetbit(block->blockIndex, loop->vec24); - break; - } - } - } - - for (list = loop->blocks; list; list = list->next) { - for (list2 = loop->blocks; list2; list2 = list2->next) { - if (bitvectorgetbit(list2->block->blockIndex, loop->vec24) && - !bitvectorgetbit(list->block->blockIndex, dominators[list2->block->blockIndex])) - break; - } - - if (!list2) - bitvectorsetbit(list->block->blockIndex, loop->vec28); - } - - for (list = loop->blocks; list; list = list->next) { - for (link = loop->body->predecessors; link; link = link->nextLink) { - if (bitvectorgetbit(link->block->blockIndex, loop->memberblocks) && - !bitvectorgetbit(list->block->blockIndex, dominators[link->block->blockIndex])) - break; - } - - if (!link) - bitvectorsetbit(list->block->blockIndex, loop->vec2C); - } -} - -static void addlooptolist(Loop *loop, Loop **list) { - Loop **scan; - Loop *scanloop; - - scan = list; - while ((scanloop = *scan)) { - if (bitvectorgetbit(loop->body->blockIndex, scanloop->memberblocks)) { - loop->parent = scanloop; - addlooptolist(loop, &scanloop->children); - return; - } - - if (bitvectorgetbit(scanloop->body->blockIndex, loop->memberblocks)) { - *scan = scanloop->nextSibling; - scanloop->parent = loop; - scanloop->nextSibling = loop->children; - loop->children = scanloop; - } else { - scan = &scanloop->nextSibling; - } - } - - loop->nextSibling = *list; - *list = loop; -} - -static void findnaturalloops(void) { - Loop *loop; - int size; - - loopdetection_nblocks = pcblockcount + 5 * nloopheaders; - loopstack = oalloc(sizeof(PCodeBlock *) * pcblockcount); - while (loopheaders) { - loop = lalloc(sizeof(Loop)); - loop->parent = loop->nextSibling = loop->children = NULL; - loop->body = loopheaders->block; - loop->preheader = NULL; - loop->blocks = NULL; - loop->basicInductionVars = NULL; - loop->footer = NULL; - loop->pc18 = NULL; - loop->loopWeight = loop->body->loopWeight; - - bitvectorinitialize(loop->memberblocks = lalloc(4 * ((loopdetection_nblocks + 31) >> 5)), loopdetection_nblocks, 0); - bitvectorinitialize(loop->vec24 = lalloc(4 * ((loopdetection_nblocks + 31) >> 5)), loopdetection_nblocks, 0); - bitvectorinitialize(loop->vec28 = lalloc(4 * ((loopdetection_nblocks + 31) >> 5)), loopdetection_nblocks, 0); - bitvectorinitialize(loop->vec2C = lalloc(4 * ((loopdetection_nblocks + 31) >> 5)), loopdetection_nblocks, 0); - - findnaturalloop(loop); - addlooptolist(loop, &loopsinflowgraph); - - loopheaders = loopheaders->next; - } -} - -static PCodeBlock *makepreheaderblock(void) { - PCodeLabel *label; - PCodeBlock *block; - - label = makepclabel(); - block = lalloc(sizeof(PCodeBlock)); - block->nextBlock = NULL; - block->prevBlock = NULL; - block->labels = NULL; - block->successors = NULL; - block->predecessors = NULL; - block->firstPCode = block->lastPCode = NULL; - block->pcodeCount = 0; - block->flags = 0; - block->blockIndex = pcblockcount++; - pclabel(block, label); - return block; -} - -static void insertpreheaderbefore(PCodeBlock *a, PCodeBlock *b) { - a->nextBlock = b; - a->prevBlock = b->prevBlock; - b->prevBlock->nextBlock = a; - b->prevBlock = a; -} - -void insertpreheaderblock(Loop *loop) { - PCodeBlock *preheader; - PCodeBlock *block29; - PCodeBlock *block28; - PCode *pcode27; - PCLink *link; // r26 - PCLink **linkptr; // r25 - PCodeLabel *newlabel; // r23 - PCLink *innerlink; - PCodeBlock *block; - PCodeArg *arg; - int i; - - preheader = loop->preheader = makepreheaderblock(); - block29 = NULL; - block28 = loop->body; - - if (!block28->labels) - pclabel(block28, makepclabel()); - - appendpcode(preheader, makepcode(PC_B, block28->labels)); - preheader->loopWeight = loop->parent ? loop->parent->loopWeight : 1; - - linkptr = &block28->predecessors; - while ((link = *linkptr)) { - if (bitvectorgetbit(link->block->blockIndex, loop->memberblocks)) { - linkptr = &link->nextLink; - } else { - if (link->block->pcodeCount) { - pcode27 = link->block->lastPCode; - if (pcode27->op == PC_B) { - CError_ASSERT(462, pcode27->args[0].kind == PCOp_LABEL); - if (pcode27->args[0].data.label.label->block == block28) - pcode27->args[0].data.label.label = preheader->labels; - } else if (pcode27->op == PC_BT || pcode27->op == PC_BF) { - CError_ASSERT(474, pcode27->args[2].kind == PCOp_LABEL); - if (pcode27->args[2].data.label.label->block == block28) - pcode27->args[2].data.label.label = preheader->labels; - } else if (pcode27->op == PC_BCTR) { - if (pcode27->argCount > 1 && pcode27->args[1].kind == PCOp_MEMORY) { - Object *obj = pcode27->args[1].data.mem.obj; - UInt32 *array = (UInt32 *) obj->u.data.u.switchtable.data; - int i; - for (i = 0; i < obj->u.data.u.switchtable.size; i++) { - if (((PCodeLabel *) CTool_ResolveIndexToPointer(array[i]))->block == block28) - array[i] = CTool_CreateIndexFromPointer(preheader->labels); - } - } else { - CodeLabelList *cll; - for (cll = codelabellist; cll; cll = cll->next) { - if (cll->label->pclabel->block == block28) - cll->label->pclabel = preheader->labels; - } - } - } else { - CError_ASSERT(505, link->block->nextBlock == block28); - } - } - - for (innerlink = link->block->successors; innerlink; innerlink = innerlink->nextLink) { - if (innerlink->block == block28) - innerlink->block = preheader; - } - - *linkptr = link->nextLink;; - link->nextLink = preheader->predecessors; - preheader->predecessors = link; - } - } - - if (!bitvectorgetbit(block28->prevBlock->blockIndex, loop->memberblocks)) { - insertpreheaderbefore(preheader, block28); - - if ( - (!block28->nextBlock || !bitvectorgetbit(block28->nextBlock->blockIndex, loop->memberblocks)) && - block28->lastPCode && - (block28->lastPCode->flags & fIsBranch) && - block28->lastPCode->op != PC_BDNZ - ) { - i = block28->lastPCode->argCount; - arg = block28->lastPCode->args; - while (i && arg->kind != PCOp_LABEL) { - arg++; - i--; - } - - if (i && arg->kind == PCOp_LABEL && arg->data.label.label->block == block28) { - block29 = makepreheaderblock(); - insertpreheaderbefore(block29, block28); - newlabel = makepclabel(); - pclabel(block29, newlabel); - arg->data.label.label = newlabel; - - link = lalloc(sizeof(PCLink)); - link->block = block28; - link->nextLink = block29->predecessors; - block29->predecessors = link; - - link = lalloc(sizeof(PCLink)); - link->block = block28; - link->nextLink = block29->successors; - block29->successors = link; - - for (link = block28->successors; link; link = link->nextLink) { - if (link->block == block28) - link->block = block29; - } - for (link = block28->predecessors; link; link = link->nextLink) { - if (link->block == block28) - link->block = block29; - } - - bitvectorsetbit(block29->blockIndex, loop->vec2C); - addblocktoloop(loop, block29); - } - } - } else { - for (block = pcbasicblocks; block; block = block->nextBlock) { - if (bitvectorgetbit(block->blockIndex, loop->memberblocks)) - break; - } - insertpreheaderbefore(preheader, block); - } - - link = lalloc(sizeof(PCLink)); - link->block = preheader; - link->nextLink = block28->predecessors; - block28->predecessors = link; - - link = lalloc(sizeof(PCLink)); - link->block = block28; - link->nextLink = preheader->successors; - preheader->successors = link; - - for (loop = loop->parent; loop; loop = loop->parent) { - addblocktoloop(loop, preheader); - if (bitvectorgetbit(block28->blockIndex, loop->vec28)) { - bitvectorsetbit(preheader->blockIndex, loop->vec28); - if (block29) - bitvectorsetbit(block29->blockIndex, loop->vec28); - } - if (bitvectorgetbit(block28->blockIndex, loop->vec2C)) { - bitvectorsetbit(preheader->blockIndex, loop->vec2C); - if (block29) - bitvectorsetbit(block29->blockIndex, loop->vec2C); - } - } -} - -static void insertpreheaderblocks(Loop *loop) { - while (loop) { - if (loop->children) - insertpreheaderblocks(loop->children); - insertpreheaderblock(loop); - loop = loop->nextSibling; - } -} - -void findloopsinflowgraph(void) { - loopsinflowgraph = NULL; - computedominators(); - if (findloopheaders()) { - findnaturalloops(); - insertpreheaderblocks(loopsinflowgraph); - } - freeoheap(); -} - -static int checklooplimits(SInt32 opcode, SInt32 condition, SInt32 c, SInt32 d, SInt32 addend, SInt32 *result) { - if (opcode == PC_BT) { - if (condition == 0) { - if (addend <= 0) - return 0; - if (c < d) - *result = (d - c + addend - 1) / addend; - else - *result = 0; - } else if (condition == 1) { - if (addend >= 0) - return 0; - if (c > d) - *result = (c - d - addend - 1) / -addend; - else - *result = 0; - } else { - return 0; - } - } else { - if (condition == 0) { - if (addend >= 0) - return 0; - if (c >= d) - *result = (c - d - addend) / -addend; - else - *result = 0; - } else if (condition == 1) { - if (addend <= 0) - return 0; - if (c <= d) - *result = (d - c + addend) / addend; - else - *result = 0; - } else if (c < d) { - if (addend <= 0) - return 0; - if ((d - c) % addend) - return 0; - *result = (d - c) / addend; - } else if (c > d) { - if (addend >= 0) - return 0; - if ((c - d) % -addend) - return 0; - *result = (c - d) / -addend; - } else { - *result = 0; - } - } - - return 1; -} - -static int checkunsignedlooplimits(SInt32 opcode, SInt32 condition, UInt32 c, UInt32 d, SInt32 addend, UInt32 *result) { - if (opcode == PC_BT) { - if (condition == 0) { - if (addend <= 0) - return 0; - if (c < d) - *result = (d - c + addend - 1) / addend; - else - *result = 0; - } else if (condition == 1) { - if (addend >= 0) - return 0; - if (c > d) - *result = (c - d - addend - 1) / -addend; - else - *result = 0; - } else { - return 0; - } - } else { - if (condition == 0) { - if (addend >= 0) - return 0; - if (c >= d) - *result = (c - d - addend) / -addend; - else - *result = 0; - } else if (condition == 1) { - if (addend <= 0) - return 0; - if (c <= d) - *result = (d - c + addend) / addend; - else - *result = 0; - } else if (c < d) { - if (addend <= 0) - return 0; - if ((d - c) % addend) - return 0; - *result = (d - c) / addend; - } else if (c > d) { - if (addend >= 0) - return 0; - if ((c - d) % -addend) - return 0; - *result = (c - d) / -addend; - } else { - *result = 0; - } - } - - return (*result & 0x80000000) == 0; -} - -static int checkunknownloop(int a, int b, int c, unsigned char *op) { - if (a == PC_BT) { - if (b == 0) { - if (c <= 0) - return 0; - *op = ELESS; - } else if (b == 1) { - if (c >= 0) - return 0; - *op = EGREATER; - } else { - return 0; - } - } else { - if (b == 0) { - if (c >= 0) - return 0; - *op = EGREATEREQU; - } else if (b == 1) { - if (c <= 0) - return 0; - *op = ELESSEQU; - } else if (c == 1) { - *op = ENOTEQU; - } else if (c == -1) { - *op = ENOTEQU; - } else { - return 0; - } - } - - return 1; -} - -static void checkcountingloop(Loop *loop) { - RegUseOrDef *list; - PCode *lastpcode; - PCode *prevpcode; - PCode *pc8; - PCode *check; - short op12; - short reg11; - SInt16 reg4; - short reg11b; - Loop *child; - - if (!(lastpcode = loop->body->lastPCode)) - return; - if (lastpcode->op != PC_BT && lastpcode->op != PC_BF) - return; - if (lastpcode->args[2].kind != PCOp_LABEL) - return; - - if (!bitvectorgetbit(lastpcode->args[2].data.label.label->block->blockIndex, loop->memberblocks)) - return; - if (bitvectorgetbit(loop->body->nextBlock->blockIndex, loop->memberblocks)) - return; - - reg11 = lastpcode->args[0].data.reg.reg; - reg4 = lastpcode->args[1].data.imm.value; - prevpcode = lastpcode->prevPCode; - if (!prevpcode) - return; - - op12 = prevpcode->op; - if (op12 == PC_ADDI && prevpcode->args[2].kind == PCOp_IMMEDIATE) { - pc8 = prevpcode; - prevpcode = prevpcode->prevPCode; - if (!prevpcode) - return; - - op12 = prevpcode->op; - if (pc8->args[0].data.reg.reg != pc8->args[1].data.reg.reg) - return; - if (op12 != PC_CMP && op12 != PC_CMPL && op12 != PC_CMPI && op12 != PC_CMPLI) - return; - if (prevpcode->args[1].data.reg.reg != pc8->args[0].data.reg.reg) - return; - if ((loop->step = pc8->args[2].data.imm.value) == 0) - return; - } - - if (op12 != PC_CMP && op12 != PC_CMPL && op12 != PC_CMPI && op12 != PC_CMPLI) - return; - - if (prevpcode->args[0].data.reg.reg != reg11) - return; - - reg11b = prevpcode->args[1].data.reg.reg; - if (reg11b < 32) - return; - - if (loop->preheader->nextBlock != lastpcode->args[2].data.label.label->block) - return; - - if (op12 == PC_CMPI) { - if (prevpcode->prevPCode) - return; - loop->upper = prevpcode->args[2].data.imm.value; - loop->upperType = LOOP_BOUND_CONSTANT; - } else if (op12 == PC_CMPLI) { - if (prevpcode->prevPCode) - return; - loop->upper = prevpcode->args[2].data.imm.value & 0xFFFF; - loop->upperType = LOOP_BOUND_CONSTANT; - } else if (op12 == PC_CMP || op12 == PC_CMPL) { - if (prevpcode->prevPCode) { - if ( - prevpcode->prevPCode->op == PC_LI && - prevpcode->prevPCode->args[1].kind == PCOp_IMMEDIATE && - prevpcode->prevPCode->args[0].data.reg.reg == prevpcode->args[2].data.reg.reg && - !prevpcode->prevPCode->prevPCode - ) { - loop->upper = prevpcode->prevPCode->args[1].data.imm.value; - loop->upperType = LOOP_BOUND_CONSTANT; - } else if ( - prevpcode->prevPCode->op == PC_LIS && - prevpcode->prevPCode->args[1].kind == PCOp_IMMEDIATE && - prevpcode->prevPCode->args[0].data.reg.reg == prevpcode->args[2].data.reg.reg && - !prevpcode->prevPCode->prevPCode - ) { - loop->upper = prevpcode->prevPCode->args[1].data.imm.value << 16; - loop->upperType = LOOP_BOUND_CONSTANT; - } else if ( - prevpcode->prevPCode->op == PC_ADDI && - prevpcode->prevPCode->args[2].kind == PCOp_IMMEDIATE && - prevpcode->prevPCode->args[0].data.reg.reg == prevpcode->args[2].data.reg.reg && - prevpcode->prevPCode->args[1].data.reg.reg == prevpcode->args[2].data.reg.reg && - prevpcode->prevPCode->prevPCode && - prevpcode->prevPCode->prevPCode->op == PC_LIS && - prevpcode->prevPCode->prevPCode->args[1].kind == PCOp_IMMEDIATE && - prevpcode->prevPCode->prevPCode->args[0].data.reg.reg == prevpcode->args[2].data.reg.reg && - !prevpcode->prevPCode->prevPCode->prevPCode - ) { - loop->upper = prevpcode->prevPCode->args[2].data.imm.value + - (prevpcode->prevPCode->prevPCode->args[1].data.imm.value << 16); - loop->upperType = LOOP_BOUND_CONSTANT; - } else { - return; - } - } else { - pc8 = NULL; - for (list = reg_Defs[RegClass_GPR][prevpcode->args[2].data.reg.reg]; list; list = list->next) { - if (bitvectorgetbit(Defs[list->id].pcode->block->blockIndex, loop->memberblocks)) - return; - } - for (list = reg_Defs[RegClass_GPR][prevpcode->args[2].data.reg.reg]; list; list = list->next) { - if (bitvectorgetbit(list->id, usedefinfo[loop->preheader->blockIndex].defvec8)) { - if (!pc8) { - pc8 = Defs[list->id].pcode; - if ( - pc8->op == PC_LI && - pc8->args[1].kind == PCOp_IMMEDIATE - ) { - loop->upper = pc8->args[1].data.imm.value; - loop->upperType = LOOP_BOUND_CONSTANT; - } else if ( - pc8->op == PC_LIS && - pc8->args[1].kind == PCOp_IMMEDIATE - ) { - loop->upper = pc8->args[1].data.imm.value << 16; - loop->upperType = LOOP_BOUND_CONSTANT; - } else if ( - pc8->op == PC_ADDI && - pc8->args[2].kind == PCOp_IMMEDIATE && - pc8->args[1].data.reg.reg == prevpcode->args[2].data.reg.reg && - pc8->prevPCode && - pc8->prevPCode->op == PC_LIS && - pc8->prevPCode->args[1].kind == PCOp_IMMEDIATE && - pc8->prevPCode->args[0].data.reg.reg == prevpcode->args[2].data.reg.reg - ) { - loop->upper = pc8->args[2].data.imm.value + - (pc8->prevPCode->args[1].data.imm.value << 16); - loop->upperType = LOOP_BOUND_CONSTANT; - } else { - loop->upperType = LOOP_BOUND_VARIABLE; - break; - } - } else { - loop->upperType = LOOP_BOUND_VARIABLE; - break; - } - } - } - - if (loop->upperType == LOOP_BOUND_INDETERMINATE) - loop->upperType = LOOP_BOUND_VARIABLE; - } - } - - pc8 = NULL; - - for (list = reg_Defs[RegClass_GPR][reg11b]; list; list = list->next) { - check = Defs[list->id].pcode; - if (bitvectorgetbit(check->block->blockIndex, loop->memberblocks)) { - if (!pc8) { - pc8 = check; - if (check->op != PC_ADDI) - return; - if (check->args[1].data.reg.reg != reg11b) - return; - if (check->args[2].kind != PCOp_IMMEDIATE) - return; - if ((loop->step = check->args[2].data.imm.value) == 0) - return; - } else { - return; - } - } - } - - if (!pc8) - return; - - if (pc8->block != prevpcode->block && !bitvectorgetbit(prevpcode->block->blockIndex, loop->vec2C)) - return; - - if (loop->children) { - for (child = loop->children; child; child = child->nextSibling) { - if (bitvectorgetbit(pc8->block->blockIndex, child->memberblocks)) - return; - } - } - - loop->pc18 = pc8; - - pc8 = NULL; - - for (list = reg_Defs[RegClass_GPR][reg11b]; list; list = list->next) { - if (bitvectorgetbit(list->id, usedefinfo[loop->preheader->blockIndex].defvec8)) { - if (!pc8) { - pc8 = Defs[list->id].pcode; - if ( - pc8->op == PC_LI && - pc8->args[1].kind == PCOp_IMMEDIATE - ) { - loop->lower = pc8->args[1].data.imm.value; - loop->lowerType = LOOP_BOUND_CONSTANT; - } else if ( - pc8->op == PC_LIS && - pc8->args[1].kind == PCOp_IMMEDIATE - ) { - loop->lower = pc8->args[1].data.imm.value << 16; - loop->lowerType = LOOP_BOUND_CONSTANT; - } else if ( - pc8->op == PC_ADDI && - pc8->args[2].kind == PCOp_IMMEDIATE && - pc8->args[1].data.reg.reg == reg11b && - pc8->prevPCode && - pc8->prevPCode->op == PC_LIS && - pc8->prevPCode->args[1].kind == PCOp_IMMEDIATE && - pc8->prevPCode->args[0].data.reg.reg == reg11b - ) { - loop->lower = pc8->args[2].data.imm.value + - (pc8->prevPCode->args[1].data.imm.value << 16); - loop->lowerType = LOOP_BOUND_CONSTANT; - } else { - loop->lowerType = LOOP_BOUND_VARIABLE; - break; - } - } else { - loop->lowerType = LOOP_BOUND_INDETERMINATE; - break; - } - } - } - - if (loop->lowerType == LOOP_BOUND_INDETERMINATE) - loop->lowerType = LOOP_BOUND_VARIABLE; - - if (loop->lowerType == LOOP_BOUND_CONSTANT && loop->upperType == LOOP_BOUND_CONSTANT) { - if (op12 == PC_CMP || op12 == PC_CMPI) { - if (!checklooplimits(lastpcode->op, reg4, loop->lower, loop->upper, loop->step, &loop->iterationCount)) - return; - } else { - if (!checkunsignedlooplimits(lastpcode->op, reg4, loop->lower, loop->upper, loop->step, (UInt32 *) &loop->iterationCount)) - return; - } - loop->isKnownCountingLoop = 1; - } else if (loop->lowerType != LOOP_BOUND_INDETERMINATE || loop->upperType != LOOP_BOUND_INDETERMINATE) { - if (!checkunknownloop(lastpcode->op, reg4, loop->step, &loop->unknownCondition)) - return; - loop->isUnknownCountingLoop = 1; - } -} - -void analyzeForCountableLoops(Loop *loop) { - if (!loop) - return; - - while (loop) { - if (loop->children) - analyzeForCountableLoops(loop->children); - checkcountingloop(loop); - loop = loop->nextSibling; - } -} - -void analyzeloop(Loop *loop) { - BlockList *list; - PCodeBlock *block; - PCode *pcode; - - loop->bodySize = 0; - loop->x4D = 0; - loop->x4E = 0; - loop->x4F = 1; - loop->isKnownCountingLoop = 0; - loop->isUnknownCountingLoop = 0; - loop->lowerType = LOOP_BOUND_INDETERMINATE; - loop->upperType = LOOP_BOUND_INDETERMINATE; - loop->iterationCount = -1; - loop->x57 = 0; - loop->x52 = 0; - - for (list = loop->blocks; list; list = list->next) { - block = list->block; - if (!loop->children) - block->flags |= fPCBlockFlag2000; - loop->bodySize += block->pcodeCount; - - if (block != loop->body) { - if (!block->successors || !block->predecessors || block->successors->nextLink || block->predecessors->nextLink) - loop->x4F = 0; - } - - if ((block->flags & fPCBlockFlag4000) == fPCBlockFlag4000) - loop->x52 = 1; - - for (pcode = block->firstPCode; pcode; pcode = pcode->nextPCode) { - if (PCODE_FLAG_SET_T(pcode) & fLink) - loop->x4D = 1; - - if (pcode->op == PC_BCTRL || pcode->op == PC_BCTR || pcode->op == PC_BCCTR || pcode->op == PC_MTCTR || pcode->op == PC_MFCTR) { - loop->x4E = 1; - } else if (pcode->flags & fIsRead) { - if (pcode->op == PC_LBZX || pcode->op == PC_LHZX || pcode->op == PC_LHAX || pcode->op == PC_LWZX || pcode->op == PC_LFSX || pcode->op == PC_LFDX) - loop->x53 = 1; - } else if (pcode->flags & fIsWrite) { - if (pcode->op == PC_STBX || pcode->op == PC_STHX || pcode->op == PC_STWX || pcode->op == PC_STFSX || pcode->op == PC_STFDX) - loop->x54 = 1; - } else { - if (pcode->op == PC_EIEIO || pcode->op == PC_SYNC || pcode->op == PC_ISYNC) - loop->x57 = 1; - } - } - } - - if (!loop->children && !loop->x4D && loop->bodySize < 32) { - for (list = loop->blocks; list; list = list->next) - list->block->flags |= fPCBlockFlag2000; - } -} - -static void analyzeloops(Loop *loop) { - while (loop) { - if (loop->children) - analyzeloops(loop->children); - analyzeloop(loop); - loop = loop->nextSibling; - } -} - -void analyzeloopsinflowgraph(void) { - if (loopsinflowgraph) - analyzeloops(loopsinflowgraph); -} |