Path: blob/master/runtime/compiler/optimizer/EstimateCodeSize.cpp
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#include "env/StackMemoryRegion.hpp"23#include "optimizer/EstimateCodeSize.hpp"2425#include "env/FrontEnd.hpp"26#include "compile/Compilation.hpp"27#include "il/ResolvedMethodSymbol.hpp"28#include "infra/Assert.hpp"29#include "optimizer/CallInfo.hpp"30#include "ras/LogTracer.hpp"31#include "env/VMJ9.h"32#include "runtime/J9Profiler.hpp"3334TR_EstimateCodeSize *35TR_EstimateCodeSize::get(TR_InlinerBase * inliner, TR_InlinerTracer *tracer, int32_t sizeThreshold)36{37TR::Compilation *comp = inliner->comp();38TR_EstimateCodeSize *estimator = comp->fej9()->getCodeEstimator(comp);3940estimator->_inliner = inliner;41estimator->_tracer = tracer;4243estimator->_isLeaf = false;44estimator->_foundThrow = false;45estimator->_hasExceptionHandlers = false;46estimator->_throwCount = 0;47estimator->_mayHaveVirtualCallProfileInfo = false;4849TR_CatchBlockProfileInfo * catchInfo = TR_CatchBlockProfileInfo::get(comp);50estimator->_aggressivelyInlineThrows = catchInfo && catchInfo->getCatchCounter()51>= TR_CatchBlockProfileInfo::EDOThreshold;5253estimator->_recursionDepth = 0;54estimator->_recursedTooDeep = false;5556estimator->_sizeThreshold = sizeThreshold;57estimator->_realSize = 0;58estimator->_error = ECS_NORMAL;5960estimator->_numOfEstimatedCalls = 0;61estimator->_hasNonColdCalls = true;6263estimator->_totalBCSize = 0;6465return estimator;66}6768void69TR_EstimateCodeSize::release(TR_EstimateCodeSize *estimator)70{71TR::Compilation *comp = estimator->_inliner->comp();72comp->fej9()->releaseCodeEstimator(comp, estimator);73}7475bool76TR_EstimateCodeSize::calculateCodeSize(TR_CallTarget *calltarget, TR_CallStack *callStack, bool recurseDown)77{78TR_InlinerDelimiter delimiter(tracer(), "calculateCodeSize");7980_isLeaf = true;81_foundThrow = false;82_hasExceptionHandlers = false;83_throwCount = 0;8485_mayHaveVirtualCallProfileInfo = (TR_ValueProfileInfoManager::get(comp()) != NULL);8687bool retval = false;8889{90TR::StackMemoryRegion stackMemoryRegion(*comp()->trMemory());91retval = estimateCodeSize(calltarget, callStack, recurseDown);92} // Stack memory region scope9394if (_inliner->getPolicy()->tryToInline(calltarget, callStack, true))95{96heuristicTrace(tracer(),"tryToInline pattern matched. Assuming zero size for %s\n", tracer()->traceSignature(calltarget->_calleeSymbol));97_realSize = 0;98retval = true;99}100101if (!retval && _inliner->forceInline(calltarget))102retval = true;103104return retval;105}106107const char *108TR_EstimateCodeSize::getError()109{110switch(_error)111{112case ECS_NORMAL: return "ECS_NORMAL";113case ECS_RECURSION_DEPTH_THRESHOLD_EXCEEDED: return "ECS_RECURSION_DEPTH_THRESHOLD_EXCEEDED";114case ECS_OPTIMISTIC_SIZE_THRESHOLD_EXCEEDED: return "ECS_OPTIMISTIC_SIZE_THRESHOLD_EXCEEDED";115case ECS_VISITED_COUNT_THRESHOLD_EXCEEDED: return "ECS_VISITED_COUNT_THRESHOLD_EXCEEDED";116case ECS_REAL_SIZE_THRESHOLD_EXCEEDED: return "ECS_REAL_SIZE_THRESHOLD_EXCEEDED";117case ECS_ARGUMENTS_INCOMPATIBLE: return "ECS_ARGUMENTS_INCOMPATIBLE";118case ECS_CALLSITES_CREATION_FAILED: return "ECS_CALLSITES_CREATION_FAILED";119default: return "ECS_UNKNOWN";120}121}122123bool124TR_EstimateCodeSize::isInlineable(TR_CallStack * prevCallStack, TR_CallSite *callsite)125{126TR_ASSERT(callsite, "Estimate Code Size: callsite is null!");127128heuristicTrace(tracer(),"Depth %d: Created Call Site %p for call found at bc index %d. Signature %s Looking for call targets.",129_recursionDepth, callsite, callsite->_byteCodeIndex, tracer()->traceSignature(callsite));130131if (_inliner->getPolicy()->supressInliningRecognizedInitialCallee(callsite, _inliner->comp()))132{133heuristicTrace(tracer(),"Skip looking for call targets because supressInliningRecognizedInitialCallee is true for this call site %p\n", callsite);134return false;135}136137callsite->findCallSiteTarget(prevCallStack, _inliner);138_inliner->applyPolicyToTargets(prevCallStack, callsite);139140141if (callsite->numTargets() <= 0)142{143if (tracer()->debugLevel())144tracer()->dumpCallSite(145callsite,146"Call About to be Dumped returned false from findInlineTargets in partialCodeSize estimation");147148heuristicTrace(tracer(),"Depth %d: Did not find any targets to be inlined in callsite %p bc index %d. Signature %s",149_recursionDepth, callsite, callsite->_byteCodeIndex, tracer()->traceSignature(callsite));150151_isLeaf = false;152return false;153}154155if (tracer()->debugLevel())156tracer()->dumpCallSite(157callsite,158"Call About to be Dumped returns true from findInlineTargets in partialCodeSize estimation");159160heuristicTrace(tracer(),"Depth %d: Found %d targets to inline for callsite %p bc index %d. Signature %s",161_recursionDepth, callsite->numTargets(),callsite, callsite->_byteCodeIndex, tracer()->traceSignature(callsite));162163return true;164}165166bool167TR_EstimateCodeSize::returnCleanup(EcsCleanupErrorStates errorState)168{169_error = errorState;170if (_mayHaveVirtualCallProfileInfo)171_inliner->comp()->decInlineDepth(true);172if (errorState > 0)173return false;174else175return true;176}177178179