/******************************************************************************* * Copyright IBM Corp. and others 2019 * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this * distribution and is available at https://www.eclipse.org/legal/epl-2.0 * or the Apache License, Version 2.0 which accompanies this distribution * and is available at https://www.apache.org/licenses/LICENSE-2.0. * * This Source Code may also be made available under the following Secondary * Licenses when the conditions for such availability set forth in the * Eclipse Public License, v. 2.0 are satisfied: GNU General Public License, * version 2 with the GNU Classpath Exception [1] and GNU General Public * License, version 2 with the OpenJDK Assembly Exception [2]. * * [1] https://www.gnu.org/software/classpath/license.html * [2] https://openjdk.org/legal/assembly-exception.html * * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 *******************************************************************************/ #include "optimizer/PreEscapeAnalysis.hpp" #include "il/AutomaticSymbol.hpp" #include "il/Block.hpp" #include "il/Node.hpp" #include "il/Node_inlines.hpp" #include "il/ResolvedMethodSymbol.hpp" #include "il/SymbolReference.hpp" #include "il/TreeTop.hpp" #include "optimizer/EscapeAnalysisTools.hpp" #include "optimizer/Optimizer.hpp" #include "optimizer/OptimizationManager.hpp" int32_t TR_PreEscapeAnalysis::perform() { if (!optimizer()->isEnabled(OMR::escapeAnalysis)) { if (comp()->trace(OMR::escapeAnalysis)) { traceMsg(comp(), "EscapeAnalysis is disabled - skipping Pre-EscapeAnalysis\n"); } return 0; } if (comp()->getOSRMode() != TR::voluntaryOSR || comp()->getOption(TR_DisableOSRLiveRangeAnalysis)) { if (comp()->trace(OMR::escapeAnalysis)) { traceMsg(comp(), "Special handling of OSR points is not possible outside of voluntary OSR or if OSR Liveness is not available - nothing to do\n"); } return 0; } if (optimizer()->getOptimization(OMR::escapeAnalysis)->numPassesCompleted() > 0) { if (comp()->trace(OMR::escapeAnalysis)) { traceMsg(comp(), "EA has self-enabled, setup not required on subsequent passes - skipping preEscapeAnalysis\n"); } return 0; } // Gather map of sym refs that were known during OSR Liveness analysis to // the sym refs that occur in the current trees // static char *disableEADefiningMap = feGetEnv("TR_DisableEAEscapeHelperDefiningMap"); TR::StackMemoryRegion stackMemoryRegion(*comp()->trMemory()); if (!disableEADefiningMap && comp()->getOSRCompilationData()) { comp()->getOSRCompilationData()->buildDefiningMap(comp()->trMemory()->currentStackRegion()); } TR_EscapeAnalysisTools tools(comp()); for (TR::Block *block = comp()->getStartBlock(); block != NULL; block = block->getNextBlock()) { if (!block->isOSRInduceBlock()) continue; for (TR::TreeTop *itr = block->getEntry(), *end = block->getExit(); itr != end; itr = itr->getNextTreeTop()) { if (itr->getNode()->getNumChildren() == 1 && itr->getNode()->getFirstChild()->getOpCodeValue() == TR::call && itr->getNode()->getFirstChild()->getSymbolReference()->isOSRInductionHelper()) { //_loads->clear(); if (optimizer()->getUseDefInfo() != NULL) { optimizer()->setUseDefInfo(NULL); } if (optimizer()->getValueNumberInfo()) { optimizer()->setValueNumberInfo(NULL); } tools.insertFakeEscapeForOSR(block, itr->getNode()->getFirstChild()); break; } } } if (!disableEADefiningMap && comp()->getOSRCompilationData()) { // Must discard references to the DefiningMaps when finished with them comp()->getOSRCompilationData()->clearDefiningMap(); } if (comp()->trace(OMR::escapeAnalysis)) { comp()->dumpMethodTrees("Trees after Pre-Escape Analysis"); } return 1; } const char * TR_PreEscapeAnalysis::optDetailString() const throw() { return "O^O PRE ESCAPE ANALYSIS: "; }