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