Skip to content

Commit 10476d9

Browse files
committed
Make minor clean up changes to Escape Analysis
This change implements several minor clean-up items for Escape Analysis: 1) The top-level findIgnoreableUses method looks for calls to eaEscapeHelper and then calls a second method named findIgnoreableUses to mark uses of candidates for stack allocation as ignorable. However, that second method doesn't actually find ignoreable uses, it just marks them. This change renames that second method to markUsesAsIgnorable for clarity. Also corrected the spelling of 'ignorable.' 2) Most trace code in Escape Analysis identifies a candidate for stack allocation by the address of the TR::Node for the allocation, which is stored in the _node field of a Candidate object. In two cases, tracing was printing the address of the Candidate object itself. 3) Removed check of environment variable that is used to disable checking in loops for aliases of candidates for stack allocation, and removed method checkAllNewsOnRHSInLoop that was used in that case. The code that it allows to be disabled has been in place for about three years now, so it seems relatively safe. Signed-off-by: Henry Zongaro <zongaro@ca.ibm.com>
1 parent 5395447 commit 10476d9

File tree

2 files changed

+31
-132
lines changed

2 files changed

+31
-132
lines changed

runtime/compiler/optimizer/EscapeAnalysis.cpp

Lines changed: 27 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,6 @@ TR_EscapeAnalysis::TR_EscapeAnalysis(TR::OptimizationManager *manager)
139139
/* monitors */
140140
_removeMonitors = true;
141141
#endif
142-
143-
static char *disableLoopAliasAllocationChecking = feGetEnv("TR_disableEALoopAliasAllocationChecking");
144-
_doLoopAllocationAliasChecking = (disableLoopAliasAllocationChecking == NULL);
145142
}
146143

147144
char *TR_EscapeAnalysis::getClassName(TR::Node *classNode)
@@ -657,7 +654,7 @@ int32_t TR_EscapeAnalysis::performAnalysisOnce()
657654
_fixedVirtualCallSites.setFirst(NULL);
658655

659656
_parms = NULL;
660-
_ignoreableUses = NULL;
657+
_ignorableUses = NULL;
661658
_nonColdLocalObjectsValueNumbers = NULL;
662659
_allLocalObjectsValueNumbers = NULL;
663660
_visitedNodes = NULL;
@@ -678,12 +675,8 @@ int32_t TR_EscapeAnalysis::performAnalysisOnce()
678675
_useDefInfo = optimizer()->getUseDefInfo();
679676
_blocksWithFlushOnEntry = new (trStackMemory()) TR_BitVector(comp()->getFlowGraph()->getNextNodeNumber(), trMemory(), stackAlloc);
680677
_visitedNodes = new (trStackMemory()) TR_BitVector(comp()->getNodeCount(), trMemory(), stackAlloc, growable);
681-
_aliasesOfAllocNode =
682-
_doLoopAllocationAliasChecking
683-
? new (trStackMemory()) TR_BitVector(0, trMemory(), stackAlloc, growable) : NULL;
684-
_aliasesOfOtherAllocNode =
685-
_doLoopAllocationAliasChecking
686-
? new (trStackMemory()) TR_BitVector(0, trMemory(), stackAlloc, growable) : NULL;
678+
_aliasesOfAllocNode = new (trStackMemory()) TR_BitVector(0, trMemory(), stackAlloc, growable);
679+
_aliasesOfOtherAllocNode = new (trStackMemory()) TR_BitVector(0, trMemory(), stackAlloc, growable);
687680

688681
if (!_useDefInfo)
689682
{
@@ -701,7 +694,7 @@ int32_t TR_EscapeAnalysis::performAnalysisOnce()
701694
}
702695
else
703696
{
704-
_ignoreableUses = new (trStackMemory()) TR_BitVector(0, trMemory(), stackAlloc);
697+
_ignorableUses = new (trStackMemory()) TR_BitVector(0, trMemory(), stackAlloc);
705698
_nonColdLocalObjectsValueNumbers = new (trStackMemory()) TR_BitVector(_valueNumberInfo->getNumberOfValues(), trMemory(), stackAlloc);
706699
_allLocalObjectsValueNumbers = new (trStackMemory()) TR_BitVector(_valueNumberInfo->getNumberOfValues(), trMemory(), stackAlloc);
707700
_notOptimizableLocalObjectsValueNumbers = new (trStackMemory()) TR_BitVector(_valueNumberInfo->getNumberOfValues(), trMemory(), stackAlloc);
@@ -712,7 +705,7 @@ int32_t TR_EscapeAnalysis::performAnalysisOnce()
712705
if ( !_candidates.isEmpty())
713706
{
714707
findLocalObjectsValueNumbers();
715-
findIgnoreableUses();
708+
findIgnorableUses();
716709
}
717710

718711
// Complete the candidate info by finding all uses and defs that are reached
@@ -1410,15 +1403,15 @@ int32_t TR_EscapeAnalysis::performAnalysisOnce()
14101403
return cost; // actual cost
14111404
}
14121405

1413-
void TR_EscapeAnalysis::findIgnoreableUses()
1406+
void TR_EscapeAnalysis::findIgnorableUses()
14141407
{
14151408
if (comp()->getOSRMode() != TR::voluntaryOSR)
14161409
return;
14171410

14181411
TR::NodeChecklist visited(comp());
14191412
bool inOSRCodeBlock = false;
14201413

1421-
// Gather all uses under fake prepareForOSR calls - they will be tracked as ignoreable
1414+
// Gather all uses under fake prepareForOSR calls - they will be tracked as ignorable
14221415
for (TR::TreeTop *treeTop = comp()->getStartTree(); treeTop; treeTop = treeTop->getNextTreeTop())
14231416
{
14241417
if (treeTop->getNode()->getOpCodeValue() == TR::BBStart)
@@ -1427,28 +1420,30 @@ void TR_EscapeAnalysis::findIgnoreableUses()
14271420
&& treeTop->getNode()->getNumChildren() > 0
14281421
&& treeTop->getNode()->getFirstChild()->getOpCodeValue() == TR::call
14291422
&& treeTop->getNode()->getFirstChild()->getSymbolReference()->getReferenceNumber() == TR_prepareForOSR)
1430-
{
1431-
TR::Node *callNode = treeTop->getNode()->getFirstChild();
1432-
for (int i = 0; i < callNode->getNumChildren(); ++i)
1433-
findIgnoreableUses(callNode->getChild(i), visited);
1434-
}
1423+
{
1424+
TR::Node *callNode = treeTop->getNode()->getFirstChild();
1425+
for (int i = 0; i < callNode->getNumChildren(); ++i)
1426+
{
1427+
markUsesAsIgnorable(callNode->getChild(i), visited);
1428+
}
1429+
}
14351430
}
14361431
}
14371432

1438-
void TR_EscapeAnalysis::findIgnoreableUses(TR::Node *node, TR::NodeChecklist &visited)
1433+
void TR_EscapeAnalysis::markUsesAsIgnorable(TR::Node *node, TR::NodeChecklist &visited)
14391434
{
14401435
if (visited.contains(node))
14411436
return;
14421437
visited.add(node);
14431438
if (trace())
1444-
traceMsg(comp(), "Marking n%dn as an ignoreable use\n", node->getGlobalIndex());
1445-
_ignoreableUses->set(node->getGlobalIndex());
1439+
traceMsg(comp(), "Marking n%dn as an ignorable use\n", node->getGlobalIndex());
1440+
_ignorableUses->set(node->getGlobalIndex());
14461441

14471442
int32_t i;
14481443
for (i = 0; i < node->getNumChildren(); i++)
14491444
{
14501445
TR::Node *child = node->getChild(i);
1451-
findIgnoreableUses(child, visited);
1446+
markUsesAsIgnorable(child, visited);
14521447
}
14531448
}
14541449

@@ -2494,7 +2489,7 @@ bool TR_EscapeAnalysis::checkDefsAndUses(TR::Node *node, Candidate *candidate)
24942489
TR::Node *useNode = _useDefInfo->getNode(useIndex+_useDefInfo->getFirstUseIndex());
24952490

24962491
// Only add this value number if it's not to be ignored
2497-
if (_ignoreableUses->get(useNode->getGlobalIndex()))
2492+
if (_ignorableUses->get(useNode->getGlobalIndex()))
24982493
{
24992494
continue;
25002495
}
@@ -2622,16 +2617,7 @@ bool TR_EscapeAnalysis::checkOtherDefsOfLoopAllocation(TR::Node *useNode, Candid
26222617
if (trace())
26232618
traceMsg(comp(), " Look at def node [%p] for use node [%p]\n", defNode, useNode);
26242619

2625-
bool allnewsonrhs;
2626-
2627-
if (_doLoopAllocationAliasChecking)
2628-
{
2629-
allnewsonrhs = checkAllNewsOnRHSInLoopWithAliasing(defIndex, useNode, candidate);
2630-
}
2631-
else
2632-
{
2633-
allnewsonrhs = checkAllNewsOnRHSInLoop(defNode, useNode, candidate);
2634-
}
2620+
bool allnewsonrhs = checkAllNewsOnRHSInLoopWithAliasing(defIndex, useNode, candidate);
26352621

26362622

26372623
if (!allnewsonrhs &&
@@ -2673,8 +2659,6 @@ bool TR_EscapeAnalysis::checkOtherDefsOfLoopAllocation(TR::Node *useNode, Candid
26732659

26742660
bool TR_EscapeAnalysis::checkAllNewsOnRHSInLoopWithAliasing(int32_t defIndex, TR::Node *useNode, Candidate *candidate)
26752661
{
2676-
TR_ASSERT(_doLoopAllocationAliasChecking, "Reached checkAllNewsOnRHSInLoopWithAliasing unexpectedly");
2677-
26782662
// _aliasesOfAllocNode contains sym refs that are just aliases for a fresh allocation
26792663
// i.e. it is just a simple attempt at tracking allocations in cases such as :
26802664
// ...
@@ -2760,7 +2744,7 @@ bool TR_EscapeAnalysis::checkAllNewsOnRHSInLoopWithAliasing(int32_t defIndex, TR
27602744

27612745
if (trace())
27622746
{
2763-
traceMsg(comp(), " Look at defNode2 [%p] with otherAllocNode [%p]\n", defNode2, otherAllocNode);
2747+
traceMsg(comp(), " Look at defNode2 [%p] with otherAllocNode [%p]\n", defNode2, otherAllocNode->_node);
27642748
}
27652749

27662750
if (!rhsIsHarmless &&
@@ -2800,7 +2784,7 @@ bool TR_EscapeAnalysis::checkAllNewsOnRHSInLoopWithAliasing(int32_t defIndex, TR
28002784
{
28012785
if (trace())
28022786
{
2803-
traceMsg(comp(), " rhs is harmless for defNode2 [%p] with otherAllocNode [%p]\n", defNode2, otherAllocNode);
2787+
traceMsg(comp(), " rhs is harmless for defNode2 [%p] with otherAllocNode [%p]\n", defNode2, otherAllocNode->_node);
28042788
}
28052789
rhsIsHarmless = true;
28062790
break;
@@ -2880,83 +2864,6 @@ bool TR_EscapeAnalysis::checkAllNewsOnRHSInLoopWithAliasing(int32_t defIndex, TR
28802864
return allnewsonrhs;
28812865
}
28822866

2883-
bool TR_EscapeAnalysis::checkAllNewsOnRHSInLoop(TR::Node *defNode, TR::Node *useNode, Candidate *candidate)
2884-
{
2885-
TR_ASSERT(!_doLoopAllocationAliasChecking, "Reached checkAllNewsOnRHSInLoop unexpectedly");
2886-
2887-
int32_t useIndex = useNode->getUseDefIndex();
2888-
bool allnewsonrhs = false;
2889-
2890-
if ((_valueNumberInfo->getValueNumber(defNode) == _valueNumberInfo->getValueNumber(candidate->_node)))
2891-
{
2892-
if ((defNode->getFirstChild() == candidate->_node) &&
2893-
(_valueNumberInfo->getValueNumber(defNode) == _valueNumberInfo->getValueNumber(useNode)))
2894-
allnewsonrhs = true;
2895-
else
2896-
{
2897-
allnewsonrhs = true;
2898-
TR_UseDefInfo::BitVector defs2(comp()->allocator());
2899-
_useDefInfo->getUseDef(defs2, useIndex);
2900-
TR_UseDefInfo::BitVector::Cursor cursor2(defs2);
2901-
for (cursor2.SetToFirstOne(); cursor2.Valid(); cursor2.SetToNextOne())
2902-
{
2903-
int32_t defIndex2 = cursor2;
2904-
if (defIndex2 == 0)
2905-
{
2906-
allnewsonrhs = false;
2907-
break;
2908-
}
2909-
2910-
TR::Node *defNode2 = _useDefInfo->getNode(defIndex2);
2911-
TR::Node *firstChild = defNode2->getFirstChild();
2912-
bool rhsIsHarmless = false;
2913-
for (Candidate *candidate = _candidates.getFirst(); candidate; candidate = candidate->getNext())
2914-
{
2915-
if (candidate->_node == firstChild)
2916-
{
2917-
rhsIsHarmless = true;
2918-
break;
2919-
}
2920-
}
2921-
2922-
2923-
if (!rhsIsHarmless)
2924-
{
2925-
if (firstChild->getOpCode().hasSymbolReference() &&
2926-
firstChild->getSymbol()->isArrayShadowSymbol())
2927-
{
2928-
TR::Node *addr = firstChild->getFirstChild();
2929-
if (addr->getOpCode().isArrayRef())
2930-
{
2931-
TR::Node *underlyingArray = addr->getFirstChild();
2932-
2933-
int32_t fieldNameLen = -1;
2934-
char *fieldName = NULL;
2935-
if (underlyingArray && underlyingArray->getOpCode().hasSymbolReference() &&
2936-
underlyingArray->getSymbolReference()->getSymbol()->isStaticField())
2937-
{
2938-
fieldName = underlyingArray->getSymbolReference()->getOwningMethod(comp())->staticName(underlyingArray->getSymbolReference()->getCPIndex(), fieldNameLen, comp()->trMemory());
2939-
}
2940-
2941-
if (fieldName && (fieldNameLen > 0) &&
2942-
!strncmp(fieldName, "java/lang/Integer$IntegerCache.cache", 36))
2943-
rhsIsHarmless = true;
2944-
}
2945-
}
2946-
}
2947-
2948-
if (!rhsIsHarmless)
2949-
{
2950-
allnewsonrhs = false;
2951-
break;
2952-
}
2953-
}
2954-
}
2955-
}
2956-
2957-
return allnewsonrhs;
2958-
}
2959-
29602867
bool TR_EscapeAnalysis::checkOverlappingLoopAllocation(TR::Node *useNode, Candidate *candidate)
29612868
{
29622869
// The allocation is inside a loop and a use has been found that has other
@@ -2968,10 +2875,7 @@ bool TR_EscapeAnalysis::checkOverlappingLoopAllocation(TR::Node *useNode, Candid
29682875
//
29692876
TR::TreeTop *treeTop;
29702877
_visitedNodes->empty();
2971-
if (_doLoopAllocationAliasChecking)
2972-
{
2973-
_aliasesOfAllocNode->empty();
2974-
}
2878+
_aliasesOfAllocNode->empty();
29752879
rcount_t numReferences = 0; //candidate->_node->getReferenceCount()-1;
29762880
for (treeTop = candidate->_treeTop->getEnclosingBlock()->getEntry(); treeTop; treeTop = treeTop->getNextTreeTop())
29772881
{
@@ -2998,8 +2902,7 @@ bool TR_EscapeAnalysis::checkOverlappingLoopAllocation(TR::Node *node, TR::Node
29982902

29992903
_visitedNodes->set(node->getGlobalIndex());
30002904

3001-
if (_doLoopAllocationAliasChecking
3002-
&& node->getOpCode().isStore() && node->getSymbol()->isAutoOrParm())
2905+
if (node->getOpCode().isStore() && node->getSymbol()->isAutoOrParm())
30032906
{
30042907
if (node->getFirstChild() == allocNode)
30052908
{
@@ -3021,10 +2924,9 @@ bool TR_EscapeAnalysis::checkOverlappingLoopAllocation(TR::Node *node, TR::Node
30212924
if ((node != allocNode)
30222925
&& (_valueNumberInfo->getValueNumber(node) == _valueNumberInfo->getValueNumber(useNode)))
30232926
{
3024-
if (!_doLoopAllocationAliasChecking
3025-
|| (!(node->getOpCode().isLoadVarDirect()
3026-
&& _aliasesOfAllocNode->get(node->getSymbolReference()->getReferenceNumber()))
3027-
&& (numReferences > 0)))
2927+
if (!(node->getOpCode().isLoadVarDirect()
2928+
&& _aliasesOfAllocNode->get(node->getSymbolReference()->getReferenceNumber()))
2929+
&& (numReferences > 0))
30282930
{
30292931
return false;
30302932
}
@@ -3060,7 +2962,6 @@ void TR_EscapeAnalysis::visitTree(TR::Node *node)
30602962

30612963
void TR_EscapeAnalysis::collectAliasesOfAllocations(TR::Node *node, TR::Node *allocNode)
30622964
{
3063-
TR_ASSERT(_doLoopAllocationAliasChecking, "Reached collectAliasesOfAllocations unexpectedly");
30642965
if (_visitedNodes->get(node->getGlobalIndex()))
30652966
{
30662967
return;

runtime/compiler/optimizer/EscapeAnalysis.hpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2022 IBM Corp. and others
2+
* Copyright (c) 2000, 2023 IBM Corp. and others
33
*
44
* This program and the accompanying materials are made available under
55
* the terms of the Eclipse Public License 2.0 which accompanies this
@@ -508,8 +508,8 @@ class TR_EscapeAnalysis : public TR::Optimization
508508

509509
int32_t performAnalysisOnce();
510510
void findCandidates();
511-
void findIgnoreableUses();
512-
void findIgnoreableUses(TR::Node *node, TR::NodeChecklist& visited);
511+
void findIgnorableUses();
512+
void markUsesAsIgnorable(TR::Node *node, TR::NodeChecklist& visited);
513513
void findLocalObjectsValueNumbers();
514514
void findLocalObjectsValueNumbers(TR::Node *node, TR::NodeChecklist& visited);
515515

@@ -585,7 +585,6 @@ class TR_EscapeAnalysis : public TR::Optimization
585585
*/
586586
void collectAliasesOfAllocations(TR::Node *node, TR::Node *allocNode);
587587

588-
bool checkAllNewsOnRHSInLoop(TR::Node *defNode, TR::Node *useNode, Candidate *candidate);
589588
bool checkAllNewsOnRHSInLoopWithAliasing(int32_t defIndex, TR::Node *useNode, Candidate *candidate);
590589
bool usesValueNumber(Candidate *candidate, int32_t valueNumber);
591590
Candidate *findCandidate(int32_t valueNumber);
@@ -709,7 +708,7 @@ class TR_EscapeAnalysis : public TR::Optimization
709708
TR_UseDefInfo *_useDefInfo;
710709
bool _invalidateUseDefInfo;
711710
TR_BitVector *_otherDefsForLoopAllocation;
712-
TR_BitVector *_ignoreableUses;
711+
TR_BitVector *_ignorableUses;
713712
TR_BitVector *_nonColdLocalObjectsValueNumbers;
714713
TR_BitVector *_allLocalObjectsValueNumbers;
715714
TR_BitVector *_notOptimizableLocalObjectsValueNumbers;
@@ -769,7 +768,6 @@ class TR_EscapeAnalysis : public TR::Optimization
769768
#endif
770769
bool _repeatAnalysis;
771770
bool _somethingChanged;
772-
bool _doLoopAllocationAliasChecking;
773771
TR_ScratchList<TR_DependentAllocations> _dependentAllocations;
774772
TR_BitVector * _vnTemp;
775773
TR_BitVector * _vnTemp2;

0 commit comments

Comments
 (0)