Path: blob/master/runtime/compiler/optimizer/J9EstimateCodeSize.hpp
6000 views
/*******************************************************************************1* Copyright (c) 2000, 2021 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#ifndef J9ESTIMATECS_INCL23#define J9ESTIMATECS_INCL2425#include "il/Block.hpp"26#include "ilgen/J9ByteCodeIterator.hpp"27#include "compile/Compilation.hpp"28#include "optimizer/Inliner.hpp"29#include "optimizer/J9Inliner.hpp"30#include "il/Node.hpp"31#include "infra/Stack.hpp"32#include "il/TreeTop.hpp"33#include "control/Recompilation.hpp"34#include "control/RecompilationInfo.hpp"35#include "env/TRMemory.hpp"36#include "optimizer/EstimateCodeSize.hpp"3738class TR_ResolvedMethod;39class NeedsPeekingHeuristic;4041class TR_J9EstimateCodeSize : public TR_EstimateCodeSize42{43public:4445TR_J9EstimateCodeSize() : TR_EstimateCodeSize(), _optimisticSize(0), _lastCallBlockFrequency(-1) { }4647int32_t getOptimisticSize() { return _optimisticSize; }4849/** \brief50* The inliner weight adjustment factor used for java/lang/String* compression related methods.51*/52static const float STRING_COMPRESSION_ADJUSTMENT_FACTOR;5354/** \brief55* The inliner weight adjustment factor used for `java/lang/reflect/Method.invoke`.56*/57static const float METHOD_INVOKE_ADJUSTMENT_FACTOR;5859/** \brief60* Adjusts the estimated \p value by a \p factor for string compression related methods.61* \param method62* The method we are trying to make an estimate adjustment for.63* \param value64* The estimated value we are trying to adjust.65* \param factor66* The factor multiplier to adjust the value by.67* \return68* true if the \p value was adjusted by the \p factor for the specific \p method; false otherwise.69* \note70* If an adjustment is performed the formula used to calculate the new value is:71* \code72* value *= factor;73* \endcode74*/75static bool adjustEstimateForStringCompression(TR_ResolvedMethod* method, int32_t& value, float factor);7677/** \brief78* Adjusts the estimated \p value by a \p factor for `java/lang/reflect/Method.invoke`.79* \param method80* The method we are trying to make an estimate adjustment for.81* \param value82* The estimated value we are trying to adjust.83* \param factor84* The factor multiplier to adjust the value by.85* \return86* true if the \p value was adjusted by the \p factor for the specific \p method; false otherwise.87* \note88* If an adjustment is performed the formula used to calculate the new value is:89* \code90* value *= factor;91* \endcode92*/93static bool adjustEstimateForMethodInvoke(TR_ResolvedMethod* method, int32_t& value, float factor);9495static TR::Block *getBlock(TR::Compilation *comp, TR::Block * * blocks, TR_ResolvedMethod *feMethod, int32_t i, TR::CFG & cfg);9697static void setupNode(TR::Node *node, uint32_t bcIndex, TR_ResolvedMethod *feMethod, TR::Compilation *comp);98static void setupLastTreeTop(TR::Block *currentBlock, TR_J9ByteCode bc,99uint32_t bcIndex, TR::Block *destinationBlock, TR_ResolvedMethod *feMethod,100TR::Compilation *comp);101102protected:103bool estimateCodeSize(TR_CallTarget *, TR_CallStack * , bool recurseDown = true);104105/** \brief106* Generates a CFG for the calltarget->_calleeMethod.107*108* \param calltarget109* The calltarget which we wish to generate a CFG for.110*111* \param cfgRegion112* The memory region where the cfg is going to be stored113*114* \param bci115* The bytecode iterator. Must be instantiated in the following way:116* \code117* bci(0, static_cast<TR_ResolvedJ9Method *> (calltarget->_calleeMethod), ...)118* \endcode119*120* \param nph121* Pointer to NeedsPeekingHeuristic.122*123* \param blocks124* Array of block pointers. Size of array must be equal to the maximum125* bytecode index in calltarget->_calleeMethod126*127* \param flags128* Array of flags8_t. Size of array must be equal to maximum bytecode129* index in calltarget->_calleeMethod130*131* \return132* Reference to cfg133*/134TR::CFG &processBytecodeAndGenerateCFG(TR_CallTarget *calltarget, TR::Region &cfgRegion, TR_J9ByteCodeIterator &bci, NeedsPeekingHeuristic &nph, TR::Block** blocks, flags8_t * flags);135bool realEstimateCodeSize(TR_CallTarget *calltarget, TR_CallStack *prevCallStack, bool recurseDown, TR::Region &cfgRegion);136137bool reduceDAAWrapperCodeSize(TR_CallTarget* target);138139// Partial Inlining Logic140bool isInExceptionRange(TR_ResolvedMethod * feMethod, int32_t bcIndex);141bool trimBlocksForPartialInlining (TR_CallTarget *calltarget, TR_Queue<TR::Block> *);142bool isPartialInliningCandidate(TR_CallTarget *calltarget, TR_Queue<TR::Block> *);143bool graphSearch( TR::CFG *, TR::Block *, TR::Block::partialFlags, TR::Block::partialFlags);144int32_t labelGraph( TR::CFG *, TR_Queue<TR::Block> *, TR_Queue<TR::Block> *);145void processGraph(TR_CallTarget * );146147148int32_t _lastCallBlockFrequency;149int32_t _optimisticSize; // size if we assume we are doing a partial inline150};151152#define NUM_PREV_BC 5153class TR_prevArgs154{155public:156TR_prevArgs() { for (int32_t i = 0 ; i < NUM_PREV_BC ; i++ ) { _prevBC[i] = J9BCunknown ; } }157158void printIndexes(TR::Compilation *comp)159{160for (int32_t i = 0 ; i < NUM_PREV_BC ; i++)161{162if(comp->getDebug())163traceMsg(comp,"_prevBC[%d] = %s\n" ,i,((TR_J9VM*)(comp->fej9()))->getByteCodeName(_prevBC[i]));164}165}166167void updateArg(TR_J9ByteCode bc )168{169for(int32_t i=NUM_PREV_BC-2 ; i>=0 ; i-- )170{171_prevBC[i+1] = _prevBC[i];172}173_prevBC[0] = bc;174}175176bool isArgAtIndexReceiverObject (int32_t index)177{178if ( index < NUM_PREV_BC && _prevBC[index] == J9BCaload0)179{180return true;181}182else183return false;184}185186int32_t getNumPrevConstArgs(int32_t numparms)187{188int32_t count=0;189190for(int32_t i=0 ; i < NUM_PREV_BC && i < numparms ; i++)191{192switch (_prevBC[i])193{194case J9BCaconstnull:195case J9BCiconstm1:196case J9BCiconst0:197case J9BCiconst1:198case J9BCiconst2:199case J9BCiconst3:200case J9BCiconst4:201case J9BCiconst5:202case J9BClconst0:203case J9BClconst1:204case J9BCfconst0:205case J9BCfconst1:206case J9BCfconst2:207case J9BCdconst0:208case J9BCdconst1:209case J9BCldc: case J9BCldcw: case J9BCldc2lw: case J9BCldc2dw:210case J9BCbipush: case J9BCsipush:211count++;212break;213default:214break;215}216}217return count;218}219220221protected:222TR_J9ByteCode _prevBC[NUM_PREV_BC];223};224225226227228#endif229230231