Path: blob/master/runtime/compiler/codegen/CodeGenRA.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#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.2728#pragma csect(CODE,"TRJ9CGRABase#C")29#pragma csect(STATIC,"TRJ9CGRABase#S")30#pragma csect(TEST,"TRJ9CGRABase#T")31#endif3233#include "codegen/J9CodeGenerator.hpp"3435#include <limits.h>36#include <stdint.h>37#include <stdlib.h>38#include <algorithm>39#include "codegen/BackingStore.hpp"40#include "codegen/CodeGenerator.hpp"41#include "codegen/CodeGenerator_inlines.hpp"42#include "env/FrontEnd.hpp"43#include "codegen/GCStackAtlas.hpp"44#include "codegen/Instruction.hpp"45#include "codegen/Linkage.hpp"46#include "codegen/Linkage_inlines.hpp"47#include "codegen/LinkageConventionsEnum.hpp"48#include "codegen/LiveReference.hpp"49#include "codegen/LiveRegister.hpp"50#include "codegen/Register.hpp"51#include "codegen/RegisterConstants.hpp"52#include "codegen/TreeEvaluator.hpp"53#include "compile/Compilation.hpp"54#include "control/Options.hpp"55#include "control/Options_inlines.hpp"56#include "env/CompilerEnv.hpp"57#include "env/IO.hpp"58#include "env/ObjectModel.hpp"59#include "env/StackMemoryRegion.hpp"60#include "env/TRMemory.hpp"61#include "il/AliasSetInterface.hpp"62#include "il/AutomaticSymbol.hpp"63#include "il/Block.hpp"64#include "il/DataTypes.hpp"65#include "il/ILOpCodes.hpp"66#include "il/ILOps.hpp"67#include "il/MethodSymbol.hpp"68#include "il/Node.hpp"69#include "il/Node_inlines.hpp"70#include "il/ParameterSymbol.hpp"71#include "il/ResolvedMethodSymbol.hpp"72#include "il/Symbol.hpp"73#include "il/SymbolReference.hpp"74#include "il/TreeTop.hpp"75#include "il/TreeTop_inlines.hpp"76#include "infra/Array.hpp"77#include "infra/Assert.hpp"78#include "infra/BitVector.hpp"79#include "infra/Cfg.hpp"80#include "infra/Flags.hpp"81#include "infra/Link.hpp"82#include "infra/List.hpp"83#include "infra/TRCfgEdge.hpp"84#include "infra/TRCfgNode.hpp"85#include "optimizer/Optimizations.hpp"86#include "optimizer/RegisterCandidate.hpp"87#include "optimizer/Structure.hpp"88#include "ras/Debug.hpp"8990TR::AutomaticSymbol *91J9::CodeGenerator::allocateVariableSizeSymbol(int32_t size)92{93TR::AutomaticSymbol *sym = TR::AutomaticSymbol::createVariableSized(self()->trHeapMemory(), size);94self()->comp()->getMethodSymbol()->addVariableSizeSymbol(sym);95if (self()->getDebug())96self()->getDebug()->newVariableSizeSymbol(sym);97return sym;98}99100TR::SymbolReference *101J9::CodeGenerator::allocateVariableSizeSymRef(int32_t byteLength)102{103if (self()->traceBCDCodeGen())104traceMsg(self()->comp(),"\tallocateVariableSizeSymbolReference: length = %d\n",byteLength);105TR::SymbolReference *symRef = self()->getFreeVariableSizeSymRef(byteLength);106TR::AutomaticSymbol *sym = NULL;107if (symRef == NULL)108{109sym = self()->allocateVariableSizeSymbol(byteLength);110symRef = new (self()->trHeapMemory()) TR::SymbolReference(self()->comp()->getSymRefTab(), sym);111symRef->setIsTempVariableSizeSymRef();112if (self()->traceBCDCodeGen())113traceMsg(self()->comp(),"\t\tno available symRef allocate symRef #%d : %s (%p) of length = %d\n",symRef->getReferenceNumber(),self()->getDebug()->getName(sym),sym,byteLength);114_variableSizeSymRefAllocList.push_front(symRef);115}116else117{118sym = symRef->getSymbol()->getVariableSizeSymbol();119if (self()->traceBCDCodeGen())120traceMsg(self()->comp(),"\t\treuse available symRef #%d : %s (%p) with length = %d\n",symRef->getReferenceNumber(),self()->getDebug()->getName(sym),sym,byteLength);121}122sym->setActiveSize(byteLength);123sym->setReferenceCount(0);124if (self()->traceBCDCodeGen())125traceMsg(self()->comp(),"\treturning symRef #%d (%s) : activeSize set to %d (length = %d)\n",126symRef->getReferenceNumber(),self()->getDebug()->getName(sym),sym->getActiveSize(),sym->getSize());127return symRef;128}129130void131J9::CodeGenerator::freeAllVariableSizeSymRefs()132{133if (!_variableSizeSymRefPendingFreeList.empty())134{135auto it = _variableSizeSymRefPendingFreeList.begin();136while (it != _variableSizeSymRefPendingFreeList.end())137{138TR_ASSERT((*it)->getSymbol()->isVariableSizeSymbol(),"symRef #%d must contain a variable size symbol\n",(*it)->getReferenceNumber());139self()->freeVariableSizeSymRef(*(it++), true); // freeAddressTakenSymbols=true140}141}142}143144void145J9::CodeGenerator::freeVariableSizeSymRef(146TR::SymbolReference *symRef,147bool freeAddressTakenSymbol)148{149TR_ASSERT(symRef->getSymbol()->isVariableSizeSymbol(),"symRef #%d must contain a variable size symbol\n",symRef->getReferenceNumber());150auto *sym = symRef->getSymbol()->getVariableSizeSymbol();151if (self()->traceBCDCodeGen())152traceMsg(self()->comp(),"\tfreeVariableSizeSymbol: #%d (%s)%s%s%s\n",153symRef->getReferenceNumber(),self()->getDebug()->getName(sym),154sym->isSingleUse()?", isSingleUse=true":"",freeAddressTakenSymbol?", freeAddressTakenSymbol=true":"",sym->isAddressTaken()?", symAddrTaken=true":"");155TR_ASSERT(!(std::find(_variableSizeSymRefFreeList.begin(), _variableSizeSymRefFreeList.end(), symRef) != _variableSizeSymRefFreeList.end())156,"symRef #%d has already been freed\n",symRef->getReferenceNumber());157if (sym->isAddressTaken() && !freeAddressTakenSymbol)158{159if (self()->traceBCDCodeGen())160traceMsg(self()->comp(),"\t\tsym->isAddressTaken()=true and freeAddressTakenSymbol=false so do not free sym #%d (%s %p)\n",symRef->getReferenceNumber(),self()->getDebug()->getName(sym),sym);161return;162}163else164{165if (self()->traceBCDCodeGen())166traceMsg(self()->comp(),"\t\tfree symRef #%d (%s %p)\n",symRef->getReferenceNumber(),self()->getDebug()->getName(sym),sym);167sym->setIsSingleUse(false);168sym->setIsAddressTaken(false);169sym->setNodeToFreeAfter(NULL);170sym->setReferenceCount(0);171symRef->resetHasTemporaryNegativeOffset();172bool found = (std::find(_variableSizeSymRefPendingFreeList.begin(), _variableSizeSymRefPendingFreeList.end(), symRef) != _variableSizeSymRefPendingFreeList.end());173if (!_variableSizeSymRefPendingFreeList.empty() && found)174_variableSizeSymRefPendingFreeList.remove(symRef);175_variableSizeSymRefFreeList.push_front(symRef);176}177}178179void180J9::CodeGenerator::pendingFreeVariableSizeSymRef(TR::SymbolReference *symRef)181{182TR_ASSERT(symRef->getSymbol()->isVariableSizeSymbol(),"symRef #%d must contain a variable size symbol\n",symRef->getReferenceNumber());183bool found = (std::find(_variableSizeSymRefPendingFreeList.begin(), _variableSizeSymRefPendingFreeList.end(), symRef) != _variableSizeSymRefPendingFreeList.end());184if (self()->traceBCDCodeGen())185traceMsg(self()->comp(),"\tpendingFreeVariableSizeSymRef: #%d (%s) %s to pending free list\n",186symRef->getReferenceNumber(),self()->getDebug()->getName(symRef->getSymbol()),found ?"do not add (already present)":"add");187if (!found)188_variableSizeSymRefPendingFreeList.push_front(symRef);189}190191192TR::SymbolReference *193J9::CodeGenerator::getFreeVariableSizeSymRef(int32_t byteLength)194{195TR::SymbolReference *biggestSymRef;196if(_variableSizeSymRefFreeList.empty())197return NULL;198else199biggestSymRef = _variableSizeSymRefFreeList.front();200201TR::SymbolReference *previous = NULL;202TR::SymbolReference *savedPrevious = NULL;203TR::SymbolReference *biggestPrevious = NULL;204if (self()->traceBCDCodeGen())205traceMsg(self()->comp(),"\tgetFreeVariableSizeSymRef of length %d\n",byteLength);206207if (biggestSymRef)208{209if (self()->traceBCDCodeGen())210traceMsg(self()->comp(),"\t\tset initial biggestSymRef to #%d (%s) with length %d\n",211biggestSymRef->getReferenceNumber(),self()->getDebug()->getName(biggestSymRef->getSymbol()),biggestSymRef->getSymbol()->getSize());212auto i = _variableSizeSymRefFreeList.begin();213while (i != _variableSizeSymRefFreeList.end())214{215previous = savedPrevious;216if (self()->traceBCDCodeGen())217traceMsg(self()->comp(),"\t\texamine free symRef #%d (%s) with length %d\n",(*i)->getReferenceNumber(),self()->getDebug()->getName((*i)->getSymbol()),(*i)->getSymbol()->getSize());218if ((*i)->getSymbol()->getSize() >= byteLength)219{220if (self()->traceBCDCodeGen())221{222traceMsg(self()->comp(),"\t\tfound big enough free symRef #%d (%s) with length >= req length of %d\n",(*i)->getReferenceNumber(),self()->getDebug()->getName((*i)->getSymbol()),byteLength);223traceMsg(self()->comp(),"\t\tremove free symRef #%d (%s) from list, previous is %p\n",(*i)->getReferenceNumber(),self()->getDebug()->getName((*i)->getSymbol()),previous ? previous:(void *)0);224}225TR::SymbolReference *symRef = *i;226if(previous == NULL)227_variableSizeSymRefFreeList.pop_front();228else229{230auto foundIt = std::find(_variableSizeSymRefFreeList.begin(), _variableSizeSymRefFreeList.end(), previous);231if(foundIt != _variableSizeSymRefFreeList.end())232{233++foundIt;234_variableSizeSymRefFreeList.erase(foundIt); // pops head if previous==NULL235}236}237TR_ASSERT(!(std::find(_variableSizeSymRefFreeList.begin(), _variableSizeSymRefFreeList.end(), (*i)) != _variableSizeSymRefFreeList.end())238,"shouldn't find symRef #%d as it was just removed\n",(*i)->getReferenceNumber());239return symRef;240}241else if ((*i)->getSymbol()->getSize() > biggestSymRef->getSymbol()->getSize())242{243if (self()->traceBCDCodeGen())244traceMsg(self()->comp(),"\t\tupdate biggest symRef seen to #%d (%s) with length %d\n",(*i)->getReferenceNumber(),self()->getDebug()->getName((*i)->getSymbol()),byteLength);245biggestPrevious = previous;246biggestSymRef = *i;247}248savedPrevious = *i;249++i;250}251if (self()->traceBCDCodeGen())252traceMsg(self()->comp(),"\t\tincrease biggestSymRef #%d (%s) size from %d -> %d\n",253biggestSymRef->getReferenceNumber(),self()->getDebug()->getName(biggestSymRef->getSymbol()),biggestSymRef->getSymbol()->getSize(),byteLength);254biggestSymRef->getSymbol()->setSize(byteLength);255}256257if (self()->traceBCDCodeGen() && biggestSymRef)258traceMsg(self()->comp(),"\t\tremove free symRef #%d (%s) from list, previous is %p\n",biggestSymRef->getReferenceNumber(),self()->getDebug()->getName(biggestSymRef->getSymbol()),previous ? previous:(void *)9999);259if(biggestPrevious == NULL)260_variableSizeSymRefFreeList.pop_front();261else262{263auto foundIt = std::find(_variableSizeSymRefFreeList.begin(), _variableSizeSymRefFreeList.end(), biggestPrevious);264if(foundIt != _variableSizeSymRefFreeList.end())265{266auto nextIt = ++foundIt;267_variableSizeSymRefFreeList.remove(*nextIt); // pops head if previous==NULL268}269}270TR_ASSERT(!biggestSymRef || !(std::find(_variableSizeSymRefFreeList.begin(), _variableSizeSymRefFreeList.end(), biggestSymRef) != _variableSizeSymRefFreeList.end())271,"shouldn't find biggestSymRef #%d as it was just removed\n",biggestSymRef->getReferenceNumber());272return biggestSymRef;273}274275void276J9::CodeGenerator::checkForUnfreedVariableSizeSymRefs()277{278bool foundUnfreedSlot = false;279for (auto i = _variableSizeSymRefAllocList.begin(); i != _variableSizeSymRefAllocList.end(); ++i)280{281bool found = (std::find(_variableSizeSymRefFreeList.begin(), _variableSizeSymRefFreeList.end(), (*i)) != _variableSizeSymRefFreeList.end());282if (!found)283{284TR_ASSERT((*i)->getSymbol()->isVariableSizeSymbol(),"symRef #%d must contain a variable size symbol\n",(*i)->getReferenceNumber());285if (self()->traceBCDCodeGen())286traceMsg(self()->comp(),"Variable size symRef #%d (%s) has not been freed (symbol refCount is %d)\n",287(*i)->getReferenceNumber(),self()->getDebug()->getName((*i)->getSymbol()),(*i)->getSymbol()->getVariableSizeSymbol()->getReferenceCount());288foundUnfreedSlot = true;289}290}291TR_ASSERT(!foundUnfreedSlot,"Unfreed variable size symRefs found at end of method\n");292}293294295