Path: blob/master/runtime/compiler/optimizer/FearPointAnalysis.cpp
6000 views
/*******************************************************************************1* Copyright (c) 2000, 2019 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/21#include <stddef.h>22#include <stdint.h>23#include "optimizer/FearPointAnalysis.hpp"24#include "env/StackMemoryRegion.hpp"25#include "codegen/CodeGenerator.hpp"26#include "compile/Compilation.hpp"27#include "control/Options.hpp"28#include "control/Options_inlines.hpp"29#include "env/TRMemory.hpp"30#include "il/Node.hpp"31#include "il/Node_inlines.hpp"32#include "infra/Assert.hpp"33#include "infra/BitVector.hpp"34#include "infra/Checklist.hpp"3536bool TR_FearPointAnalysis::virtualGuardsKillFear()37{38static bool kill = (feGetEnv("TR_FPAnalaysisGuardsDoNotKillFear") == NULL);39return kill;40}4142int32_t TR_FearPointAnalysis::getNumberOfBits() { return 1; }4344bool TR_FearPointAnalysis::supportsGenAndKillSets() { return true; }4546TR_DataFlowAnalysis::Kind TR_FearPointAnalysis::getKind() { return FearPointAnalysis; }4748TR_FearPointAnalysis *TR_FearPointAnalysis::asFearPointAnalysis() { return this; }4950void TR_FearPointAnalysis::analyzeNode(TR::Node *node, vcount_t visitCount, TR_BlockStructure *block, TR_SingleBitContainer *bv)51{52}5354void TR_FearPointAnalysis::analyzeTreeTopsInBlockStructure(TR_BlockStructure *block)55{56}5758/**59* Conduct fear analysis for an set of fear generating nodes, provided60* as a bit vector of their global indices.61*62* The default behaviour will initially search trees for children nodes generating63* fear and then propagate this upwards. When topLevelFearOnly is enabled, this phase64* is skipped and it is assumed that the set of fear generating nodes are all treetop nodes.65*/66TR_FearPointAnalysis::TR_FearPointAnalysis(67TR::Compilation *comp,68TR::Optimizer *optimizer,69TR_Structure *rootStructure,70TR_BitVector &fearGeneratingNodes,71bool topLevelFearOnly,72bool trace) :73TR_BackwardUnionSingleBitContainerAnalysis(comp, comp->getFlowGraph(), optimizer, trace),74_fearGeneratingNodes(fearGeneratingNodes),75_EMPTY(comp->getNodeCount(), trMemory(), stackAlloc),76_topLevelFearOnly(topLevelFearOnly),77_trace(trace)78{7980if (comp->getVisitCount() > 8000)81comp->resetVisitCounts(1);828384// Allocate the map from node to BitVector of fear generating nodes that reach it85// Must be before the stack mark since it will be used by the caller86//87_fearfulNodes = (TR_SingleBitContainer**) trMemory()->allocateStackMemory(comp->getNodeCount() * sizeof(TR_SingleBitContainer *));88TR::NodeChecklist checklist(comp);89for (TR::TreeTop *treeTop = comp->getStartTree(); treeTop; treeTop = treeTop->getNextTreeTop())90{91if (treeTop->getNode()->getOpCodeValue() == TR::BBStart)92{93TR::Block *currentBlock = treeTop->getEnclosingBlock();94if (currentBlock->isOSRCatchBlock() || currentBlock->isOSRCodeBlock())95{96treeTop = currentBlock->getExit();97continue;98}99}100101computeFear(comp, treeTop->getNode(), checklist);102}103104// Only nodes in fearGeneratingNodes will have fear initially, so it is cheaper to105// apply these directly106//107if (_topLevelFearOnly)108computeFearFromBitVector(comp);109110111// Allocate the block info before setting the stack mark - it will be used by112// the caller113//114initializeBlockInfo();115116{117TR::StackMemoryRegion stackMemoryRegion(*trMemory());118performAnalysis(rootStructure, false);119}120121}122123void TR_FearPointAnalysis::computeFear(TR::Compilation *comp, TR::Node *node, TR::NodeChecklist &checklist)124{125if (checklist.contains(node))126return;127checklist.add(node);128_fearfulNodes[node->getGlobalIndex()] = new (trStackMemory()) TR_SingleBitContainer(comp->getNodeCount(), trMemory(), stackAlloc);129130// If only the treetops are of concern then its safe to use the131// cheaper BitVector method to compute initial fear132//133if (_topLevelFearOnly)134return;135136for (int i = 0; i < node->getNumChildren(); ++i)137{138computeFear(comp, node->getChild(i), checklist);139*(_fearfulNodes[node->getGlobalIndex()]) |= *(_fearfulNodes[node->getChild(i)->getGlobalIndex()]);140}141142if (_fearGeneratingNodes.get(node->getGlobalIndex()))143{144if (_trace)145traceMsg(comp, "@@ n%dn generates fear\n", node->getGlobalIndex());146_fearfulNodes[node->getGlobalIndex()]->set();147}148}149150#if defined(DEBUG) || defined(PROD_WITH_ASSUMES)151bool TR_FearPointAnalysis::confirmFearFromBitVector(TR::Node *node)152{153if (_fearGeneratingNodes.get(node->getGlobalIndex()))154return true;155156for (int i = 0; i < node->getNumChildren(); ++i)157if (confirmFearFromBitVector(node->getChild(i)))158return true;159160return false;161}162#endif163164void TR_FearPointAnalysis::computeFearFromBitVector(TR::Compilation *comp)165{166TR_BitVectorIterator nodes(_fearGeneratingNodes);167while (nodes.hasMoreElements())168{169int32_t index = nodes.getNextElement();170if (_trace)171traceMsg(comp, "@@ n%dn generates fear\n", index);172TR_ASSERT(_fearfulNodes[index],173"all fear generating nodes must be treetop nodes when using topLevelFearOnly, otherwise the data structure may not be initialized");174_fearfulNodes[index]->set();175}176177#if defined(DEBUG) || defined(PROD_WITH_ASSUMES)178// Do a complete pass to confirm the cheaper approach was used correctly179TR::NodeChecklist checklist(comp);180for (TR::TreeTop *treeTop = comp->getStartTree(); treeTop; treeTop = treeTop->getNextTreeTop())181{182if (treeTop->getNode()->getOpCodeValue() == TR::BBStart)183{184TR::Block *currentBlock = treeTop->getEnclosingBlock();185if (currentBlock->isOSRCatchBlock() || currentBlock->isOSRCodeBlock())186{187treeTop = currentBlock->getExit();188continue;189}190}191192bool fearful = confirmFearFromBitVector(treeTop->getNode());193TR_ASSERT(_fearfulNodes[treeTop->getNode()->getGlobalIndex()]->get() == fearful,194"all fear generating nodes must be treetop nodes when using topLevelFearOnly, otherwise the initial fear may be incorrect");195}196#endif197}198199TR_SingleBitContainer *TR_FearPointAnalysis::generatedFear(TR::Node *node)200{201TR_SingleBitContainer *returnValue = _fearfulNodes[node->getGlobalIndex()];202if (!returnValue)203return &_EMPTY;204return returnValue;205}206207void TR_FearPointAnalysis::initializeGenAndKillSetInfo()208{209for (int32_t i = 0; i < comp()->getFlowGraph()->getNextNodeNumber(); ++i)210{211_regularGenSetInfo[i] = new (trStackMemory()) TR_SingleBitContainer(getNumberOfBits(),trMemory(), stackAlloc);212_exceptionGenSetInfo[i] = new (trStackMemory()) TR_SingleBitContainer(getNumberOfBits(),trMemory(), stackAlloc);213_regularKillSetInfo[i] = new (trStackMemory()) TR_SingleBitContainer(getNumberOfBits(),trMemory(), stackAlloc);214_exceptionKillSetInfo[i] = new (trStackMemory()) TR_SingleBitContainer(getNumberOfBits(),trMemory(), stackAlloc);215}216217TR::Block *currentBlock = NULL;218bool exceptingTTSeen = false;219for (TR::TreeTop *treeTop = comp()->findLastTree(); treeTop; treeTop = treeTop->getPrevTreeTop())220{221if (treeTop->getNode()->getOpCodeValue() == TR::BBEnd)222{223exceptingTTSeen = false;224currentBlock = treeTop->getEnclosingBlock();225if (currentBlock->isOSRCatchBlock() || currentBlock->isOSRCodeBlock())226{227_regularKillSetInfo[currentBlock->getNumber()]->setAll(getNumberOfBits());228_exceptionKillSetInfo[currentBlock->getNumber()]->setAll(getNumberOfBits());229treeTop = currentBlock->getEntry();230}231continue;232}233234if (treeTop->getNode()->getOpCode().canRaiseException())235{236exceptingTTSeen = true;237_exceptionKillSetInfo[currentBlock->getNumber()]->empty();238}239240if (comp()->isPotentialOSRPointWithSupport(treeTop))241{242_regularKillSetInfo[currentBlock->getNumber()]->setAll(getNumberOfBits());243_exceptionKillSetInfo[currentBlock->getNumber()]->setAll(getNumberOfBits());244_regularGenSetInfo[currentBlock->getNumber()]->empty();245}246247// kill any fear originating from inside248if (virtualGuardsKillFear()249&& treeTop->getNode()->isTheVirtualGuardForAGuardedInlinedCall()250&& comp()->cg()->supportsMergingGuards())251{252_regularKillSetInfo[currentBlock->getNumber()]->setAll(getNumberOfBits());253_exceptionKillSetInfo[currentBlock->getNumber()]->setAll(getNumberOfBits());254//*(_regularKillSetInfo[currentBlock->getNumber()]) |= *(_inlinedCalleeMasks[treeTop->getNode()->getByteCodeInfo().getCallerIndex()]);255//*(_exceptionKillSetInfo[currentBlock->getNumber()]) |= *(_inlinedCalleeMasks[treeTop->getNode()->getByteCodeInfo().getCallerIndex()]);256}257258TR_SingleBitContainer *fear = generatedFear(treeTop->getNode());259*(_regularGenSetInfo[currentBlock->getNumber()] ) |= *fear;260if (exceptingTTSeen)261*(_exceptionGenSetInfo[currentBlock->getNumber()]) |= *fear;262}263}264265bool TR_FearPointAnalysis::postInitializationProcessing()266{267return true;268}269270271272