49 bool isLocalIntVar(
jitdata* jd,
s4 varIndex);
81 instr->
sx.
val.
i = constant;
89 instr->
sx.
val.
i = constant;
103 instr->
sx.
val.
i = constant;
111 instr->
sx.
val.
i = constant;
119 instr->
sx.
val.
i = constant;
134 instr->
sx.
s23.s2.varindex = src2;
160 s4 count = instr->
sx.
s23.s3.tablehigh - instr->
sx.
s23.s2.tablelow + 2;
169 s4 count = instr->
sx.
s23.s2.lookupcount;
190 block->
icount = numInstructions;
201 basicblock* trampoline = createBasicblock(jd, 1);
202 opcode_GOTO(trampoline->
iinstr, target);
209 loop->
header->ld->copiedTo = duplicateBasicblock(loop->
header);
212 for (std::vector<basicblock*>::iterator it = loop->
nodes.begin(); it != loop->
nodes.end(); ++it)
214 (*it)->ld->copiedTo = duplicateBasicblock(*it);
233 *lastBlockInLoopPtr = 0;
237 for (std::vector<basicblock*>::iterator it = loop->
nodes.begin(); it != loop->
nodes.end(); ++it)
239 (*it)->ld->belongingTo =
loop;
244 bool loopFound =
false;
249 if (block->ld->belongingTo == loop)
252 if (lastBlock == 0 || lastBlock->ld->belongingTo != loop)
262 if (block->ld->loop == 0)
269 *beforeLoopPtr = lastBlock;
272 *lastBlockInLoopPtr =
block;
279 if (loop->
header->
indepth != 0 || (*lastBlockInLoopPtr)->outdepth != 0)
290 buildBasicblockList(jd, loop, beforeLoop, lastBlockInLoop, loopSwitch, 0, 0, loopTrampoline);
295 buildBasicblockList(jd, loop, beforeLoop, lastBlockInLoop, loopSwitch1, loopSwitch2, 0, loopTrampoline);
313 loopSwitch1->
next = beforeLoop->
next;
314 beforeLoop->
next = loopSwitch1;
327 loopSwitch2->
next = lastLoopSwitch->
next;
328 lastLoopSwitch->
next = loopSwitch2;
330 lastLoopSwitch = loopSwitch2;
336 loopSwitch3->
next = lastLoopSwitch->
next;
337 lastLoopSwitch->
next = loopSwitch3;
339 lastLoopSwitch = loopSwitch3;
343 lastBlockInLoop->
next = loopTrampoline;
346 std::vector<basicblock*> duplicates;
347 duplicates.reserve(loop->
nodes.size() + 1);
351 for (
basicblock* block = lastLoopSwitch->
next; block != loopTrampoline; block = block->
next)
353 end->
next = block->ld->copiedTo;
354 end = block->ld->copiedTo;
357 duplicates.push_back(block->ld->copiedTo);
360 block->ld->copiedTo = 0;
368 for (std::vector<basicblock*>::iterator it = duplicates.begin(); it != duplicates.end(); ++it)
370 pred->nodes.push_back(*it);
372 pred->nodes.push_back(loopTrampoline);
373 pred->nodes.push_back(loopSwitch1);
375 pred->nodes.push_back(loopSwitch2);
377 pred->nodes.push_back(loopSwitch3);
383 for (std::vector<basicblock*>::iterator it = loop->
nodes.begin(); it != loop->
nodes.end(); ++it)
385 for (
instruction* instr = (*it)->iinstr; instr != (*it)->iinstr + (*it)->icount; instr++)
416 if (array == instr->s1.varindex && index == instr->sx.s23.s2.varindex)
437 if (!block->ld->copiedTo)
447 if (instr->dst.block->ld->copiedTo)
448 instr->dst.block = loopSwitch;
451 if (instr->sx.s23.s3.jsrtarget.block->ld->copiedTo)
452 instr->sx.s23.s3.jsrtarget.block = loopSwitch;
457 s4 count = instr->sx.s23.s3.tablehigh - instr->sx.s23.s2.tablelow + 2;
462 if (target->
block->ld->copiedTo)
463 target->
block = loopSwitch;
471 if (instr->sx.s23.s3.lookupdefault.block->ld->copiedTo)
472 instr->sx.s23.s3.lookupdefault.block = loopSwitch;
476 s4 count = instr->sx.s23.s2.lookupcount;
504 if (instr->dst.block->ld->copiedTo)
505 instr->dst.block = instr->dst.block->ld->copiedTo;
508 if (instr->sx.s23.s3.jsrtarget.block->ld->copiedTo)
509 instr->sx.s23.s3.jsrtarget.block = instr->sx.s23.s3.jsrtarget.block->ld->copiedTo;
514 s4 count = instr->sx.s23.s3.tablehigh - instr->sx.s23.s2.tablelow + 2;
519 if (target->
block->ld->copiedTo)
528 if (instr->sx.s23.s3.lookupdefault.block->ld->copiedTo)
529 instr->sx.s23.s3.lookupdefault.block = instr->sx.s23.s3.lookupdefault.block->ld->copiedTo;
533 s4 count = instr->sx.s23.s2.lookupcount;
555 for (std::vector<LoopContainer*>::iterator it = loop->
children.begin(); it != loop->
children.end(); ++it)
557 optimizeLoop(jd, *it);
584 if (!checkLoop(jd, loop, &beforeLoop, &lastBlockInLoop))
593 basicblock* loopSwitch1 = createBasicblock(jd, 2);
594 basicblock* loopSwitch2 = createBasicblock(jd, 4);
600 instr = loopSwitch1->
iinstr;
602 opcode_ALOAD(instr++, array, array);
603 opcode_IFNULL(instr++, array, loop->
header->ld->copiedTo);
605 assert(instr - loopSwitch1->
iinstr == loopSwitch1->
icount);
610 instr = loopSwitch2->
iinstr;
612 opcode_ALOAD(instr++, array, array);
613 opcode_ARRAYLENGTH(instr++, array, jd->ld->freeVariable);
617 assert(instr - loopSwitch2->
iinstr == loopSwitch2->
icount);
620 basicblock* loopTrampoline = createTrampoline(jd, lastBlockInLoop->
next);
623 redirectJumps(jd, loopSwitch1);
624 buildBasicblockList(jd, loop, beforeLoop, lastBlockInLoop, loopSwitch1, loopSwitch2, loopTrampoline);
646 if (!checkLoop(jd, loop, &beforeLoop, &lastBlockInLoop))
657 basicblock* loopSwitch1 = createBasicblock(jd, 2);
658 basicblock* loopSwitch2 = createBasicblock(jd, 2);
659 basicblock* loopSwitch3 = createBasicblock(jd, 4);
665 instr = loopSwitch1->
iinstr;
667 opcode_ILOAD(instr++, invariantVariable, invariantVariable);
670 assert(instr - loopSwitch1->
iinstr == loopSwitch1->
icount);
675 instr = loopSwitch2->
iinstr;
677 opcode_ALOAD(instr++, array, array);
678 opcode_IFNULL(instr++, array, loop->
header->ld->copiedTo);
680 assert(instr - loopSwitch2->
iinstr == loopSwitch2->
icount);
685 instr = loopSwitch3->
iinstr;
687 opcode_ILOAD(instr++, invariantVariable, invariantVariable);
688 opcode_ALOAD(instr++, array, array);
689 opcode_ARRAYLENGTH(instr++, array, jd->ld->freeVariable);
690 opcode_IF_ICMPGE(instr++, invariantVariable, jd->ld->freeVariable, loop->
header->ld->copiedTo);
692 assert(instr - loopSwitch3->
iinstr == loopSwitch3->
icount);
695 basicblock* loopTrampoline = createTrampoline(jd, lastBlockInLoop->
next);
698 redirectJumps(jd, loopSwitch1);
699 buildBasicblockList(jd, loop, beforeLoop, lastBlockInLoop, loopSwitch1, loopSwitch2, loopSwitch3, loopTrampoline);
721 if (!checkLoop(jd, loop, &beforeLoop, &lastBlockInLoop))
730 basicblock* loopSwitch1 = createBasicblock(jd, 2);
731 basicblock* loopSwitch2 = createBasicblock(jd, 3);
737 instr = loopSwitch1->
iinstr;
739 opcode_ALOAD(instr++, array, array);
740 opcode_IFNULL(instr++, array, loop->
header->ld->copiedTo);
742 assert(instr - loopSwitch1->
iinstr == loopSwitch1->
icount);
747 instr = loopSwitch2->
iinstr;
749 opcode_ALOAD(instr++, array, array);
750 opcode_ARRAYLENGTH(instr++, array, jd->ld->freeVariable);
753 assert(instr - loopSwitch2->
iinstr == loopSwitch2->
icount);
756 basicblock* loopTrampoline = createTrampoline(jd, lastBlockInLoop->
next);
759 redirectJumps(jd, loopSwitch1);
760 buildBasicblockList(jd, loop, beforeLoop, lastBlockInLoop, loopSwitch1, loopSwitch2, loopTrampoline);
810 if (!checkLoop(jd, loop, &beforeLoop, &lastBlockInLoop))
821 basicblock* loopSwitch = createBasicblock(jd, 2);
828 opcode_ILOAD(instr++, invariantVariable, invariantVariable);
829 opcode_IFLT(instr++, invariantVariable, 0, loop->
header->ld->copiedTo);
831 assert(instr - loopSwitch->
iinstr == loopSwitch->
icount);
834 basicblock* loopTrampoline = createTrampoline(jd, lastBlockInLoop->
next);
837 redirectJumps(jd, loopSwitch);
838 buildBasicblockList(jd, loop, beforeLoop, lastBlockInLoop, loopSwitch, loopTrampoline);
868 if (!checkLoop(jd, loop, &beforeLoop, &lastBlockInLoop))
877 basicblock* loopSwitch = createBasicblock(jd, 3);
884 opcode_ALOAD(instr++, array, array);
885 opcode_ARRAYLENGTH(instr++, array, jd->ld->freeVariable);
888 assert(instr - loopSwitch->
iinstr == loopSwitch->
icount);
891 basicblock* loopTrampoline = createTrampoline(jd, lastBlockInLoop->
next);
894 redirectJumps(jd, loopSwitch);
895 buildBasicblockList(jd, loop, beforeLoop, lastBlockInLoop, loopSwitch, loopTrampoline);
907 bool isLocalIntVar(
jitdata* jd,
s4 varIndex)
919 jd->ld->freeVariable = jd->
vartop++;
932 for (std::vector<LoopContainer*>::iterator it = jd->ld->rootLoop->children.begin(); it != jd->ld->rootLoop->children.end(); ++it)
934 optimizeLoop(jd, *it);
940 bool optimizationDone =
false;
960 std::vector<s4> instructionArrayMap;
961 std::vector<s4> instructionIndexMap;
964 instructionIndexMap.resize(block->
icount);
1027 const Value& value = values[instr->
sx.
s23.s2.varindex];
1033 if (accessCounts[array][value.
variable()] == 0)
1049 ++accessCounts[array][value.
variable()];
1051 instructionArrayMap[
i] = array;
1052 instructionIndexMap[
i] = value.
variable();
1068 for (
size_t array = 0; array < accessCounts.
size(); array++)
1070 if (!values[array].isUnknown())
1073 for (
size_t index = 0; index < row.
size(); index++)
1076 if (count > bestCount)
1086 s4 smallestConstant = smallestConstants[bestArray][bestIndex];
1087 s4 biggestConstant = biggestConstants[bestArray][bestIndex];
1089 if (bestCount > 3 &&
1091 biggestConstant >= 0)
1093 basicblock* safeBlock = duplicateBasicblock(block);
1098 if (instructionArrayMap[
i] == bestArray && instructionIndexMap[
i] == bestIndex)
1107 basicblock* lowerBoundsCheck = createBasicblock(jd, 2);
1108 instr = lowerBoundsCheck->
iinstr;
1109 opcode_ILOAD(instr++, bestIndex, bestIndex);
1110 opcode_IFLT(instr++, bestIndex, -smallestConstant, safeBlock);
1111 assert(instr - lowerBoundsCheck->
iinstr == lowerBoundsCheck->
icount);
1114 basicblock* nullCheck = createBasicblock(jd, 2);
1115 instr = nullCheck->
iinstr;
1116 opcode_ALOAD(instr++, bestArray, bestArray);
1117 opcode_IFNULL(instr++, bestArray, safeBlock);
1118 assert(instr - nullCheck->
iinstr == nullCheck->
icount);
1121 basicblock* upperBoundsCheck = createBasicblock(jd, 5);
1122 instr = upperBoundsCheck->
iinstr;
1123 opcode_ILOAD(instr++, bestIndex, bestIndex);
1124 opcode_ALOAD(instr++, bestArray, bestArray);
1125 opcode_ARRAYLENGTH(instr++, bestArray, jd->ld->freeVariable);
1126 opcode_ISUBCONST(instr++, jd->ld->freeVariable, biggestConstant, jd->ld->freeVariable);
1127 opcode_IF_ICMPGE(instr++, bestIndex, jd->ld->freeVariable, safeBlock);
1128 assert(instr - upperBoundsCheck->
iinstr == upperBoundsCheck->
icount);
1135 trampoline->
next = safeBlock;
1136 block->
next = trampoline;
1138 nullCheck->
next = upperBoundsCheck;
1139 lowerBoundsCheck->
next = nullCheck;
1141 lastBlock->
next = lowerBoundsCheck;
1146 block->ld->arrayIndexCheck = lowerBoundsCheck;
1147 optimizationDone =
true;
1157 if (optimizationDone)
1169 if (instr->
dst.
block->ld->arrayIndexCheck)
1173 if (instr->
sx.
s23.s3.jsrtarget.block->ld->arrayIndexCheck)
1174 instr->
sx.
s23.s3.jsrtarget.block = instr->
sx.
s23.s3.jsrtarget.block->ld->arrayIndexCheck;
1179 s4 count = instr->
sx.
s23.s3.tablehigh - instr->
sx.
s23.s2.tablelow + 2;
1182 while (--count >= 0)
1184 if (target->
block->ld->arrayIndexCheck)
1185 target->
block = target->
block->ld->arrayIndexCheck;
1193 if (instr->
sx.
s23.s3.lookupdefault.block->ld->arrayIndexCheck)
1194 instr->
sx.
s23.s3.lookupdefault.block = instr->
sx.
s23.s3.lookupdefault.block->ld->arrayIndexCheck;
1198 s4 count = instr->
sx.
s23.s2.lookupcount;
1199 while (--count >= 0)
Contains a Value-object for every variable.
void removePartiallyRedundantChecks(jitdata *jd)
Represents a single loop.
static bool instruction_has_dst(const instruction *iptr)
VariableSet invariantArrays
std::set< s4 >::iterator begin()
bool contains(s4 variableIndex)
static bool var_is_local(const jitdata *jd, s4 i)
union instruction::@12 sx
static Value newUnknown()
std::vector< basicblock * > footers
icmdtable_entry_t icmd_table[256]
struct BasicblockLoopData BasicblockLoopData
bool findFreeVariable(jitdata *jd)
NumericInstruction instruction() const
Represents the result of the addition of a certain IR-variable with a certain constant.
std::vector< basicblock * > nodes
static bool var_is_temp(const jitdata *jd, s4 i)
std::set< s4 >::iterator end()
struct instruction::@12::@13 s23
std::vector< LoopContainer * > children
void groupArrayBoundsChecks(jitdata *jd)