diff --git a/compiler/optimizer/GeneralLoopUnroller.cpp b/compiler/optimizer/GeneralLoopUnroller.cpp index 3dce0faa3b2..3d7f852c834 100644 --- a/compiler/optimizer/GeneralLoopUnroller.cpp +++ b/compiler/optimizer/GeneralLoopUnroller.cpp @@ -1667,6 +1667,12 @@ bool TR_LoopUnroller::haveIdenticalOffsets(IntrnPtr *intrnPtr1, IntrnPtr *intrnP return false; } +bool TR_LoopUnroller::isSymRefSameTypeArrayShadow(TR::Node *node) + { + // Checks that node symbolReference is an array-shadow with the same data type as the node. + return (node->getSymbolReference()->getReferenceNumber() == comp()->getSymRefTab()->getArrayShadowIndex(node->getDataType())); + } + void TR_LoopUnroller::examineArrayAccesses() { // What we are trying to achieve here is to allow the possibility to schedule array accesses @@ -1696,34 +1702,47 @@ void TR_LoopUnroller::examineArrayAccesses() // bool canProve = true; ListIterator it1(loaa->list); - ArrayAccess *aa1; - ArrayAccess *aa2; - for (aa1 = it1.getFirst(); aa1 && (aa2 = it1.getNext()); aa1 = aa2) - { - if (trace()) - traceMsg(comp(), "\tComparing array accesses %p and %p\n", aa1->aaNode, aa2->aaNode); + ArrayAccess *aa1, *aa2; + aa1 = it1.getFirst(); - // Do not take care of array accesses without internal pointers at this point. - // - if (!aa1->intrnPtrNode || !aa2->intrnPtrNode) + // Ensures that the symbolReference is an array-shadow with the same data type as the node. + if (!isSymRefSameTypeArrayShadow(aa1->aaNode)) + canProve = false; + else + { + for (; aa1 && (aa2 = it1.getNext()); aa1 = aa2) { + if (trace()) + traceMsg(comp(), "\tComparing array accesses %p and %p\n", aa1->aaNode, aa2->aaNode); + + if (!isSymRefSameTypeArrayShadow(aa2->aaNode)) + { + canProve = false; + break; + } + + // Do not take care of array accesses without internal pointers at this point. + // + if (!aa1->intrnPtrNode || !aa2->intrnPtrNode) + { + canProve = false; + break; + } + + IntrnPtr *intrnPtr1 = findIntrnPtr(aa1->intrnPtrNode->getSymbolReference()->getReferenceNumber()); + IntrnPtr *intrnPtr2 = findIntrnPtr(aa2->intrnPtrNode->getSymbolReference()->getReferenceNumber()); + if (intrnPtr1 && intrnPtr2) + { + if (aa1->intrnPtrNode == aa2->intrnPtrNode) + continue; + if (intrnPtr1->offsetNode == intrnPtr2->offsetNode) + continue; + if (haveIdenticalOffsets(intrnPtr1, intrnPtr2)) + continue; + } canProve = false; break; } - - IntrnPtr *intrnPtr1 = findIntrnPtr(aa1->intrnPtrNode->getSymbolReference()->getReferenceNumber()); - IntrnPtr *intrnPtr2 = findIntrnPtr(aa2->intrnPtrNode->getSymbolReference()->getReferenceNumber()); - if (intrnPtr1 && intrnPtr2) - { - if (aa1->intrnPtrNode == aa2->intrnPtrNode) - continue; - if (intrnPtr1->offsetNode == intrnPtr2->offsetNode) - continue; - if (haveIdenticalOffsets(intrnPtr1, intrnPtr2)) - continue; - } - canProve = false; - break; } if (!canProve || !aa1->intrnPtrNode) // if cannot prove or if there is only one element in the list diff --git a/compiler/optimizer/GeneralLoopUnroller.hpp b/compiler/optimizer/GeneralLoopUnroller.hpp index 53fee996813..8e9afb18796 100644 --- a/compiler/optimizer/GeneralLoopUnroller.hpp +++ b/compiler/optimizer/GeneralLoopUnroller.hpp @@ -137,6 +137,7 @@ class TR_LoopUnroller struct IntrnPtr; IntrnPtr *findIntrnPtr(int32_t symRefNum); bool haveIdenticalOffsets(IntrnPtr *intrnPtr1, IntrnPtr *intrnPtr2); + bool isSymRefSameTypeArrayShadow(TR::Node *node); void examineArrayAccesses(); void refineArrayAliasing();