Path: blob/master/runtime/compiler/optimizer/EstimateCodeSize.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 ESTIMATECS_INCL23#define ESTIMATECS_INCL2425#include <stddef.h>26#include <stdint.h>27#include "env/TRMemory.hpp"28#include "infra/Flags.hpp"29#include "optimizer/Inliner.hpp"3031class TR_CallStack;32namespace TR { class Compilation; }33struct TR_CallSite;34struct TR_CallTarget;3536#define MAX_ECS_RECURSION_DEPTH 303738enum EcsCleanupErrorStates {39ECS_NORMAL = 0,40ECS_RECURSION_DEPTH_THRESHOLD_EXCEEDED,41ECS_OPTIMISTIC_SIZE_THRESHOLD_EXCEEDED,42ECS_VISITED_COUNT_THRESHOLD_EXCEEDED,43ECS_REAL_SIZE_THRESHOLD_EXCEEDED,44ECS_ARGUMENTS_INCOMPATIBLE,45ECS_CALLSITES_CREATION_FAILED46};4748class TR_EstimateCodeSize49{50public:5152void * operator new (size_t size, TR::Allocator allocator) { return allocator.allocate(size); }53void operator delete (void *, TR::Allocator allocator) {}5455// {56// TR_EstimateCodeSize::raiiWrapper lexicalScopeObject(....);57// TR_EstimateCodeSize *ecs = lexicalScopeObject->getCodeEstimator();58// ... do whatever you gotta do59// } // estimator will be automatically freed by lexicalScopeObject regardless of how scope is exited60class raiiWrapper61{62public:63raiiWrapper(TR_InlinerBase *inliner, TR_InlinerTracer *tracer, int32_t sizeThreshold)64{65_estimator = TR_EstimateCodeSize::get(inliner, tracer, sizeThreshold);66}6768~raiiWrapper()69{70TR_EstimateCodeSize::release(_estimator);71}7273TR_EstimateCodeSize *getCodeEstimator()74{75return _estimator;76}7778private:79TR_EstimateCodeSize *_estimator;80};8182TR_EstimateCodeSize() { }8384static TR_EstimateCodeSize *get(TR_InlinerBase *inliner, TR_InlinerTracer *tracer, int32_t sizeThreshold);85static void release(TR_EstimateCodeSize *estimator);8687bool calculateCodeSize(TR_CallTarget *, TR_CallStack *, bool recurseDown = true);8889int32_t getSize() { return _realSize; }90virtual int32_t getOptimisticSize() { return 0; } // override in subclasses that support partial inlining91const char *getError();92int32_t getSizeThreshold() { return _sizeThreshold; }93bool aggressivelyInlineThrows() { return _aggressivelyInlineThrows; }94bool recursedTooDeep() { return _recursedTooDeep; }95bool isLeaf() { return _isLeaf; }9697int32_t getNumOfEstimatedCalls() { return _numOfEstimatedCalls; }98/*99* \brief100* tell whether this callsite has inlineable target101*/102bool isInlineable(TR_CallStack *, TR_CallSite *callsite);103104TR::Compilation *comp() { return _inliner->comp(); }105TR_InlinerTracer *tracer() { return _tracer; }106TR_InlinerBase* getInliner() { return _inliner; }107108protected:109110virtual bool estimateCodeSize(TR_CallTarget *, TR_CallStack * , bool recurseDown = true) = 0;111112113/*114* \brief common tasks requiring completion before returning from estimation115*116* \param errorState117* an unique state used to identify where estimate code size bailed out118*/119bool returnCleanup(EcsCleanupErrorStates errorState);120121/* Fields */122123bool _isLeaf;124bool _foundThrow;125bool _hasExceptionHandlers;126bool _mayHaveVirtualCallProfileInfo;127bool _aggressivelyInlineThrows;128int32_t _throwCount;129130int32_t _recursionDepth;131bool _recursedTooDeep;132133int32_t _sizeThreshold;134int32_t _realSize; // size once we know if we're doing a partial inline or not135EcsCleanupErrorStates _error;136137int32_t _totalBCSize; // Pure accumulation of the bytecode size. Used by HW-based inlining.138139TR_InlinerBase * _inliner;140TR_InlinerTracer *_tracer;141142int32_t _numOfEstimatedCalls;143bool _hasNonColdCalls;144};145146#endif147148149