Path: blob/master/runtime/compiler/optimizer/J9Optimizer.cpp
6000 views
/*******************************************************************************1* Copyright (c) 2000, 2022 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*******************************************************************************/2122#if defined(J9ZOS390)23//On zOS XLC linker can't handle files with same name at link time24//This workaround with pragma is needed. What this does is essentially25//give a different name to the codesection (csect) for this file. So it26//doesn't conflict with another file with same name.27#pragma csect(CODE,"J9Optimizer#C")28#pragma csect(STATIC,"J9Optimizer#S")29#pragma csect(TEST,"J9Optimizer#T")30#endif3132#include "optimizer/Optimizer.hpp"3334#include <stddef.h>35#include <stdint.h>36#include "compile/Compilation.hpp"37#include "compile/Method.hpp"38#include "control/Options.hpp"39#include "control/Options_inlines.hpp"40#include "control/Recompilation.hpp"41#include "control/RecompilationInfo.hpp"42#include "il/ResolvedMethodSymbol.hpp"43#include "optimizer/AllocationSinking.hpp"44#include "optimizer/IdiomRecognition.hpp"45#include "optimizer/Inliner.hpp"46#include "optimizer/J9Inliner.hpp"47#include "optimizer/JitProfiler.hpp"48#include "optimizer/LiveVariablesForGC.hpp"49#include "optimizer/OptimizationManager.hpp"50#include "optimizer/OptimizationStrategies.hpp"51#include "optimizer/Optimizations.hpp"52#include "optimizer/PartialRedundancy.hpp"53#include "optimizer/ProfileGenerator.hpp"54#include "optimizer/SequentialStoreSimplifier.hpp"55#include "optimizer/SignExtendLoads.hpp"56#include "optimizer/StringBuilderTransformer.hpp"57#include "optimizer/SwitchAnalyzer.hpp"58#include "optimizer/DynamicLiteralPool.hpp"59#include "optimizer/EscapeAnalysis.hpp"60#include "optimizer/PreEscapeAnalysis.hpp"61#include "optimizer/PostEscapeAnalysis.hpp"62#include "optimizer/DataAccessAccelerator.hpp"63#include "optimizer/HotFieldMarking.hpp"64#include "optimizer/IsolatedStoreElimination.hpp"65#include "optimizer/LoopAliasRefiner.hpp"66#include "optimizer/MonitorElimination.hpp"67#include "optimizer/NewInitialization.hpp"68#include "optimizer/SinkStores.hpp"69#include "optimizer/SPMDParallelizer.hpp"70#include "optimizer/StringPeepholes.hpp"71#include "optimizer/StripMiner.hpp"72#include "optimizer/ValuePropagation.hpp"73#include "optimizer/TrivialDeadBlockRemover.hpp"74#include "optimizer/OSRGuardInsertion.hpp"75#include "optimizer/OSRGuardRemoval.hpp"76#include "optimizer/JProfilingBlock.hpp"77#include "optimizer/JProfilingValue.hpp"78#include "optimizer/JProfilingRecompLoopTest.hpp"79#include "runtime/J9Profiler.hpp"80#include "optimizer/UnsafeFastPath.hpp"81#include "optimizer/TreeLowering.hpp"82#include "optimizer/VarHandleTransformer.hpp"83#include "optimizer/StaticFinalFieldFolding.hpp"84#include "optimizer/HandleRecompilationOps.hpp"85#include "optimizer/MethodHandleTransformer.hpp"86#include "optimizer/VectorAPIExpansion.hpp"878889static const OptimizationStrategy J9EarlyGlobalOpts[] =90{91{ OMR::stringBuilderTransformer },92{ OMR::stringPeepholes }, // need stringpeepholes to catch bigdecimal patterns93{ OMR::inlining },94{ OMR::methodHandleInvokeInliningGroup, OMR::IfEnabled },95{ OMR::staticFinalFieldFolding, },96{ OMR::osrGuardInsertion, OMR::MustBeDone },97{ OMR::osrExceptionEdgeRemoval }, // most inlining is done by now98{ OMR::jProfilingBlock },99{ OMR::stringBuilderTransformer },100{ OMR::stringPeepholes, },101//{ basicBlockOrdering, IfLoops }, // early ordering with no extension102{ OMR::treeSimplification, OMR::IfEnabled },103{ OMR::compactNullChecks }, // cleans up after inlining; MUST be done before PRE104{ OMR::virtualGuardTailSplitter }, // merge virtual guards105{ OMR::treeSimplification },106{ OMR::CFGSimplification },107{ OMR::endGroup }108};109110static const OptimizationStrategy J9EarlyLocalOpts[] =111{112{ OMR::localValuePropagation },113//{ localValuePropagationGroup },114{ OMR::localReordering },115{ OMR::switchAnalyzer },116{ OMR::treeSimplification, OMR::IfEnabled }, // simplify any exprs created by LCP/LCSE117{ OMR::catchBlockRemoval }, // if all possible exceptions in a try were removed by inlining/LCP/LCSE118{ OMR::deadTreesElimination }, // remove any anchored dead loads119{ OMR::profiledNodeVersioning },120{ OMR::endGroup }121};122123static const OptimizationStrategy signExtendLoadsOpts[] =124{125{ OMR::signExtendLoads },126{ OMR::endGroup }127};128129// **************************************************************************130//131// Strategy that is used by full speed debug for methods that do share slots (the old FSD strategy before OSR)132//133// **************************************************************************134static const OptimizationStrategy fsdStrategyOptsForMethodsWithSlotSharing[] =135{136{ OMR::trivialInlining, OMR::IfNotFullInliningUnderOSRDebug }, //added for fsd inlining137{ OMR::inlining, OMR::IfFullInliningUnderOSRDebug }, //added for fsd inlining138{ OMR::basicBlockExtension },139{ OMR::treeSimplification }, //added for fsd inlining140{ OMR::localCSE },141{ OMR::treeSimplification },142{ OMR::cheapTacticalGlobalRegisterAllocatorGroup }, // added for fsd gra143{ OMR::treeLowering, OMR::MustBeDone },144{ OMR::globalLiveVariablesForGC },145{ OMR::regDepCopyRemoval },146{ OMR::endOpts },147};148149150// **************************************************************************151//152// Strategy that is used by full speed debug for methods that do not share slots153//154// **************************************************************************155static const OptimizationStrategy fsdStrategyOptsForMethodsWithoutSlotSharing[] =156{157{ OMR::coldBlockOutlining },158{ OMR::trivialInlining, OMR::IfNotFullInliningUnderOSRDebug }, //added for fsd inlining159{ OMR::inlining, OMR::IfFullInliningUnderOSRDebug }, //added for fsd inlining160{ OMR::virtualGuardTailSplitter }, // merge virtual guards161{ OMR::treeSimplification },162163{ OMR::CFGSimplification, OMR::IfOptServer }, // for WAS trace folding164{ OMR::treeSimplification, OMR::IfOptServer }, // for WAS trace folding165{ OMR::localCSE, OMR::IfEnabledAndOptServer }, // for WAS trace folding166{ OMR::treeSimplification, OMR::IfEnabledAndOptServer }, // for WAS trace folding167{ OMR::globalValuePropagation, },168{ OMR::treeSimplification, OMR::IfEnabled },169{ OMR::cheapObjectAllocationGroup, },170{ OMR::globalValuePropagation, OMR::IfEnabled }, // if inlined a call or an object171{ OMR::treeSimplification, OMR::IfEnabled },172{ OMR::catchBlockRemoval, OMR::IfEnabled }, // if checks were removed173{ OMR::globalValuePropagation, OMR::IfEnabledMarkLastRun}, // mark monitors requiring sync174{ OMR::virtualGuardTailSplitter, OMR::IfEnabled }, // merge virtual guards175{ OMR::CFGSimplification },176{ OMR::globalCopyPropagation, },177{ OMR::lastLoopVersionerGroup, OMR::IfLoops },178{ OMR::globalDeadStoreElimination, OMR::IfLoops },179{ OMR::deadTreesElimination, },180{ OMR::basicBlockOrdering, OMR::IfLoops }, // required for loop reduction181{ OMR::treeSimplification },182{ OMR::loopReduction },183{ OMR::blockShuffling }, // to stress idiom recognition184{ OMR::idiomRecognition, OMR::IfLoops },185{ OMR::blockSplitter },186{ OMR::treeSimplification },187{ OMR::inductionVariableAnalysis, OMR::IfLoopsAndNotProfiling },188{ OMR::generalLoopUnroller, OMR::IfLoopsAndNotProfiling },189{ OMR::samplingJProfiling },190{ OMR::basicBlockExtension, OMR::MarkLastRun }, // extend blocks; move trees around if reqd191{ OMR::treeSimplification }, // revisit; not really required ?192{ OMR::localValuePropagationGroup, },193{ OMR::arraycopyTransformation },194{ OMR::treeSimplification, OMR::IfEnabled },195{ OMR::localDeadStoreElimination, }, // after latest copy propagation196{ OMR::deadTreesElimination, }, // remove dead anchors created by check/store removal197{ OMR::treeSimplification, OMR::IfEnabled },198{ OMR::localCSE },199{ OMR::treeSimplification, OMR::MarkLastRun },200{ OMR::andSimplification, }, //clean up after versioner201{ OMR::compactNullChecks, }, // cleanup at the end202{ OMR::deadTreesElimination, OMR::IfEnabled }, // cleanup at the end203{ OMR::treesCleansing, OMR::IfEnabled },204{ OMR::deadTreesElimination, OMR::IfEnabled }, // cleanup at the end205{ OMR::localCSE, OMR::IfEnabled }, // common up expressions for sunk stores206{ OMR::treeSimplification, OMR::IfEnabledMarkLastRun }, // cleanup the trees after sunk store and localCSE207{ OMR::dynamicLiteralPool, },208{ OMR::localDeadStoreElimination, OMR::IfEnabled }, //remove the astore if no literal pool is required209{ OMR::localCSE, OMR::IfEnabled }, //common up lit pool refs in the same block210{ OMR::deadTreesElimination, OMR::IfEnabled }, // cleanup at the end211{ OMR::treeSimplification, OMR::IfEnabledMarkLastRun }, // Simplify non-normalized address computations introduced by prefetch insertion212{ OMR::trivialDeadTreeRemoval, OMR::IfEnabled }, // final cleanup before opcode expansion213{ OMR::globalDeadStoreElimination, },214{ OMR::cheapTacticalGlobalRegisterAllocatorGroup, },215{ OMR::treeLowering, OMR::MustBeDone },216{ OMR::globalDeadStoreGroup, },217{ OMR::rematerialization, },218{ OMR::compactNullChecks, }, // cleanup at the end219{ OMR::deadTreesElimination, OMR::IfEnabled }, // remove dead anchors created by check/store removal220{ OMR::deadTreesElimination, OMR::IfEnabled }, // remove dead RegStores produced by previous deadTrees pass221{ OMR::globalLiveVariablesForGC },222{ OMR::regDepCopyRemoval },223{ OMR::endOpts },224};225226227static const OptimizationStrategy *fsdStrategies[] =228{229fsdStrategyOptsForMethodsWithSlotSharing,230fsdStrategyOptsForMethodsWithoutSlotSharing231};232233234// **********************************************************235//236// NO-OPT STRATEGY237//238// **********************************************************239static const OptimizationStrategy noOptStrategyOpts[] =240{241{ OMR::trivialDeadTreeRemoval, OMR::IfEnabled },242{ OMR::treeSimplification },243{ OMR::recompilationModifier, OMR::IfEnabled },244{ OMR::treeLowering, OMR::MustBeDone },245{ OMR::globalLiveVariablesForGC, OMR::IfAggressiveLiveness },246{ OMR::endOpts }247};248249250// ***************************************************************************251//252// Strategy for cold methods. This is an early compile for methods known to have253// loops so it should have a light optimization load.254//255// ***************************************************************************256257static const OptimizationStrategy coldStrategyOpts[] =258{259{ OMR::trivialDeadTreeRemoval, OMR::IfEnabled },260{ OMR::coldBlockOutlining },261{ OMR::stringBuilderTransformer, OMR::IfNotQuickStart },262{ OMR::stringPeepholes, OMR::IfNotQuickStart }, // need stringpeepholes to catch bigdecimal patterns263{ OMR::trivialInlining },264{ OMR::jProfilingBlock },265{ OMR::virtualGuardTailSplitter },266{ OMR::recompilationModifier, OMR::IfEnabled },267{ OMR::samplingJProfiling },268{ OMR::treeSimplification }, // cleanup before basicBlockExtension269#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)270{ OMR::recognizedCallTransformer, OMR::MarkLastRun },271#endif272{ OMR::basicBlockExtension },273{ OMR::localValuePropagationGroup },274{ OMR::deadTreesElimination },275{ OMR::localCSE, OMR::IfEnabled },276{ OMR::treeSimplification },277{ OMR::arraycopyTransformation },278{ OMR::sequentialLoadAndStoreColdGroup, OMR::IfEnabled }, // disabled by default, enabled by -Xjit:enableSequentialLoadStoreCold279{ OMR::localCSE, OMR::IfEnabled },280{ OMR::treeSimplification, },281{ OMR::localDeadStoreElimination, OMR::IfEnabled },282{ OMR::deadTreesElimination, OMR::IfEnabled },283{ OMR::localCSE, OMR::IfEnabled },284{ OMR::treeSimplification },285{ OMR::dynamicLiteralPool, OMR::IfNotProfiling },286{ OMR::localCSE, OMR::IfEnabled },287{ OMR::treeSimplification, OMR::MarkLastRun },288{ OMR::rematerialization },289{ OMR::compactNullChecks, OMR::IfEnabled },290{ OMR::signExtendLoadsGroup, OMR::IfEnabled },291{ OMR::jProfilingRecompLoopTest, OMR::IfLoops },292{ OMR::trivialDeadTreeRemoval, },293{ OMR::cheapTacticalGlobalRegisterAllocatorGroup, OMR::IfAOTAndEnabled },294{ OMR::jProfilingValue, OMR::MustBeDone },295{ OMR::treeLowering, OMR::MustBeDone },296{ OMR::globalLiveVariablesForGC, OMR::IfAggressiveLiveness },297{ OMR::profilingGroup, OMR::IfProfiling },298{ OMR::regDepCopyRemoval },299{ OMR::hotFieldMarking },300{ OMR::endOpts }301};302303304// ***************************************************************************305//306// Strategy for warm methods. An initial number of invocations of the method307// have already happened, but this is the first compile of the method.308//309// ***************************************************************************310//311static const OptimizationStrategy warmStrategyOpts[] =312{313{ OMR::trivialDeadTreeRemoval, OMR::IfEnabled},314{ OMR::coldBlockOutlining },315{ OMR::stringBuilderTransformer },316{ OMR::stringPeepholes }, // need stringpeepholes to catch bigdecimal patterns317{ OMR::inlining },318{ OMR::methodHandleInvokeInliningGroup, OMR::IfEnabled },319{ OMR::staticFinalFieldFolding, },320{ OMR::osrGuardInsertion, OMR::MustBeDone },321{ OMR::osrExceptionEdgeRemoval }, // most inlining is done by now322{ OMR::jProfilingBlock },323{ OMR::virtualGuardTailSplitter }, // merge virtual guards324{ OMR::treeSimplification },325{ OMR::sequentialLoadAndStoreWarmGroup, OMR::IfEnabled }, // disabled by default, enabled by -Xjit:enableSequentialLoadStoreWarm326{ OMR::cheapGlobalValuePropagationGroup },327{ OMR::localCSE, OMR::IfVectorAPI },328{ OMR::dataAccessAccelerator }, // globalValuePropagation and inlining might expose opportunities for dataAccessAccelerator329{ OMR::globalCopyPropagation, OMR::IfVoluntaryOSR },330{ OMR::lastLoopVersionerGroup, OMR::IfLoops },331{ OMR::globalDeadStoreElimination, OMR::IfEnabledAndLoops},332{ OMR::deadTreesElimination },333{ OMR::recompilationModifier, OMR::IfEnabledAndNotProfiling },334{ OMR::localReordering, OMR::IfNoLoopsOREnabledAndLoops }, // if required or if not done earlier335{ OMR::basicBlockOrdering, OMR::IfLoops }, // required for loop reduction336{ OMR::treeSimplification },337{ OMR::loopReduction },338{ OMR::blockShuffling }, // to stress idiom recognition339{ OMR::idiomRecognition, OMR::IfLoopsAndNotProfiling },340{ OMR::blockSplitter },341{ OMR::treeSimplification },342{ OMR::inductionVariableAnalysis, OMR::IfLoopsAndNotProfiling },343{ OMR::generalLoopUnroller, OMR::IfLoopsAndNotProfiling },344{ OMR::virtualGuardHeadMerger },345#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)346{ OMR::recognizedCallTransformer, OMR::MarkLastRun },347#endif348{ OMR::basicBlockExtension, OMR::MarkLastRun }, // extend blocks; move trees around if reqd349{ OMR::treeSimplification }, // revisit; not really required ?350{ OMR::localValuePropagationGroup },351{ OMR::arraycopyTransformation },352{ OMR::treeSimplification, OMR::IfEnabled },353{ OMR::redundantAsyncCheckRemoval, OMR::IfNotJitProfiling },354{ OMR::localDeadStoreElimination }, // after latest copy propagation355{ OMR::deadTreesElimination }, // remove dead anchors created by check/store removal356{ OMR::treeSimplification, OMR::IfEnabled },357{ OMR::localCSE },358{ OMR::treeSimplification, OMR::MarkLastRun },359{ OMR::andSimplification, OMR::IfEnabled }, //clean up after versioner360{ OMR::compactNullChecks }, // cleanup at the end361{ OMR::deadTreesElimination, OMR::IfEnabled }, // cleanup at the end362{ OMR::globalCopyPropagation, OMR::IfMethodHandleInvokes }, // Does a lot of good after methodHandleInvokeInliningGroup363{ OMR::generalStoreSinking },364{ OMR::treesCleansing, OMR::IfEnabled },365{ OMR::deadTreesElimination, OMR::IfEnabled }, // cleanup at the end366{ OMR::localCSE, OMR::IfEnabled }, // common up expressions for sunk stores367{ OMR::treeSimplification, OMR::IfEnabledMarkLastRun }, // cleanup the trees after sunk store and localCSE368{ OMR::dynamicLiteralPool, OMR::IfNotProfiling },369{ OMR::samplingJProfiling },370{ OMR::trivialBlockExtension },371{ OMR::localDeadStoreElimination, OMR::IfEnabled }, //remove the astore if no literal pool is required372{ OMR::localCSE, OMR::IfEnabled }, //common up lit pool refs in the same block373{ OMR::deadTreesElimination, OMR::IfEnabled }, // cleanup at the end374{ OMR::signExtendLoadsGroup, OMR::IfEnabled }, // last opt before GRA375{ OMR::treeSimplification, OMR::IfEnabledMarkLastRun }, // Simplify non-normalized address computations introduced by prefetch insertion376{ OMR::trivialDeadTreeRemoval, OMR::IfEnabled }, // final cleanup before opcode expansion377{ OMR::globalDeadStoreElimination, OMR::IfVoluntaryOSR },378{ OMR::arraysetStoreElimination },379{ OMR::checkcastAndProfiledGuardCoalescer },380{ OMR::jProfilingRecompLoopTest, OMR::IfLoops },381{ OMR::globalDeadStoreElimination, OMR::IfVectorAPI }, // global dead store removal382{ OMR::deadTreesElimination, OMR::IfVectorAPI }, // cleanup after dead store removal383{ OMR::vectorAPIExpansion, OMR::IfVectorAPI },384{ OMR::cheapTacticalGlobalRegisterAllocatorGroup, OMR::IfEnabled },385{ OMR::jProfilingValue, OMR::MustBeDone },386{ OMR::treeLowering, OMR::MustBeDone },387{ OMR::globalDeadStoreGroup, },388{ OMR::rematerialization },389{ OMR::compactNullChecks, OMR::IfEnabled }, // cleanup at the end390{ OMR::deadTreesElimination, OMR::IfEnabled }, // remove dead anchors created by check/store removal391{ OMR::deadTreesElimination, OMR::IfEnabled }, // remove dead RegStores produced by previous deadTrees pass392{ OMR::compactLocals, OMR::IfNotJitProfiling }, // analysis results are invalidated by profilingGroup393{ OMR::globalLiveVariablesForGC },394{ OMR::profilingGroup, OMR::IfProfiling },395{ OMR::regDepCopyRemoval },396{ OMR::hotFieldMarking },397{ OMR::endOpts }398};399400401// ***************************************************************************402// A (possibly temporary) strategy for partially optimizing W-Code403// ***************************************************************************404//405static const OptimizationStrategy reducedWarmStrategyOpts[] =406{407{ OMR::inlining },408{ OMR::staticFinalFieldFolding, },409{ OMR::osrGuardInsertion, OMR::MustBeDone },410{ OMR::osrExceptionEdgeRemoval }, // most inlining is done by now411{ OMR::jProfilingBlock },412{ OMR::dataAccessAccelerator }, // immediate does unconditional dataAccessAccelerator after inlining413{ OMR::treeSimplification },414{ OMR::deadTreesElimination },415{ OMR::treeSimplification },416#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)417{ OMR::recognizedCallTransformer, OMR::MarkLastRun },418#endif419{ OMR::basicBlockExtension }, // extend blocks; move trees around if reqd420{ OMR::treeSimplification }, // revisit; not really required ?421{ OMR::localCSE },422{ OMR::treeSimplification, OMR::MarkLastRun },423{ OMR::deadTreesElimination, OMR::IfEnabled }, // cleanup at the end424{ OMR::jProfilingRecompLoopTest, OMR::IfLoops },425{ OMR::globalDeadStoreElimination, OMR::IfVectorAPI }, // global dead store removal426{ OMR::deadTreesElimination, OMR::IfVectorAPI }, // cleanup after dead store removal427{ OMR::vectorAPIExpansion, OMR::IfVectorAPI},428{ OMR::cheapTacticalGlobalRegisterAllocatorGroup, OMR::IfEnabled },429{ OMR::treeLowering, OMR::MustBeDone },430{ OMR::jProfilingValue, OMR::MustBeDone },431{ OMR::hotFieldMarking },432{ OMR::endOpts }433};434435436// ***************************************************************************437//438// Strategy for hot methods. The method has been compiled before and sampling439// has discovered that it is hot.440//441// ***************************************************************************442const OptimizationStrategy hotStrategyOpts[] =443{444{ OMR::trivialDeadTreeRemoval, OMR::IfEnabled },445{ OMR::coldBlockOutlining },446{ OMR::earlyGlobalGroup },447{ OMR::earlyLocalGroup },448{ OMR::stripMiningGroup, OMR::IfLoops }, // strip mining in loops449{ OMR::loopReplicator, OMR::IfLoops }, // tail-duplication in loops450{ OMR::blockSplitter, OMR::IfNews }, // treeSimplification + blockSplitter + VP => opportunity for EA451{ OMR::expensiveGlobalValuePropagationGroup },452{ OMR::localCSE, OMR::IfVectorAPI },453{ OMR::loopCanonicalization, OMR::IfVectorAPI },454{ OMR::partialRedundancyEliminationGroup, OMR::IfVectorAPI },455{ OMR::globalDeadStoreElimination, OMR::IfVectorAPI }, // global dead store removal456{ OMR::deadTreesElimination, OMR::IfVectorAPI }, // cleanup after dead store removal457{ OMR::vectorAPIExpansion, OMR::IfVectorAPI },458{ OMR::dataAccessAccelerator },459{ OMR::osrGuardRemoval, OMR::IfEnabled }, // run after calls/monents/asyncchecks have been removed460{ OMR::globalDeadStoreGroup, },461{ OMR::idiomRecognition, OMR::IfLoopsAndNotProfiling }, // Early pass of idiomRecognition - Loop Canonicalizer transformations break certain idioms (i.e. arrayTranslateAndTest)462{ OMR::globalCopyPropagation, OMR::IfNoLoops },463{ OMR::loopCanonicalizationGroup, OMR::IfLoops }, // canonicalize loops (improve fall throughs)464{ OMR::inductionVariableAnalysis, OMR::IfLoops },465{ OMR::redundantInductionVarElimination, OMR::IfLoops },466{ OMR::loopAliasRefinerGroup, OMR::IfLoops },467{ OMR::recompilationModifier, OMR::IfEnabledAndNotProfiling },468{ OMR::partialRedundancyEliminationGroup },469{ OMR::globalDeadStoreElimination, OMR::IfLoopsAndNotProfiling },470{ OMR::inductionVariableAnalysis, OMR::IfLoopsAndNotProfiling },471{ OMR::loopSpecializerGroup, OMR::IfLoopsAndNotProfiling },472{ OMR::inductionVariableAnalysis, OMR::IfLoopsAndNotProfiling },473{ OMR::generalLoopUnroller, OMR::IfLoopsAndNotProfiling }, // unroll Loops474#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)475{ OMR::recognizedCallTransformer, OMR::MarkLastRun },476#endif477{ OMR::blockManipulationGroup },478{ OMR::lateLocalGroup },479{ OMR::sequentialStoreSimplificationGroup, }, // reduce sequential stores into an arrayset480{ OMR::redundantAsyncCheckRemoval, OMR::IfNotJitProfiling }, // optimize async check placement481{ OMR::recompilationModifier, OMR::IfProfiling }, // do before GRA to avoid commoning of longs afterwards482{ OMR::globalCopyPropagation, OMR::IfMoreThanOneBlock }, // Can produce opportunities for store sinking483{ OMR::generalStoreSinking },484485486{ OMR::localCSE, OMR::IfEnabled }, //common up lit pool refs in the same block487{ OMR::treeSimplification, OMR::IfEnabled }, // cleanup the trees after sunk store and localCSE488{ OMR::dynamicLiteralPool, OMR::IfNotProfiling },489{ OMR::trivialBlockExtension },490{ OMR::localDeadStoreElimination, OMR::IfEnabled }, //remove the astore if no literal pool is required491{ OMR::localCSE, OMR::IfEnabled }, //common up lit pool refs in the same block492{ OMR::deadTreesElimination, OMR::IfEnabled }, // cleanup at the end493{ OMR::signExtendLoadsGroup, OMR::IfEnabled }, // last opt before GRA494{ OMR::trivialDeadTreeRemoval, OMR::IfEnabled }, // final cleanup before opcode expansion495{ OMR::arraysetStoreElimination },496{ OMR::localValuePropagation, OMR::MarkLastRun },497{ OMR::arraycopyTransformation },498{ OMR::checkcastAndProfiledGuardCoalescer },499{ OMR::jProfilingRecompLoopTest, OMR::IfLoops },500{ OMR::tacticalGlobalRegisterAllocatorGroup, OMR::IfEnabled },501{ OMR::jProfilingValue, OMR::MustBeDone },502{ OMR::treeLowering, OMR::MustBeDone },503{ OMR::globalDeadStoreElimination, OMR::IfMoreThanOneBlock }, // global dead store removal504{ OMR::deadTreesElimination }, // cleanup after dead store removal505{ OMR::compactNullChecks }, // cleanup at the end506{ OMR::finalGlobalGroup }, // done just before codegen507{ OMR::profilingGroup, OMR::IfProfiling },508{ OMR::regDepCopyRemoval },509{ OMR::hotFieldMarking },510{ OMR::endOpts }511};512513// ***************************************************************************514//515// Strategy for very hot methods. This is not currently used, same as hot.516//517// ***************************************************************************518const OptimizationStrategy veryHotStrategyOpts[] =519{520{ OMR::hotStrategy },521{ OMR::endOpts }522};523524// ***************************************************************************525//526// Strategy for scorching hot methods. This is the last time the method will527// be compiled, so throw everything (within reason) at it.528//529// ***************************************************************************530const OptimizationStrategy scorchingStrategyOpts[] =531{532#if 0533{ OMR::hotStrategy },534{ OMR::endOpts }535#else536{ OMR::coldBlockOutlining },537{ OMR::earlyGlobalGroup },538{ OMR::earlyLocalGroup },539{ OMR::andSimplification }, // needs commoning across blocks to work well; must be done after versioning540{ OMR::stripMiningGroup, OMR::IfLoops }, // strip mining in loops541{ OMR::loopReplicator, OMR::IfLoops }, // tail-duplication in loops542{ OMR::blockSplitter, OMR::IfNews }, // treeSimplification + blockSplitter + VP => opportunity for EA543{ OMR::arrayPrivatizationGroup, OMR::IfNews }, // must precede escape analysis544{ OMR::veryExpensiveGlobalValuePropagationGroup },545{ OMR::dataAccessAccelerator }, //always run after GVP546{ OMR::osrGuardRemoval, OMR::IfEnabled }, // run after calls/monents/asyncchecks have been removed547{ OMR::globalDeadStoreGroup, },548{ OMR::idiomRecognition, OMR::IfLoopsAndNotProfiling }, // Early pass of idiomRecognition - Loop Canonicalizer transformations break certain idioms (i.e. arrayTranslateAndTest)549{ OMR::globalCopyPropagation, OMR::IfNoLoops },550{ OMR::localCSE, OMR::IfVectorAPI },551{ OMR::loopCanonicalization, OMR::IfVectorAPI },552{ OMR::partialRedundancyEliminationGroup, OMR::IfVectorAPI },553{ OMR::globalDeadStoreElimination, OMR::IfVectorAPI }, // global dead store removal554{ OMR::deadTreesElimination, OMR::IfVectorAPI }, // cleanup after dead store removal555{ OMR::vectorAPIExpansion, OMR::IfVectorAPI },556{ OMR::loopCanonicalizationGroup, OMR::IfLoops }, // canonicalize loops (improve fall throughs)557{ OMR::inductionVariableAnalysis, OMR::IfLoops },558{ OMR::redundantInductionVarElimination, OMR::IfLoops },559{ OMR::loopAliasRefinerGroup, OMR::IfLoops }, // version loops to improve aliasing (after versioned to reduce code growth)560{ OMR::expressionsSimplification, OMR::IfLoops },561{ OMR::recompilationModifier, OMR::IfEnabled },562{ OMR::partialRedundancyEliminationGroup },563{ OMR::globalDeadStoreElimination, OMR::IfLoops },564{ OMR::inductionVariableAnalysis, OMR::IfLoops },565{ OMR::loopSpecializerGroup, OMR::IfLoops },566{ OMR::inductionVariableAnalysis, OMR::IfLoops },567{ OMR::generalLoopUnroller, OMR::IfLoops }, // unroll Loops568{ OMR::blockSplitter, OMR::MarkLastRun },569#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)570{ OMR::recognizedCallTransformer, OMR::MarkLastRun },571#endif572{ OMR::blockManipulationGroup },573{ OMR::lateLocalGroup },574{ OMR::sequentialStoreSimplificationGroup }, // reduce sequential stores into an arrayset575{ OMR::redundantAsyncCheckRemoval, OMR::IfNotJitProfiling }, // optimize async check placement576{ OMR::recompilationModifier, OMR::IfProfiling }, // do before GRA to avoid commoning of longs afterwards577{ OMR::globalCopyPropagation, OMR::IfMoreThanOneBlock }, // Can produce opportunities for store sinking578{ OMR::generalStoreSinking },579{ OMR::localCSE, OMR::IfEnabled }, //common up lit pool refs in the same block580{ OMR::treeSimplification, OMR::IfEnabled }, // cleanup the trees after sunk store and localCSE581{ OMR::dynamicLiteralPool, OMR::IfNotProfiling },582{ OMR::trivialBlockExtension },583{ OMR::localDeadStoreElimination, OMR::IfEnabled }, //remove the astore if no literal pool is required584{ OMR::localCSE, OMR::IfEnabled }, //common up lit pool refs in the same block585{ OMR::signExtendLoadsGroup, OMR::IfEnabled }, // last opt before GRA586{ OMR::arraysetStoreElimination },587{ OMR::localValuePropagation, OMR::MarkLastRun },588{ OMR::arraycopyTransformation },589{ OMR::checkcastAndProfiledGuardCoalescer },590{ OMR::tacticalGlobalRegisterAllocatorGroup, OMR::IfEnabled },591{ OMR::jProfilingValue, OMR::MustBeDone },592{ OMR::treeLowering, OMR::MustBeDone },593{ OMR::globalDeadStoreElimination, OMR::IfMoreThanOneBlock }, // global dead store removal594{ OMR::deadTreesElimination }, // cleanup after dead store removal595{ OMR::compactNullChecks }, // cleanup at the end596{ OMR::finalGlobalGroup }, // done just before codegen597{ OMR::profilingGroup, OMR::IfProfiling },598{ OMR::regDepCopyRemoval },599{ OMR::hotFieldMarking },600{ OMR::endOpts }601#endif602};603604const OptimizationStrategy sequentialLoadAndStoreColdOpts[] =605{606{ OMR::localDeadStoreElimination },607{ OMR::deadTreesElimination },608{ OMR::expensiveGlobalValuePropagationGroup },609{ OMR::sequentialStoreSimplificationGroup },610{ OMR::endGroup }611};612613const OptimizationStrategy sequentialLoadAndStoreWarmOpts[] =614{615{ OMR::localValuePropagationGroup },616{ OMR::localDeadStoreElimination },617{ OMR::deadTreesElimination },618{ OMR::expensiveGlobalValuePropagationGroup },619{ OMR::sequentialStoreSimplificationGroup },620{ OMR::endGroup }621};622623const OptimizationStrategy sequentialStoreSimplificationOpts[] =624{625{ OMR::treeSimplification },626{ OMR::sequentialStoreSimplification },627{ OMR::treeSimplification }, // might fold expressions created by versioning/induction variables628{ OMR::endGroup }629};630631632// **********************************************************633//634// AHEAD-OF-TIME-COMPILATION STRATEGY635//636// **********************************************************637static const OptimizationStrategy AOTStrategyOpts[] =638{639{ OMR::earlyGlobalGroup },640{ OMR::earlyLocalGroup },641{ OMR::stripMiningGroup, OMR::IfLoops }, // strip mining in loops642{ OMR::loopReplicator, OMR::IfLoops }, // tail-duplication in loops643{ OMR::expensiveGlobalValuePropagationGroup },644{ OMR::localCSE, OMR::IfVectorAPI },645{ OMR::loopCanonicalization, OMR::IfVectorAPI },646{ OMR::partialRedundancyEliminationGroup, OMR::IfVectorAPI },647{ OMR::globalDeadStoreElimination, OMR::IfVectorAPI }, // global dead store removal648{ OMR::deadTreesElimination, OMR::IfVectorAPI }, // cleanup after dead store removal649{ OMR::vectorAPIExpansion, OMR::IfVectorAPI },650{ OMR::globalDeadStoreGroup, },651{ OMR::globalCopyPropagation, OMR::IfNoLoops },652{ OMR::loopCanonicalizationGroup, OMR::IfLoops }, // canonicalize loops (improve fall throughs) and versioning653{ OMR::partialRedundancyEliminationGroup },654{ OMR::globalDeadStoreElimination, OMR::IfLoops },655{ OMR::generalLoopUnroller, OMR::IfLoops }, // unroll Loops656{ OMR::blockManipulationGroup },657{ OMR::lateLocalGroup },658{ OMR::sequentialStoreSimplificationGroup }, // reduce sequential stores into an arrayset659{ OMR::redundantAsyncCheckRemoval, OMR::IfNotJitProfiling }, // optimize async check placement660{ OMR::dynamicLiteralPool, OMR::IfNotProfiling },661{ OMR::localDeadStoreElimination, OMR::IfEnabled }, //remove the astore if no literal pool is required662{ OMR::localCSE, OMR::IfEnabled }, //common up lit pool refs in the same block663{ OMR::signExtendLoadsGroup, OMR::IfEnabled }, // last opt before GRA664{ OMR::arraysetStoreElimination },665{ OMR::tacticalGlobalRegisterAllocatorGroup, OMR::IfEnabled },666{ OMR::treeLowering, OMR::MustBeDone},667{ OMR::globalCopyPropagation, OMR::IfMoreThanOneBlock}, // global copy propagation668{ OMR::globalDeadStoreElimination, OMR::IfMoreThanOneBlock}, // global dead store removal669{ OMR::deadTreesElimination }, // cleanup after dead store removal670{ OMR::compactNullChecks }, // cleanup at the end671{ OMR::finalGlobalGroup }, // done just before codegen672{ OMR::regDepCopyRemoval },673{ OMR::endOpts }674};675676677static const OptimizationStrategy *j9CompilationStrategies[] =678{679noOptStrategyOpts,680coldStrategyOpts,681warmStrategyOpts,682hotStrategyOpts,683veryHotStrategyOpts,684scorchingStrategyOpts,685AOTStrategyOpts,686reducedWarmStrategyOpts687};688689690// ***************************************************************************691//692// Cheaper strategy for warm methods.693//694// ***************************************************************************695//696static const OptimizationStrategy cheapWarmStrategyOpts[] =697{698{ OMR::trivialDeadTreeRemoval, OMR::IfEnabled },699{ OMR::coldBlockOutlining },700{ OMR::stringBuilderTransformer },701{ OMR::stringPeepholes }, // need stringpeepholes to catch bigdecimal patterns702{ OMR::inlining },703{ OMR::methodHandleInvokeInliningGroup, OMR::IfEnabled },704{ OMR::staticFinalFieldFolding, },705{ OMR::osrGuardInsertion, OMR::MustBeDone },706{ OMR::osrExceptionEdgeRemoval }, // most inlining is done by now707{ OMR::jProfilingBlock },708{ OMR::virtualGuardTailSplitter }, // merge virtual guards709{ OMR::treeSimplification },710#ifdef TR_HOST_S390711{ OMR::sequentialLoadAndStoreWarmGroup, OMR::IfEnabled },712#endif713{ OMR::cheapGlobalValuePropagationGroup },714{ OMR::localCSE, OMR::IfVectorAPI },715{ OMR::dataAccessAccelerator },716#ifdef TR_HOST_S390717{ OMR::globalCopyPropagation, OMR::IfVoluntaryOSR },718#endif719{ OMR::lastLoopVersionerGroup, OMR::IfLoops },720#ifdef TR_HOST_S390721{ OMR::globalDeadStoreElimination, OMR::IfEnabledAndLoops },722{ OMR::deadTreesElimination },723{ OMR::recompilationModifier, OMR::IfEnabledAndNotProfiling },724{ OMR::localReordering, OMR::IfNoLoopsOREnabledAndLoops },725{ OMR::basicBlockOrdering, OMR::IfLoops },726{ OMR::treeSimplification },727{ OMR::loopReduction },728{ OMR::blockShuffling },729#endif730{ OMR::localCSE, OMR::IfLoopsAndNotProfiling },731{ OMR::idiomRecognition, OMR::IfLoopsAndNotProfiling },732{ OMR::blockSplitter },733{ OMR::treeSimplification }, // revisit; not really required ?734{ OMR::virtualGuardHeadMerger },735#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)736{ OMR::recognizedCallTransformer, OMR::MarkLastRun },737#endif738{ OMR::basicBlockExtension, OMR::MarkLastRun }, // extend blocks; move trees around if reqd739{ OMR::localValuePropagationGroup },740{ OMR::explicitNewInitialization, OMR::IfNews },741{ OMR::arraycopyTransformation },742{ OMR::treeSimplification, OMR::IfEnabled },743{ OMR::asyncCheckInsertion, OMR::IfNotJitProfiling },744{ OMR::localCSE },745{ OMR::treeSimplification, OMR::MarkLastRun },746{ OMR::andSimplification, OMR::IfEnabled }, //clean up after versioner747{ OMR::compactNullChecks }, // cleanup at the end748{ OMR::deadTreesElimination, OMR::IfEnabled }, // cleanup at the end749{ OMR::globalCopyPropagation, OMR::IfMethodHandleInvokes }, // Does a lot of good after methodHandleInvokeInliningGroup750{ OMR::treesCleansing, OMR::IfEnabled },751{ OMR::deadTreesElimination, OMR::IfEnabled }, // cleanup at the end752{ OMR::localCSE, OMR::IfEnabled }, // common up expressions for sunk stores753{ OMR::treeSimplification, OMR::IfEnabledMarkLastRun }, // cleanup the trees after sunk store and localCSE754755/** \breif756* This optimization is performance critical on z Systems. On z Systems a literal pool register is blocked off757* by default at the start of the compilation since materializing this address could be expensive depending on758* the architecture level we are executing on. This optimization pass validates support for dynamically759* materializing the literal pool address and frees up the literal pool register for register allocation.760*/761{ OMR::dynamicLiteralPool, OMR::IfNotProfiling },762{ OMR::samplingJProfiling },763{ OMR::trivialBlockExtension },764{ OMR::localCSE, OMR::IfEnabled }, //common up lit pool refs in the same block765{ OMR::deadTreesElimination, OMR::IfEnabled }, // cleanup at the end766{ OMR::treeSimplification, OMR::IfEnabledMarkLastRun }, // Simplify non-normalized address computations introduced by prefetch insertion767{ OMR::trivialDeadTreeRemoval, OMR::IfEnabled }, // final cleanup before opcode expansion768{ OMR::jProfilingRecompLoopTest, OMR::IfLoops },769{ OMR::globalDeadStoreElimination, OMR::IfVectorAPI }, // global dead store removal770{ OMR::deadTreesElimination, OMR::IfVectorAPI }, // cleanup after dead store removal771{ OMR::vectorAPIExpansion, OMR::IfVectorAPI },772{ OMR::cheapTacticalGlobalRegisterAllocatorGroup, OMR::IfEnabled },773{ OMR::jProfilingValue, OMR::MustBeDone },774{ OMR::treeLowering, OMR::MustBeDone },775{ OMR::globalDeadStoreGroup, },776{ OMR::compactNullChecks, OMR::IfEnabled }, // cleanup at the end777{ OMR::deadTreesElimination, OMR::IfEnabled }, // remove dead anchors created by check/store removal778{ OMR::deadTreesElimination, OMR::IfEnabled }, // remove dead RegStores produced by previous deadTrees pass779{ OMR::redundantGotoElimination, OMR::IfEnabledAndNotJitProfiling }, // dead store and dead tree elimination may have left empty blocks780{ OMR::compactLocals, OMR::IfNotJitProfiling }, // analysis results are invalidated by profilingGroup781{ OMR::globalLiveVariablesForGC },782{ OMR::profilingGroup, OMR::IfProfiling },783{ OMR::regDepCopyRemoval },784{ OMR::hotFieldMarking },785{ OMR::endOpts }786};787788789static const OptimizationStrategy profilingOpts[] =790{791{ OMR::profileGenerator, OMR::MustBeDone },792{ OMR::deadTreesElimination, OMR::IfEnabled },793{ OMR::endGroup }794};795796static const OptimizationStrategy cheapTacticalGlobalRegisterAllocatorOpts[] =797{798{ OMR::redundantGotoElimination, OMR::IfNotJitProfiling }, // need to be run before global register allocator799{ OMR::tacticalGlobalRegisterAllocator, OMR::IfEnabled },800{ OMR::endGroup }801};802803804J9::Optimizer::Optimizer(TR::Compilation *comp, TR::ResolvedMethodSymbol *methodSymbol, bool isIlGen,805const OptimizationStrategy *strategy, uint16_t VNType)806: OMR::Optimizer(comp, methodSymbol, isIlGen, strategy, VNType)807{808// initialize additional J9 optimizations809810_opts[OMR::inlining] =811new (comp->allocator()) TR::OptimizationManager(self(), TR_Inliner::create, OMR::inlining);812_opts[OMR::targetedInlining] =813new (comp->allocator()) TR::OptimizationManager(self(), TR_Inliner::create, OMR::targetedInlining);814_opts[OMR::targetedInlining]->setOptPolicy(new (comp->allocator()) TR_J9JSR292InlinerPolicy(comp));815816_opts[OMR::trivialInlining] =817new (comp->allocator()) TR::OptimizationManager(self(), TR_TrivialInliner::create, OMR::trivialInlining);818819_opts[OMR::dynamicLiteralPool] =820new (comp->allocator()) TR::OptimizationManager(self(), TR_DynamicLiteralPool::create, OMR::dynamicLiteralPool);821_opts[OMR::arraycopyTransformation] =822new (comp->allocator()) TR::OptimizationManager(self(), TR::ArraycopyTransformation::create, OMR::arraycopyTransformation);823_opts[OMR::signExtendLoads] =824new (comp->allocator()) TR::OptimizationManager(self(), TR_SignExtendLoads::create, OMR::signExtendLoads);825_opts[OMR::sequentialStoreSimplification] =826new (comp->allocator()) TR::OptimizationManager(self(), TR_SequentialStoreSimplifier::create, OMR::sequentialStoreSimplification);827_opts[OMR::explicitNewInitialization] =828new (comp->allocator()) TR::OptimizationManager(self(), TR_LocalNewInitialization::create, OMR::explicitNewInitialization);829_opts[OMR::redundantMonitorElimination] =830new (comp->allocator()) TR::OptimizationManager(self(), TR::MonitorElimination::create, OMR::redundantMonitorElimination);831_opts[OMR::preEscapeAnalysis] =832new (comp->allocator()) TR::OptimizationManager(self(), TR_PreEscapeAnalysis::create, OMR::preEscapeAnalysis);833_opts[OMR::escapeAnalysis] =834new (comp->allocator()) TR::OptimizationManager(self(), TR_EscapeAnalysis::create, OMR::escapeAnalysis);835_opts[OMR::postEscapeAnalysis] =836new (comp->allocator()) TR::OptimizationManager(self(), TR_PostEscapeAnalysis::create, OMR::postEscapeAnalysis);837_opts[OMR::isolatedStoreElimination] =838new (comp->allocator()) TR::OptimizationManager(self(), TR_IsolatedStoreElimination::create, OMR::isolatedStoreElimination);839_opts[OMR::localLiveVariablesForGC] =840new (comp->allocator()) TR::OptimizationManager(self(), TR_LocalLiveVariablesForGC::create, OMR::localLiveVariablesForGC);841_opts[OMR::globalLiveVariablesForGC] =842new (comp->allocator()) TR::OptimizationManager(self(), TR_GlobalLiveVariablesForGC::create, OMR::globalLiveVariablesForGC);843_opts[OMR::recompilationModifier] =844new (comp->allocator()) TR::OptimizationManager(self(), TR_RecompilationModifier::create, OMR::recompilationModifier);845_opts[OMR::profileGenerator] =846new (comp->allocator()) TR::OptimizationManager(self(), TR_ProfileGenerator::create, OMR::profileGenerator);847_opts[OMR::dataAccessAccelerator] =848new (comp->allocator()) TR::OptimizationManager(self(), TR_DataAccessAccelerator::create, OMR::dataAccessAccelerator);849_opts[OMR::stringBuilderTransformer] =850new (comp->allocator()) TR::OptimizationManager(self(), TR_StringBuilderTransformer::create, OMR::stringBuilderTransformer);851_opts[OMR::stringPeepholes] =852new (comp->allocator()) TR::OptimizationManager(self(), TR_StringPeepholes::create, OMR::stringPeepholes);853_opts[OMR::switchAnalyzer] =854new (comp->allocator()) TR::OptimizationManager(self(), TR::SwitchAnalyzer::create, OMR::switchAnalyzer);855_opts[OMR::treeLowering] =856new (comp->allocator()) TR::OptimizationManager(self(), TR::TreeLowering::create, OMR::treeLowering);857_opts[OMR::varHandleTransformer] =858new (comp->allocator()) TR::OptimizationManager(self(), TR_VarHandleTransformer::create, OMR::varHandleTransformer);859_opts[OMR::methodHandleTransformer] =860new (comp->allocator()) TR::OptimizationManager(self(), TR_MethodHandleTransformer::create, OMR::methodHandleTransformer);861_opts[OMR::unsafeFastPath] =862new (comp->allocator()) TR::OptimizationManager(self(), TR_UnsafeFastPath::create, OMR::unsafeFastPath);863_opts[OMR::idiomRecognition] =864new (comp->allocator()) TR::OptimizationManager(self(), TR_CISCTransformer::create, OMR::idiomRecognition);865_opts[OMR::loopAliasRefiner] =866new (comp->allocator()) TR::OptimizationManager(self(), TR_LoopAliasRefiner::create, OMR::loopAliasRefiner);867_opts[OMR::allocationSinking] =868new (comp->allocator()) TR::OptimizationManager(self(), TR_AllocationSinking::create, OMR::allocationSinking);869_opts[OMR::samplingJProfiling] =870new (comp->allocator()) TR::OptimizationManager(self(), TR_JitProfiler::create, OMR::samplingJProfiling);871_opts[OMR::SPMDKernelParallelization] =872new (comp->allocator()) TR::OptimizationManager(self(), TR_SPMDKernelParallelizer::create, OMR::SPMDKernelParallelization);873_opts[OMR::trivialDeadBlockRemover] =874new (comp->allocator()) TR::OptimizationManager(self(), TR_TrivialDeadBlockRemover::create, OMR::trivialDeadBlockRemover);875_opts[OMR::osrGuardInsertion] =876new (comp->allocator()) TR::OptimizationManager(self(), TR_OSRGuardInsertion::create, OMR::osrGuardInsertion);877_opts[OMR::osrGuardRemoval] =878new (comp->allocator()) TR::OptimizationManager(self(), TR_OSRGuardRemoval::create, OMR::osrGuardRemoval);879_opts[OMR::jProfilingBlock] =880new (comp->allocator()) TR::OptimizationManager(self(), TR_JProfilingBlock::create, OMR::jProfilingBlock);881_opts[OMR::jProfilingRecompLoopTest] =882new (comp->allocator()) TR::OptimizationManager(self(), TR_JProfilingRecompLoopTest::create, OMR::jProfilingRecompLoopTest);883_opts[OMR::jProfilingValue] =884new (comp->allocator()) TR::OptimizationManager(self(), TR_JProfilingValue::create, OMR::jProfilingValue);885_opts[OMR::staticFinalFieldFolding] =886new (comp->allocator()) TR::OptimizationManager(self(), TR_StaticFinalFieldFolding::create, OMR::staticFinalFieldFolding);887_opts[OMR::handleRecompilationOps] =888new (comp->allocator()) TR::OptimizationManager(self(), TR_HandleRecompilationOps::create, OMR::handleRecompilationOps);889_opts[OMR::hotFieldMarking] =890new (comp->allocator()) TR::OptimizationManager(self(), TR_HotFieldMarking::create, OMR::hotFieldMarking);891_opts[OMR::vectorAPIExpansion] =892new (comp->allocator()) TR::OptimizationManager(self(), TR_VectorAPIExpansion::create, OMR::vectorAPIExpansion);893// NOTE: Please add new J9 optimizations here!894895// initialize additional J9 optimization groups896897_opts[OMR::loopAliasRefinerGroup] =898new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::loopAliasRefinerGroup, loopAliasRefinerOpts);899_opts[OMR::cheapObjectAllocationGroup] =900new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::cheapObjectAllocationGroup, cheapObjectAllocationOpts);901_opts[OMR::expensiveObjectAllocationGroup] =902new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::expensiveObjectAllocationGroup, expensiveObjectAllocationOpts);903_opts[OMR::eachEscapeAnalysisPassGroup] =904new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::eachEscapeAnalysisPassGroup, eachEscapeAnalysisPassOpts);905_opts[OMR::cheapGlobalValuePropagationGroup] =906new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::cheapGlobalValuePropagationGroup, cheapGlobalValuePropagationOpts);907_opts[OMR::expensiveGlobalValuePropagationGroup] =908new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::expensiveGlobalValuePropagationGroup, expensiveGlobalValuePropagationOpts);909_opts[OMR::earlyGlobalGroup] =910new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::earlyGlobalGroup, J9EarlyGlobalOpts);911_opts[OMR::earlyLocalGroup] =912new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::earlyLocalGroup, J9EarlyLocalOpts);913_opts[OMR::isolatedStoreGroup] =914new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::isolatedStoreGroup, isolatedStoreOpts);915_opts[OMR::cheapTacticalGlobalRegisterAllocatorGroup] =916new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::cheapTacticalGlobalRegisterAllocatorGroup, cheapTacticalGlobalRegisterAllocatorOpts);917_opts[OMR::sequentialStoreSimplificationGroup] =918new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::sequentialStoreSimplificationGroup, sequentialStoreSimplificationOpts);919_opts[OMR::signExtendLoadsGroup] =920new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::signExtendLoadsGroup, signExtendLoadsOpts);921_opts[OMR::loopSpecializerGroup] =922new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::loopSpecializerGroup, loopSpecializerOpts);923_opts[OMR::profilingGroup] =924new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::profilingGroup, profilingOpts);925_opts[OMR::sequentialLoadAndStoreColdGroup] =926new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::sequentialLoadAndStoreColdGroup, sequentialLoadAndStoreColdOpts);927_opts[OMR::sequentialLoadAndStoreWarmGroup] =928new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::sequentialLoadAndStoreWarmGroup, sequentialLoadAndStoreWarmOpts);929930_opts[OMR::noOptStrategy] =931new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::noOptStrategy, noOptStrategyOpts);932_opts[OMR::coldStrategy] =933new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::coldStrategy, coldStrategyOpts);934_opts[OMR::warmStrategy] =935new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::warmStrategy, warmStrategyOpts);936_opts[OMR::hotStrategy] =937new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::hotStrategy, hotStrategyOpts);938_opts[OMR::veryHotStrategy] =939new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::veryHotStrategy, veryHotStrategyOpts);940_opts[OMR::scorchingStrategy] =941new (comp->allocator()) TR::OptimizationManager(self(), NULL, OMR::scorchingStrategy, scorchingStrategyOpts);942943// NOTE: Please add new J9 optimization groups here!944945// turn requested on for optimizations/groups946self()->setRequestOptimization(OMR::eachExpensiveGlobalValuePropagationGroup, true);947948self()->setRequestOptimization(OMR::cheapTacticalGlobalRegisterAllocatorGroup, true);949self()->setRequestOptimization(OMR::tacticalGlobalRegisterAllocatorGroup, true);950951self()->setRequestOptimization(OMR::tacticalGlobalRegisterAllocator, true);952953if (shouldEnableSEL(comp))954self()->setRequestOptimization(OMR::signExtendLoadsGroup, true);955if (comp->getOption(TR_EnableSequentialLoadStoreWarm))956self()->setRequestOptimization(OMR::sequentialLoadAndStoreWarmGroup, true);957if (comp->getOption(TR_EnableSequentialLoadStoreCold))958self()->setRequestOptimization(OMR::sequentialLoadAndStoreColdGroup, true);959}960961inline962TR::Optimizer *J9::Optimizer::self()963{964return (static_cast<TR::Optimizer *>(this));965}966967OMR_InlinerPolicy *J9::Optimizer::getInlinerPolicy()968{969return new (comp()->allocator()) TR_J9InlinerPolicy(comp());970}971972973OMR_InlinerUtil *J9::Optimizer::getInlinerUtil()974{975return new (comp()->allocator()) TR_J9InlinerUtil(comp());976}977978bool979J9::Optimizer::switchToProfiling(uint32_t f, uint32_t c)980{981TR::Recompilation *recomp = comp()->getRecompilationInfo();982if (!recomp) return false;983if (!recomp->shouldBeCompiledAgain()) return false; // do not profile if do not intend to compile again984if (!recomp->switchToProfiling(f, c)) return false;985setRequestOptimization(OMR::recompilationModifier, true);986setRequestOptimization(OMR::profileGenerator, true);987return true;988}989990991bool992J9::Optimizer::switchToProfiling()993{994return self()->switchToProfiling(DEFAULT_PROFILING_FREQUENCY, DEFAULT_PROFILING_COUNT);995}996997998const OptimizationStrategy *999J9::Optimizer::optimizationStrategy(TR::Compilation *c)1000{1001if (c->getOption(TR_MimicInterpreterFrameShape))1002{1003if (c->getJittedMethodSymbol()->sharesStackSlots(c))1004return fsdStrategies[0]; //0 is fsdStrategyOptsForMethodsWithSlotSharing1005else1006return fsdStrategies[1]; // 1 is fsdStrategyOptsForMethodsWithoutSlotSharing1007}10081009TR_Hotness strategy = c->getMethodHotness();1010if (strategy == warm && !c->getOption(TR_DisableCheapWarmOpts))1011{1012return cheapWarmStrategyOpts;1013}1014else1015{1016return j9CompilationStrategies[strategy];1017}1018}101910201021ValueNumberInfoBuildType1022J9::Optimizer::valueNumberInfoBuildType()1023{1024return PrePartitionVN;1025}102610271028