From 4e028e2a43b1b28042e6049da83d8630fc1ed888 Mon Sep 17 00:00:00 2001 From: Daryl Maier Date: Sat, 19 Sep 2020 14:20:22 -0400 Subject: [PATCH] Introduce CodeGenerator constructors and initialize functions * Create a new CodeGenerator constructor that takes a TR::Compilation parameter. The constructor hierarchy only contains member initialization lists. A mirrored hierarchy was created to permit downstream projets to adapt to the hierarchy changes. The default constructors will eventually be deleted and replaced with private empty stubs. This constructor will eventually be invoked via a static factory function. * Create a CodeGenerator::initialize() method to be called after object construction to initialize the CodeGenerator object. The initialize() functions take the place of the original constructor bodies and must be invoked in the same order. Signed-off-by: Daryl Maier --- compiler/aarch64/codegen/OMRCodeGenerator.cpp | 115 ++++++++ compiler/aarch64/codegen/OMRCodeGenerator.hpp | 10 +- compiler/arm/codegen/OMRCodeGenerator.cpp | 172 ++++++++++++ compiler/arm/codegen/OMRCodeGenerator.hpp | 14 +- compiler/codegen/OMRCodeGenerator.cpp | 127 +++++++++ compiler/codegen/OMRCodeGenerator.hpp | 19 +- compiler/p/codegen/OMRCodeGenerator.cpp | 253 ++++++++++++++++++ compiler/p/codegen/OMRCodeGenerator.hpp | 19 +- compiler/riscv/codegen/OMRCodeGenerator.cpp | 109 +++++++- compiler/riscv/codegen/OMRCodeGenerator.hpp | 10 +- compiler/x/amd64/codegen/OMRCodeGenerator.cpp | 88 ++++++ compiler/x/amd64/codegen/OMRCodeGenerator.hpp | 11 +- compiler/x/codegen/OMRCodeGenerator.cpp | 28 ++ compiler/x/codegen/OMRCodeGenerator.hpp | 6 +- compiler/x/i386/codegen/OMRCodeGenerator.cpp | 77 ++++++ compiler/x/i386/codegen/OMRCodeGenerator.hpp | 10 +- compiler/z/codegen/OMRCodeGenerator.cpp | 224 ++++++++++++++++ compiler/z/codegen/OMRCodeGenerator.hpp | 9 + 18 files changed, 1272 insertions(+), 29 deletions(-) diff --git a/compiler/aarch64/codegen/OMRCodeGenerator.cpp b/compiler/aarch64/codegen/OMRCodeGenerator.cpp index d7e4fbe609f..8f486b6fd69 100644 --- a/compiler/aarch64/codegen/OMRCodeGenerator.cpp +++ b/compiler/aarch64/codegen/OMRCodeGenerator.cpp @@ -41,6 +41,121 @@ #include "il/Node_inlines.hpp" #include "il/StaticSymbol.hpp" + +OMR::ARM64::CodeGenerator::CodeGenerator(TR::Compilation *comp) : + OMR::CodeGenerator(comp), + _dataSnippetList(getTypedAllocator(comp->allocator())), + _outOfLineCodeSectionList(getTypedAllocator(comp->allocator())), + _firstTimeLiveOOLRegisterList(NULL) + { + } + +void +OMR::ARM64::CodeGenerator::initialize() + { + self()->OMR::CodeGenerator::initialize(); + + TR::CodeGenerator *cg = self(); + TR::Compilation *comp = self()->comp(); + + // Initialize Linkage for Code Generator + cg->initializeLinkage(); + + _unlatchedRegisterList = + (TR::RealRegister**)cg->trMemory()->allocateHeapMemory(sizeof(TR::RealRegister*)*(TR::RealRegister::NumRegisters + 1)); + + _unlatchedRegisterList[0] = 0; // mark that list is empty + + _linkageProperties = &cg->getLinkage()->getProperties(); + + cg->setStackPointerRegister(cg->machine()->getRealRegister(_linkageProperties->getStackPointerRegister())); + cg->setMethodMetaDataRegister(cg->machine()->getRealRegister(_linkageProperties->getMethodMetaDataRegister())); + + // Tactical GRA settings + // + cg->setGlobalRegisterTable(_linkageProperties->getRegisterAllocationOrder()); + _numGPR = _linkageProperties->getNumAllocatableIntegerRegisters(); + _numFPR = _linkageProperties->getNumAllocatableFloatRegisters(); + cg->setLastGlobalGPR(_numGPR - 1); + cg->setLastGlobalFPR(_numGPR + _numFPR - 1); + + cg->getLinkage()->initARM64RealRegisterLinkage(); + cg->setSupportsGlRegDeps(); + cg->setSupportsGlRegDepOnFirstBlock(); + + cg->addSupportedLiveRegisterKind(TR_GPR); + cg->addSupportedLiveRegisterKind(TR_FPR); + cg->setLiveRegisters(new (cg->trHeapMemory()) TR_LiveRegisters(comp), TR_GPR); + cg->setLiveRegisters(new (cg->trHeapMemory()) TR_LiveRegisters(comp), TR_FPR); + + cg->setSupportsVirtualGuardNOPing(); + + cg->setSupportsRecompilation(); + + cg->setSupportsSelect(); + + _numberBytesReadInaccessible = 0; + _numberBytesWriteInaccessible = 0; + + if (TR::Compiler->vm.hasResumableTrapHandler(comp)) + cg->setHasResumableTrapHandler(); + + if (!comp->getOption(TR_DisableRegisterPressureSimulation)) + { + for (int32_t i = 0; i < TR_numSpillKinds; i++) + _globalRegisterBitVectors[i].init(cg->getNumberOfGlobalRegisters(), cg->trMemory()); + + for (TR_GlobalRegisterNumber grn=0; grn < cg->getNumberOfGlobalRegisters(); grn++) + { + TR::RealRegister::RegNum reg = (TR::RealRegister::RegNum)cg->getGlobalRegister(grn); + if (cg->getFirstGlobalGPR() <= grn && grn <= cg->getLastGlobalGPR()) + _globalRegisterBitVectors[ TR_gprSpill ].set(grn); + else if (cg->getFirstGlobalFPR() <= grn && grn <= cg->getLastGlobalFPR()) + _globalRegisterBitVectors[ TR_fprSpill ].set(grn); + + if (!cg->getProperties().getPreserved(reg)) + _globalRegisterBitVectors[ TR_volatileSpill ].set(grn); + if (cg->getProperties().getIntegerArgument(reg) || cg->getProperties().getFloatArgument(reg)) + _globalRegisterBitVectors[ TR_linkageSpill ].set(grn); + } + } + + // Calculate inverse of getGlobalRegister function + // + TR_GlobalRegisterNumber grn; + int i; + + TR_GlobalRegisterNumber globalRegNumbers[TR::RealRegister::NumRegisters]; + for (i = 0; i < cg->getNumberOfGlobalGPRs(); i++) + { + grn = cg->getFirstGlobalGPR() + i; + globalRegNumbers[cg->getGlobalRegister(grn)] = grn; + } + for (i = 0; i < cg->getNumberOfGlobalFPRs(); i++) + { + grn = cg->getFirstGlobalFPR() + i; + globalRegNumbers[cg->getGlobalRegister(grn)] = grn; + } + + // Initialize linkage reg arrays + TR::ARM64LinkageProperties linkageProperties = cg->getProperties(); + for (i = 0; i < linkageProperties.getNumIntArgRegs(); i++) + _gprLinkageGlobalRegisterNumbers[i] = globalRegNumbers[linkageProperties.getIntegerArgumentRegister(i)]; + for (i = 0; i < linkageProperties.getNumFloatArgRegs(); i++) + _fprLinkageGlobalRegisterNumbers[i] = globalRegNumbers[linkageProperties.getFloatArgumentRegister(i)]; + + if (comp->getOption(TR_TraceRA)) + { + cg->setGPRegisterIterator(new (cg->trHeapMemory()) TR::RegisterIterator(cg->machine(), TR::RealRegister::FirstGPR, TR::RealRegister::LastGPR)); + cg->setFPRegisterIterator(new (cg->trHeapMemory()) TR::RegisterIterator(cg->machine(), TR::RealRegister::FirstFPR, TR::RealRegister::LastFPR)); + } + + cg->getLinkage()->setParameterLinkageRegisterIndex(comp->getJittedMethodSymbol()); + + if (comp->target().isSMP()) + cg->setEnforceStoreOrder(); + } + OMR::ARM64::CodeGenerator::CodeGenerator() : OMR::CodeGenerator(), _dataSnippetList(getTypedAllocator(TR::comp()->allocator())), diff --git a/compiler/aarch64/codegen/OMRCodeGenerator.hpp b/compiler/aarch64/codegen/OMRCodeGenerator.hpp index edfa5134095..e4b51dde3ec 100644 --- a/compiler/aarch64/codegen/OMRCodeGenerator.hpp +++ b/compiler/aarch64/codegen/OMRCodeGenerator.hpp @@ -150,10 +150,16 @@ namespace ARM64 class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator { - public: +protected: + + CodeGenerator(TR::Compilation *comp); + +public: CodeGenerator(); + void initialize(); + /** * @brief AArch64 hook to begin instruction selection */ @@ -474,7 +480,7 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator /** * @brief Returns bit mask for real register * @param[in] reg: real register number - * + * * @return bit mask for real register */ static uint32_t registerBitMask(int32_t reg); diff --git a/compiler/arm/codegen/OMRCodeGenerator.cpp b/compiler/arm/codegen/OMRCodeGenerator.cpp index e30d7d3e309..cdad02c1cb5 100644 --- a/compiler/arm/codegen/OMRCodeGenerator.cpp +++ b/compiler/arm/codegen/OMRCodeGenerator.cpp @@ -73,6 +73,178 @@ TR::Linkage *OMR::ARM::CodeGenerator::createLinkage(TR_LinkageConventions lc) return linkage; } +OMR::ARM::CodeGenerator::CodeGenerator(TR::Compilation *comp) + : OMR::CodeGenerator(comp), + _frameRegister(NULL), + _constantData(NULL), + _outOfLineCodeSectionList(comp->trMemory()), + _internalControlFlowNestingDepth(0), + _internalControlFlowSafeNestingDepth(0) + { + } + +void +OMR::ARM::CodeGenerator::initialize() + { + self()->OMR::CodeGenerator::initialize(); + + TR::CodeGenerator *cg = self(); + TR::Compilation *comp = self()->comp(); + + // Initialize Linkage for Code Generator + cg->initializeLinkage(); + + _unlatchedRegisterList = + (TR::RealRegister**)cg->trMemory()->allocateHeapMemory(sizeof(TR::RealRegister*)*(TR::RealRegister::NumRegisters + 1)); + + _unlatchedRegisterList[0] = 0; // mark that list is empty + + _linkageProperties = &cg->getLinkage()->getProperties(); + _linkageProperties->setEndianness(comp->target().cpu.isBigEndian()); + + if (!comp->getOption(TR_FullSpeedDebug)) + cg->setSupportsDirectJNICalls(); + cg->setSupportsVirtualGuardNOPing(); + + if(comp->target().isLinux()) + { + // only hardhat linux-arm builds have the required gcc soft libraries + // that allow the vm to be compiled with -msoft-float. + // With -msoft-float any floating point return value is placed in gr0 for single precision and + // gr0 and gr1 for double precision. This is where the jit expects the result following a directToJNI call. + // The floating point return value on non-hardhat linux-arm builds is through the coprocessor register f0. + // Therefore the HasHardFloatReturn flag must be set to force generation of instructions to move the result + // from f0 to gr0/gr1 following a directToJNI dispatch. + + #if !defined(HARDHAT) && !defined(__VFP_FP__) // gcc does not support VFP with -mfloat-abi=hard yet + cg->setHasHardFloatReturn(); + #endif + } + + if (!debug("hasFramePointer")) + cg->setFrameRegister(cg->machine()->getRealRegister(_linkageProperties->getStackPointerRegister())); + else + cg->setFrameRegister(cg->machine()->getRealRegister(_linkageProperties->getFramePointerRegister())); + + cg->setMethodMetaDataRegister(cg->machine()->getRealRegister(_linkageProperties->getMethodMetaDataRegister())); + + // Tactical GRA settings +#if 1 // PPC enables below, but seem no longer used? + cg->setGlobalGPRPartitionLimit(TR::Machine::getGlobalGPRPartitionLimit()); + cg->setGlobalFPRPartitionLimit(TR::Machine::getGlobalFPRPartitionLimit()); +#endif + cg->setGlobalRegisterTable(TR::Machine::getGlobalRegisterTable()); + _numGPR = _linkageProperties->getNumAllocatableIntegerRegisters(); + cg->setLastGlobalGPR(TR::Machine::getLastGlobalGPRRegisterNumber()); + cg->setLast8BitGlobalGPR(TR::Machine::getLast8BitGlobalGPRRegisterNumber()); + cg->setLastGlobalFPR(TR::Machine::getLastGlobalFPRRegisterNumber()); + _numFPR = _linkageProperties->getNumAllocatableFloatRegisters(); + + // TODO: Disable FP-GRA since current GRA does not work well with ARM linkage (where Float register usage is limited). + cg->setDisableFpGRA(); + + cg->setSupportsRecompilation(); + + cg->setSupportsGlRegDeps(); + cg->setSupportsGlRegDepOnFirstBlock(); + cg->setPerformsChecksExplicitly(); + cg->setConsiderAllAutosAsTacticalGlobalRegisterCandidates(); + cg->setSupportsScaledIndexAddressing(); + cg->setSupportsAlignedAccessOnly(); + cg->setSupportsPrimitiveArrayCopy(); + cg->setSupportsReferenceArrayCopy(); + cg->setSupportsLoweringConstIDiv(); + cg->setSupportsNewInstanceImplOpt(); + +#ifdef J9_PROJECT_SPECIFIC + cg->setAheadOfTimeCompile(new (cg->trHeapMemory()) TR::AheadOfTimeCompile(cg)); +#endif + cg->getLinkage()->initARMRealRegisterLinkage(); + //To enable this, we must change OMR::ARM::Linkage::saveArguments to support GRA registers + //cg->getLinkage()->setParameterLinkageRegisterIndex(comp->getJittedMethodSymbol()); + + _numberBytesReadInaccessible = 0; + _numberBytesWriteInaccessible = 0; + + cg->setSupportsJavaFloatSemantics(); + cg->setSupportsInliningOfTypeCoersionMethods(); + + if (comp->target().isLinux()) + { + // On AIX and Linux, we are very far away from address + // wrapping-around. + _maxObjectSizeGuaranteedNotToOverflow = 0x10000000; + cg->setSupportsDivCheck(); + if (!comp->getOption(TR_DisableTraps)) + cg->setHasResumableTrapHandler(); + } + else + { + TR_ASSERT(0, "unknown target"); + } + + // Tactical GRA + if (!comp->getOption(TR_DisableRegisterPressureSimulation)) + { + for (int32_t i = 0; i < TR_numSpillKinds; i++) + _globalRegisterBitVectors[i].init(cg->getNumberOfGlobalRegisters(), cg->trMemory()); + + for (TR_GlobalRegisterNumber grn=0; grn < cg->getNumberOfGlobalRegisters(); grn++) + { + TR::RealRegister::RegNum reg = (TR::RealRegister::RegNum)cg->getGlobalRegister(grn); + if (cg->getFirstGlobalGPR() <= grn && grn <= cg->getLastGlobalGPR()) + _globalRegisterBitVectors[ TR_gprSpill ].set(grn); + else if (cg->getFirstGlobalFPR() <= grn && grn <= cg->getLastGlobalFPR()) + _globalRegisterBitVectors[ TR_fprSpill ].set(grn); + + if (!cg->getProperties().getPreserved(reg)) + _globalRegisterBitVectors[ TR_volatileSpill ].set(grn); + if (cg->getProperties().getIntegerArgument(reg) || cg->getProperties().getFloatArgument(reg)) + _globalRegisterBitVectors[ TR_linkageSpill ].set(grn); + } + + } + + // Calculate inverse of getGlobalRegister function + // + TR_GlobalRegisterNumber grn; + int i; + + TR_GlobalRegisterNumber globalRegNumbers[TR::RealRegister::NumRegisters]; + for (i=0; i < cg->getNumberOfGlobalGPRs(); i++) + { + grn = cg->getFirstGlobalGPR() + i; + globalRegNumbers[cg->getGlobalRegister(grn)] = grn; + } + for (i=0; i < cg->getNumberOfGlobalFPRs(); i++) + { + grn = cg->getFirstGlobalFPR() + i; + globalRegNumbers[cg->getGlobalRegister(grn)] = grn; + } + + // Initialize linkage reg arrays + TR::ARMLinkageProperties linkageProperties = cg->getProperties(); + for (i=0; i < linkageProperties.getNumIntArgRegs(); i++) + _gprLinkageGlobalRegisterNumbers[i] = globalRegNumbers[linkageProperties.getIntegerArgumentRegister(i)]; + for (i=0; i < linkageProperties.getNumFloatArgRegs(); i++) + _fprLinkageGlobalRegisterNumbers[i] = globalRegNumbers[linkageProperties.getFloatArgumentRegister(i)]; + + if (comp->getOption(TR_TraceRA)) + { + cg->setGPRegisterIterator(new (cg->trHeapMemory()) TR::RegisterIterator(cg->machine(), TR::RealRegister::FirstGPR, TR::RealRegister::LastGPR)); + cg->setFPRegisterIterator(new (cg->trHeapMemory()) TR::RegisterIterator(cg->machine(), TR::RealRegister::FirstFPR, TR::RealRegister::LastFPR)); + } + + if (!comp->compileRelocatableCode()) + { + cg->setSupportsProfiledInlining(); + } + + // Disable optimizations for max min by default on arm + comp->setOption(TR_DisableMaxMinOptimization); + } + + OMR::ARM::CodeGenerator::CodeGenerator() : OMR::CodeGenerator(), _frameRegister(NULL), diff --git a/compiler/arm/codegen/OMRCodeGenerator.hpp b/compiler/arm/codegen/OMRCodeGenerator.hpp index 63c32ad2bba..4989d934a72 100644 --- a/compiler/arm/codegen/OMRCodeGenerator.hpp +++ b/compiler/arm/codegen/OMRCodeGenerator.hpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corp. and others + * Copyright (c) 2000, 2020 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -112,10 +112,16 @@ class CodeGenerator; class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator { - public: +protected: + + CodeGenerator(TR::Compilation *comp); + +public: + + CodeGenerator(); + + void initialize(); - CodeGenerator(); /* @@ */ - CodeGenerator(TR::Compilation * comp); TR::Linkage *createLinkage(TR_LinkageConventions lc); void beginInstructionSelection(); diff --git a/compiler/codegen/OMRCodeGenerator.cpp b/compiler/codegen/OMRCodeGenerator.cpp index 2242ba3b63c..841671fd71e 100644 --- a/compiler/codegen/OMRCodeGenerator.cpp +++ b/compiler/codegen/OMRCodeGenerator.cpp @@ -148,6 +148,133 @@ TR::Instruction * OMR::CodeGenerator::generateNop(TR::Node * node, TR::Instruction *instruction, TR_NOPKind nopKind) { TR_ASSERT(0, "shouldn't get here"); return NULL;} + +OMR::CodeGenerator::CodeGenerator(TR::Compilation *comp) : + _compilation(comp), + _trMemory(comp->trMemory()), + _liveLocals(0), + _currentEvaluationTreeTop(0), + _currentEvaluationBlock(0), + _prePrologueSize(0), + _implicitExceptionPoint(0), + _localsThatAreStored(NULL), + _numLocalsWhenStoreAnalysisWasDone(-1), + _ialoadUnneeded(comp->trMemory()), + _symRefTab(comp->getSymRefTab()), + _vmThreadRegister(NULL), + _stackAtlas(NULL), + _methodStackMap(NULL), + _binaryBufferStart(NULL), + _binaryBufferCursor(NULL), + _largestOutgoingArgSize(0), + _estimatedCodeLength(0), + _estimatedSnippetStart(0), + _accumulatedInstructionLengthError(0), + _registerSaveDescription(0), + _extendedToInt64GlobalRegisters(comp->allocator()), + _liveButMaybeUnreferencedLocals(NULL), + _assignedGlobalRegisters(NULL), + _aheadOfTimeCompile(NULL), + _globalRegisterTable(NULL), + _currentGRABlockLiveOutSet(NULL), + _localsIG(NULL), + _lastGlobalGPR(0), + _firstGlobalFPR(0), + _lastGlobalFPR(0), + _firstOverlappedGlobalFPR(0), + _lastOverlappedGlobalFPR(0), + _last8BitGlobalGPR(0), + _globalGPRPartitionLimit(0), + _globalFPRPartitionLimit(0), + _firstInstruction(NULL), + _appendInstruction(NULL), + _firstGlobalVRF(-1), + _lastGlobalVRF(-1), + _firstOverlappedGlobalVRF(-1), + _lastOverlappedGlobalVRF(-1), + _overlapOffsetBetweenFPRandVRFgrns(0), + _supportedLiveRegisterKinds(0), + _blocksWithCalls(NULL), + _codeCache(0), + _committedToCodeCache(false), + _codeCacheSwitched(false), + _blockRegisterPressureCache(NULL), + _simulatedNodeStates(NULL), + _availableSpillTemps(getTypedAllocator(comp->allocator())), + _counterBlocks(getTypedAllocator(comp->allocator())), + _liveReferenceList(getTypedAllocator(comp->allocator())), + _snippetList(getTypedAllocator(comp->allocator())), + _registerArray(comp->trMemory()), + _spill4FreeList(getTypedAllocator(comp->allocator())), + _spill8FreeList(getTypedAllocator(comp->allocator())), + _spill16FreeList(getTypedAllocator(comp->allocator())), + _internalPointerSpillFreeList(getTypedAllocator(comp->allocator())), + _spilledRegisterList(NULL), + _referencedRegistersList(NULL), + _variableSizeSymRefPendingFreeList(getTypedAllocator(comp->allocator())), + _variableSizeSymRefFreeList(getTypedAllocator(comp->allocator())), + _variableSizeSymRefAllocList(getTypedAllocator(comp->allocator())), + _accumulatorNodeUsage(0), + _collectedSpillList(getTypedAllocator(comp->allocator())), + _allSpillList(getTypedAllocator(comp->allocator())), + _relocationList(getTypedAllocator(comp->allocator())), + _externalRelocationList(getTypedAllocator(comp->allocator())), + _staticRelocationList(comp->allocator()), + _preJitMethodEntrySize(0), + _jitMethodEntryPaddingSize(0), + _lastInstructionBeforeCurrentEvaluationTreeTop(NULL), + _unlatchedRegisterList(NULL), + _indentation(2), + _currentBlock(NULL), + _realVMThreadRegister(NULL), + _internalControlFlowNestingDepth(0), + _internalControlFlowSafeNestingDepth(0), + _stackOfArtificiallyInflatedNodes(comp->trMemory(), 16), + _stackOfMemoryReferencesCreatedDuringEvaluation(comp->trMemory(), 16), + randomizer(comp), + _outOfLineColdPathNestedDepth(0), + _codeGenPhase(self()), + _symbolDataTypeMap(comp->allocator()), + _lmmdFailed(false) + { + } + + +void +OMR::CodeGenerator::initialize() + { + TR::CodeGenerator *cg = self(); + TR::Compilation *comp = self()->comp(); + + _machine = new (cg->trHeapMemory()) TR::Machine(cg); + + _disableInternalPointers = comp->getOption(TR_MimicInterpreterFrameShape) || + comp->getOptions()->realTimeGC() || + comp->getOption(TR_DisableInternalPointers); + + uintptr_t maxSize = TR::Compiler->vm.getOverflowSafeAllocSize(comp); + int32_t i; + + for (i = 0; i < NumRegisterKinds; ++i) + { + _liveRegisters[i] = NULL; + _liveRealRegisters[i] = 0; + } + + for (i = 0 ; i < TR_NumLinkages; ++i) + _linkages[i] = NULL; + + _maxObjectSizeGuaranteedNotToOverflow = (maxSize > UINT_MAX) ? UINT_MAX : maxSize; + + if (comp->getDebug()) + { + comp->getDebug()->resetDebugData(); + } + + cg->setIsLeafMethod(); + } + + OMR::CodeGenerator::CodeGenerator() : _compilation(TR::comp()), _trMemory(_compilation->trMemory()), diff --git a/compiler/codegen/OMRCodeGenerator.hpp b/compiler/codegen/OMRCodeGenerator.hpp index 98301b97787..92c0a0a4d3c 100644 --- a/compiler/codegen/OMRCodeGenerator.hpp +++ b/compiler/codegen/OMRCodeGenerator.hpp @@ -246,7 +246,8 @@ namespace OMR class OMR_EXTENSIBLE CodeGenerator { - private: + +private: TR::Compilation *_compilation; TR_Memory *_trMemory; @@ -262,16 +263,28 @@ class OMR_EXTENSIBLE CodeGenerator TR::Instruction *_implicitExceptionPoint; bool areMergeableGuards(TR::Instruction *earlierGuard, TR::Instruction *laterGuard); - protected: +protected: TR_BitVector *_localsThatAreStored; int32_t _numLocalsWhenStoreAnalysisWasDone; List > _ialoadUnneeded; - public: + /** + * @brief Constructor + * + * @param[in] comp \c TR::Compilation object + */ + CodeGenerator(TR::Compilation *comp); + +public: TR_ALLOC(TR_Memory::CodeGenerator) + /** + * @brief Initialize a \c TR::CodeGenerator object + */ + void initialize(); + inline TR::CodeGenerator *self(); TR_StackMemory trStackMemory(); diff --git a/compiler/p/codegen/OMRCodeGenerator.cpp b/compiler/p/codegen/OMRCodeGenerator.cpp index deb2ffc4090..a75561393a1 100644 --- a/compiler/p/codegen/OMRCodeGenerator.cpp +++ b/compiler/p/codegen/OMRCodeGenerator.cpp @@ -107,6 +107,259 @@ #include #endif + +OMR::Power::CodeGenerator::CodeGenerator(TR::Compilation *comp) : + OMR::CodeGenerator(comp), + _stackPtrRegister(NULL), + _constantData(NULL), + _blockCallInfo(NULL), + _transientLongRegisters(comp->trMemory()), + conversionBuffer(NULL), + _outOfLineCodeSectionList(getTypedAllocator(comp->allocator())), + _startPCLabel(NULL) + { + } + + +void +OMR::Power::CodeGenerator::initialize() + { + self()->OMR::CodeGenerator::initialize(); + + TR::CodeGenerator *cg = self(); + TR::Compilation *comp = self()->comp(); + + // Initialize Linkage for Code Generator + cg->initializeLinkage(); + + _unlatchedRegisterList = + (TR::RealRegister**)cg->trMemory()->allocateHeapMemory(sizeof(TR::RealRegister*)*(TR::RealRegister::NumRegisters + 1)); + + _unlatchedRegisterList[0] = 0; // mark that list is empty + + _linkageProperties = &cg->getLinkage()->getProperties(); + + // Set up to collect items for later TOC mapping + if (comp->target().is64Bit()) + { + cg->setTrackStatics(new (cg->trHeapMemory()) TR_Array(cg->trMemory())); + cg->setTrackItems(new (cg->trHeapMemory()) TR_Array(cg->trMemory())); + } + else + { + cg->setTrackStatics(NULL); + cg->setTrackItems(NULL); + } + + cg->setStackPointerRegister(cg->machine()->getRealRegister(_linkageProperties->getNormalStackPointerRegister())); + cg->setMethodMetaDataRegister(cg->machine()->getRealRegister(_linkageProperties->getMethodMetaDataRegister())); + cg->setTOCBaseRegister(cg->machine()->getRealRegister(_linkageProperties->getTOCBaseRegister())); + cg->getLinkage()->initPPCRealRegisterLinkage(); + cg->getLinkage()->setParameterLinkageRegisterIndex(comp->getJittedMethodSymbol()); + cg->machine()->initREGAssociations(); + + // Tactical GRA settings. + // + cg->setGlobalGPRPartitionLimit(TR::Machine::getGlobalGPRPartitionLimit()); + cg->setGlobalFPRPartitionLimit(TR::Machine::getGlobalFPRPartitionLimit()); + cg->setGlobalRegisterTable(_linkageProperties->getRegisterAllocationOrder()); + _numGPR = _linkageProperties->getNumAllocatableIntegerRegisters(); + _firstGPR = 0; + _lastGPR = _numGPR - 1; + _firstParmGPR = _linkageProperties->getFirstAllocatableIntegerArgumentRegister(); + _lastVolatileGPR = _linkageProperties->getLastAllocatableIntegerVolatileRegister(); + _numFPR = _linkageProperties->getNumAllocatableFloatRegisters(); + _firstFPR = _numGPR; + _lastFPR = _firstFPR + _numFPR - 1; + _firstParmFPR = _linkageProperties->getFirstAllocatableFloatArgumentRegister(); + _lastVolatileFPR = _linkageProperties->getLastAllocatableFloatVolatileRegister(); + cg->setLastGlobalGPR(_lastGPR); + cg->setLast8BitGlobalGPR(_lastGPR); + cg->setLastGlobalFPR(_lastFPR); + + _numVRF = _linkageProperties->getNumAllocatableVectorRegisters(); + cg->setFirstGlobalVRF(_lastFPR + 1); + cg->setLastGlobalVRF(_lastFPR + _numVRF); + + cg->setSupportsGlRegDeps(); + cg->setSupportsGlRegDepOnFirstBlock(); + + cg->setSupportsRecompilation(); + + if (comp->target().is32Bit()) + cg->setUsesRegisterPairsForLongs(); + + cg->setPerformsChecksExplicitly(); + cg->setConsiderAllAutosAsTacticalGlobalRegisterCandidates(); + + cg->setEnableRefinedAliasSets(); + + static char * accessStaticsIndirectly = feGetEnv("TR_AccessStaticsIndirectly"); + if (accessStaticsIndirectly) + cg->setAccessStaticsIndirectly(true); + + if (!debug("noLiveRegisters")) + { + cg->addSupportedLiveRegisterKind(TR_GPR); + cg->addSupportedLiveRegisterKind(TR_FPR); + cg->addSupportedLiveRegisterKind(TR_CCR); + cg->addSupportedLiveRegisterKind(TR_VSX_SCALAR); + cg->addSupportedLiveRegisterKind(TR_VSX_VECTOR); + cg->addSupportedLiveRegisterKind(TR_VRF); + + cg->setLiveRegisters(new (cg->trHeapMemory()) TR_LiveRegisters(comp), TR_GPR); + cg->setLiveRegisters(new (cg->trHeapMemory()) TR_LiveRegisters(comp), TR_FPR); + cg->setLiveRegisters(new (cg->trHeapMemory()) TR_LiveRegisters(comp), TR_CCR); + cg->setLiveRegisters(new (cg->trHeapMemory()) TR_LiveRegisters(comp), TR_VRF); + cg->setLiveRegisters(new (cg->trHeapMemory()) TR_LiveRegisters(comp), TR_VSX_SCALAR); + cg->setLiveRegisters(new (cg->trHeapMemory()) TR_LiveRegisters(comp), TR_VSX_VECTOR); + } + + cg->setSupportsConstantOffsetInAddressing(); + cg->setSupportsVirtualGuardNOPing(); + cg->setSupportsPrimitiveArrayCopy(); + cg->setSupportsReferenceArrayCopy(); + cg->setSupportsSelect(); + cg->setSupportsByteswap(); + + // disabled for now + // + if (comp->getOption(TR_AggressiveOpts) && + !comp->getOption(TR_DisableArraySetOpts)) + { + cg->setSupportsArraySet(); + } + cg->setSupportsArrayCmp(); + + if (comp->target().cpu.supportsFeature(OMR_FEATURE_PPC_HAS_VSX)) + { + static bool disablePPCTRTO = (feGetEnv("TR_disablePPCTRTO") != NULL); + static bool disablePPCTRTO255 = (feGetEnv("TR_disablePPCTRTO255") != NULL); + static bool disablePPCTROT = (feGetEnv("TR_disablePPCTROT") != NULL); + static bool disablePPCTROTNoBreak = (feGetEnv("TR_disablePPCTROTNoBreak") != NULL); + + if (!disablePPCTRTO) + cg->setSupportsArrayTranslateTRTO(); +#ifndef __LITTLE_ENDIAN__ + else if (!disablePPCTRTO255) + setSupportsArrayTranslateTRTO255(); +#endif + + if (!disablePPCTROT) + cg->setSupportsArrayTranslateTROT(); + + if (!disablePPCTROTNoBreak) + cg->setSupportsArrayTranslateTROTNoBreak(); + } + + _numberBytesReadInaccessible = 0; + _numberBytesWriteInaccessible = 4096; + + // Poorly named. Not necessarily Java specific. + // + cg->setSupportsJavaFloatSemantics(); + + cg->setSupportsDivCheck(); + cg->setSupportsLoweringConstIDiv(); + if (comp->target().is64Bit()) + cg->setSupportsLoweringConstLDiv(); + cg->setSupportsLoweringConstLDivPower2(); + + static bool disableDCAS = (feGetEnv("TR_DisablePPCDCAS") != NULL); + + if (!disableDCAS && + comp->target().is64Bit() && + TR::Options::useCompressedPointers()) + { + cg->setSupportsDoubleWordCAS(); + cg->setSupportsDoubleWordSet(); + } + + if (cg->is64BitProcessor()) + cg->setSupportsInlinedAtomicLongVolatiles(); + + // Standard allows only offset multiple of 4 + // TODO: either improves the query to be size-based or gets the offset into a register + if (comp->target().is64Bit()) + cg->setSupportsAlignedAccessOnly(); + + // TODO: distinguishing among OOO and non-OOO implementations + if (comp->target().isSMP()) + cg->setEnforceStoreOrder(); + + if (!comp->getOption(TR_DisableTraps) && TR::Compiler->vm.hasResumableTrapHandler(comp)) + cg->setHasResumableTrapHandler(); + + /* + * TODO: TM is currently not compatible with read barriers. If read barriers are required, TM is disabled until the issue is fixed. + * TM is now disabled by default, due to various reasons (OS, hardware, etc), unless it is explicitly enabled. + */ + if (comp->target().cpu.supportsFeature(OMR_FEATURE_PPC_HTM) && comp->getOption(TR_EnableTM) && + !comp->getOption(TR_DisableTM) && TR::Compiler->om.readBarrierType() == gc_modron_readbar_none) + cg->setSupportsTM(); + + if (comp->target().cpu.supportsFeature(OMR_FEATURE_PPC_HAS_ALTIVEC) && comp->target().cpu.supportsFeature(OMR_FEATURE_PPC_HAS_VSX)) + cg->setSupportsAutoSIMD(); + + if (!comp->getOption(TR_DisableRegisterPressureSimulation)) + { + for (int32_t i = 0; i < TR_numSpillKinds; i++) + _globalRegisterBitVectors[i].init(cg->getNumberOfGlobalRegisters(), cg->trMemory()); + + for (TR_GlobalRegisterNumber grn=0; grn < cg->getNumberOfGlobalRegisters(); grn++) + { + TR::RealRegister::RegNum reg = (TR::RealRegister::RegNum)cg->getGlobalRegister(grn); + if (cg->getFirstGlobalGPR() <= grn && grn <= cg->getLastGlobalGPR()) + _globalRegisterBitVectors[ TR_gprSpill ].set(grn); + else if (cg->getFirstGlobalFPR() <= grn && grn <= cg->getLastGlobalFPR()) + _globalRegisterBitVectors[ TR_fprSpill ].set(grn); + + if (!cg->getProperties().getPreserved(reg)) + _globalRegisterBitVectors[ TR_volatileSpill ].set(grn); + if (cg->getProperties().getIntegerArgument(reg) || cg->getProperties().getFloatArgument(reg)) + _globalRegisterBitVectors[ TR_linkageSpill ].set(grn); + } + + } + + // Calculate inverse of getGlobalRegister function + // + TR_GlobalRegisterNumber grn; + int i; + + TR_GlobalRegisterNumber globalRegNumbers[TR::RealRegister::NumRegisters]; + for (i=0; i < cg->getNumberOfGlobalGPRs(); i++) + { + grn = cg->getFirstGlobalGPR() + i; + globalRegNumbers[cg->getGlobalRegister(grn)] = grn; + } + for (i=0; i < cg->getNumberOfGlobalFPRs(); i++) + { + grn = cg->getFirstGlobalFPR() + i; + globalRegNumbers[cg->getGlobalRegister(grn)] = grn; + } + + // Initialize linkage reg arrays + TR::PPCLinkageProperties linkageProperties = cg->getProperties(); + for (i=0; i < linkageProperties.getNumIntArgRegs(); i++) + _gprLinkageGlobalRegisterNumbers[i] = globalRegNumbers[linkageProperties.getIntegerArgumentRegister(i)]; + for (i=0; i < linkageProperties.getNumFloatArgRegs(); i++) + _fprLinkageGlobalRegisterNumbers[i] = globalRegNumbers[linkageProperties.getFloatArgumentRegister(i)]; + + if (comp->getOption(TR_TraceRA)) + { + cg->setGPRegisterIterator(new (cg->trHeapMemory()) TR::RegisterIterator(cg->machine(), TR::RealRegister::FirstGPR, TR::RealRegister::LastGPR)); + cg->setFPRegisterIterator(new (cg->trHeapMemory()) TR::RegisterIterator(cg->machine(), TR::RealRegister::FirstFPR, TR::RealRegister::LastFPR)); + } + + cg->setSupportsProfiledInlining(); + + TR_ResolvedMethod *method = comp->getJittedMethodSymbol()->getResolvedMethod(); + TR_ReturnInfo returnInfo = cg->getLinkage()->getReturnInfoFromReturnType(method->returnType()); + comp->setReturnInfo(returnInfo); + } + + OMR::Power::CodeGenerator::CodeGenerator() : OMR::CodeGenerator(), _stackPtrRegister(NULL), diff --git a/compiler/p/codegen/OMRCodeGenerator.hpp b/compiler/p/codegen/OMRCodeGenerator.hpp index a0d7725deb5..d0cb11aef37 100644 --- a/compiler/p/codegen/OMRCodeGenerator.hpp +++ b/compiler/p/codegen/OMRCodeGenerator.hpp @@ -172,7 +172,7 @@ class CodeGenerator; class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator { - public: +public: List * conversionBuffer; ListIterator * conversionBufferIt; @@ -180,8 +180,16 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator CodeGenerator(); +protected: + + CodeGenerator(TR::Compilation *comp); + +public: + TR::Linkage *createLinkage(TR_LinkageConventions lc); + void initialize(); + static bool supportsTransientPrefetch(); bool is64BitProcessor(); @@ -561,7 +569,6 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator DummyLastFlag }; - void initialize(); TR_BitVector *computeCallInfoBitVector(); @@ -619,15 +626,15 @@ class TR_PPCScratchRegisterManager : public TR_ScratchRegisterManager TR::Register *sourceReg, int32_t value, TR::CodeGenerator *cg); - + void mulConstant( TR::Node *, TR::Register *trgReg, TR::Register *sourceReg, int64_t value, TR::CodeGenerator *cg); - - + + TR::Register *addConstantToLong( TR::Node * node, TR::Register *srcReg, @@ -642,7 +649,7 @@ class TR_PPCScratchRegisterManager : public TR_ScratchRegisterManager int32_t valHigh, int32_t valLow, TR::CodeGenerator *cg); - + TR::Register *addConstantToInteger( TR::Node * node, TR::Register *srcReg, diff --git a/compiler/riscv/codegen/OMRCodeGenerator.cpp b/compiler/riscv/codegen/OMRCodeGenerator.cpp index 90c0b00ad8b..2280122336d 100644 --- a/compiler/riscv/codegen/OMRCodeGenerator.cpp +++ b/compiler/riscv/codegen/OMRCodeGenerator.cpp @@ -34,6 +34,101 @@ #include "il/Node.hpp" #include "il/Node_inlines.hpp" +OMR::RV::CodeGenerator::CodeGenerator(TR::Compilation *comp) : + OMR::CodeGenerator(comp), + _constantData(NULL), + _outOfLineCodeSectionList(getTypedAllocator(comp->allocator())) + { + } + +void +OMR::RV::CodeGenerator::initialize() + { + self()->OMR::CodeGenerator::initialize(); + + TR::CodeGenerator *cg = self(); + TR::Compilation *comp = self()->comp(); + + // Initialize Linkage for Code Generator + cg->initializeLinkage(); + + _unlatchedRegisterList = + (TR::RealRegister**)cg->trMemory()->allocateHeapMemory(sizeof(TR::RealRegister*)*(TR::RealRegister::NumRegisters + 1)); + + _unlatchedRegisterList[0] = 0; // mark that list is empty + + _linkageProperties = &cg->getLinkage()->getProperties(); + + cg->setStackPointerRegister(cg->machine()->getRealRegister(_linkageProperties->getStackPointerRegister())); + cg->setMethodMetaDataRegister(cg->machine()->getRealRegister(_linkageProperties->getMethodMetaDataRegister())); + + // Tactical GRA settings + // + cg->setGlobalRegisterTable(TR::Machine::getGlobalRegisterTable()); + _numGPR = _linkageProperties->getNumAllocatableIntegerRegisters(); + _numFPR = _linkageProperties->getNumAllocatableFloatRegisters(); + cg->setLastGlobalGPR(TR::Machine::getLastGlobalGPRRegisterNumber()); + cg->setLastGlobalFPR(TR::Machine::getLastGlobalFPRRegisterNumber()); + + cg->getLinkage()->initRVRealRegisterLinkage(); + + _numberBytesReadInaccessible = 0; + _numberBytesWriteInaccessible = 0; + + if (TR::Compiler->vm.hasResumableTrapHandler(comp)) + cg->setHasResumableTrapHandler(); + + if (!comp->getOption(TR_DisableRegisterPressureSimulation)) + { + for (int32_t i = 0; i < TR_numSpillKinds; i++) + _globalRegisterBitVectors[i].init(cg->getNumberOfGlobalRegisters(), cg->trMemory()); + + for (TR_GlobalRegisterNumber grn=0; grn < cg->getNumberOfGlobalRegisters(); grn++) + { + TR::RealRegister::RegNum reg = (TR::RealRegister::RegNum)cg->getGlobalRegister(grn); + if (cg->getFirstGlobalGPR() <= grn && grn <= cg->getLastGlobalGPR()) + _globalRegisterBitVectors[ TR_gprSpill ].set(grn); + else if (cg->getFirstGlobalFPR() <= grn && grn <= cg->getLastGlobalFPR()) + _globalRegisterBitVectors[ TR_fprSpill ].set(grn); + + if (!cg->getProperties().getPreserved(reg)) + _globalRegisterBitVectors[ TR_volatileSpill ].set(grn); + if (cg->getProperties().getIntegerArgument(reg) || cg->getProperties().getFloatArgument(reg)) + _globalRegisterBitVectors[ TR_linkageSpill ].set(grn); + } + } + + // Calculate inverse of getGlobalRegister function + // + TR_GlobalRegisterNumber grn; + int i; + + TR_GlobalRegisterNumber globalRegNumbers[TR::RealRegister::NumRegisters]; + for (i = 0; i < cg->getNumberOfGlobalGPRs(); i++) + { + grn = cg->getFirstGlobalGPR() + i; + globalRegNumbers[cg->getGlobalRegister(grn)] = grn; + } + for (i = 0; i < cg->getNumberOfGlobalFPRs(); i++) + { + grn = cg->getFirstGlobalFPR() + i; + globalRegNumbers[cg->getGlobalRegister(grn)] = grn; + } + + // Initialize linkage reg arrays + TR::RVLinkageProperties linkageProperties = cg->getProperties(); + for (i = 0; i < linkageProperties.getNumIntArgRegs(); i++) + _gprLinkageGlobalRegisterNumbers[i] = globalRegNumbers[linkageProperties.getIntegerArgumentRegister(i)]; + for (i = 0; i < linkageProperties.getNumFloatArgRegs(); i++) + _fprLinkageGlobalRegisterNumbers[i] = globalRegNumbers[linkageProperties.getFloatArgumentRegister(i)]; + + if (comp->getOption(TR_TraceRA)) + { + cg->setGPRegisterIterator(new (cg->trHeapMemory()) TR::RegisterIterator(cg->machine(), TR::RealRegister::FirstGPR, TR::RealRegister::LastGPR)); + cg->setFPRegisterIterator(new (cg->trHeapMemory()) TR::RegisterIterator(cg->machine(), TR::RealRegister::FirstFPR, TR::RealRegister::LastFPR)); + } + } + OMR::RV::CodeGenerator::CodeGenerator() : OMR::CodeGenerator(), _constantData(NULL), @@ -455,7 +550,7 @@ void OMR::RV::CodeGenerator::apply16BitLabelRelativeRelocation(int32_t *cursor, *cursor |= ENCODE_SBTYPE_IMM(distance); } -void OMR::RV::CodeGenerator::apply16BitLabelRelativeRelocation(int32_t *cursor, TR::LabelSymbol *label, int8_t d, bool isInstrOffset) +void OMR::RV::CodeGenerator::apply16BitLabelRelativeRelocation(int32_t *cursor, TR::LabelSymbol *label, int8_t d, bool isInstrOffset) { apply16BitLabelRelativeRelocation(cursor, label); } @@ -477,13 +572,13 @@ void OMR::RV::CodeGenerator::apply32BitLabelRelativeRelocation(int32_t *cursor, } int64_t OMR::RV::CodeGenerator::getLargestNegConstThatMustBeMaterialized() - { - TR_ASSERT(0, "Not Implemented on AArch64"); - return 0; + { + TR_ASSERT(0, "Not Implemented on AArch64"); + return 0; } int64_t OMR::RV::CodeGenerator::getSmallestPosConstThatMustBeMaterialized() - { - TR_ASSERT(0, "Not Implemented on AArch64"); - return 0; + { + TR_ASSERT(0, "Not Implemented on AArch64"); + return 0; } diff --git a/compiler/riscv/codegen/OMRCodeGenerator.hpp b/compiler/riscv/codegen/OMRCodeGenerator.hpp index d4240c7df24..0a5e0e77b47 100644 --- a/compiler/riscv/codegen/OMRCodeGenerator.hpp +++ b/compiler/riscv/codegen/OMRCodeGenerator.hpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2019 IBM Corp. and others + * Copyright (c) 2019, 2020 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -70,10 +70,16 @@ namespace RV class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator { - public: +protected: + + CodeGenerator(TR::Compilation *comp); + +public: CodeGenerator(); + initialize(); + /** * @brief AArch64 hook to begin instruction selection */ diff --git a/compiler/x/amd64/codegen/OMRCodeGenerator.cpp b/compiler/x/amd64/codegen/OMRCodeGenerator.cpp index 81d3ab08eaf..4d9f39e85ea 100644 --- a/compiler/x/amd64/codegen/OMRCodeGenerator.cpp +++ b/compiler/x/amd64/codegen/OMRCodeGenerator.cpp @@ -45,6 +45,94 @@ #include "infra/BitVector.hpp" #include "x/codegen/X86Ops.hpp" + +OMR::X86::AMD64::CodeGenerator::CodeGenerator(TR::Compilation *comp) : + OMR::X86::CodeGenerator(comp) + { + } + + +void OMR::X86::AMD64::CodeGenerator::initialize() + { + self()->OMR::X86::CodeGenerator::initialize(); + + TR::CodeGenerator *cg = self(); + TR::Compilation *comp = self()->comp(); + + if (comp->getOption(TR_DisableTraps)) + { + _numberBytesReadInaccessible = 0; + _numberBytesWriteInaccessible = 0; + } + else + { + _numberBytesReadInaccessible = 4096; + _numberBytesWriteInaccessible = 4096; + cg->setHasResumableTrapHandler(); + cg->setEnableImplicitDivideCheck(); + } + + cg->setSupportsDivCheck(); + + static char *c = feGetEnv("TR_disableAMD64ValueProfiling"); + if (c) + comp->setOption(TR_DisableValueProfiling); + + static char *accessStaticsIndirectly = feGetEnv("TR_AccessStaticsIndirectly"); + if (accessStaticsIndirectly) + cg->setAccessStaticsIndirectly(true); + + cg->setSupportsDoubleWordCAS(); + cg->setSupportsDoubleWordSet(); + + cg->setSupportsGlRegDepOnFirstBlock(); + cg->setConsiderAllAutosAsTacticalGlobalRegisterCandidates(); + + // Interpreter frame shape requires all autos to occupy an 8-byte slot on 64-bit. + // + if (comp->getOption(TR_MimicInterpreterFrameShape)) + cg->setMapAutosTo8ByteSlots(); + + // Common X86 initialization + // + cg->initializeX86(comp); + + cg->initLinkageToGlobalRegisterMap(); + + cg->setRealVMThreadRegister(cg->machine()->getRealRegister(TR::RealRegister::ebp)); + + // GRA-related initialization is done after calling initializeX86() so we can + // use such things as getNumberOfGlobal[FG]PRs(). + + _globalGPRsPreservedAcrossCalls.init(cg->getNumberOfGlobalRegisters(), cg->trMemory()); + _globalFPRsPreservedAcrossCalls.init(cg->getNumberOfGlobalRegisters(), cg->trMemory()); + + int16_t i; + TR_GlobalRegisterNumber grn; + for (i=0; i < cg->getNumberOfGlobalGPRs(); i++) + { + grn = cg->getFirstGlobalGPR() + i; + if (cg->getProperties().isPreservedRegister((TR::RealRegister::RegNum)cg->getGlobalRegister(grn))) + _globalGPRsPreservedAcrossCalls.set(grn); + } + for (i=0; i < cg->getNumberOfGlobalFPRs(); i++) + { + grn = cg->getFirstGlobalFPR() + i; + if (cg->getProperties().isPreservedRegister((TR::RealRegister::RegNum)cg->getGlobalRegister(grn))) + _globalFPRsPreservedAcrossCalls.set(grn); + } + + // Reduce the maxObjectSizeGuaranteedNotToOverflow value on 64-bit such that the + // runtime comparison does not sign extend (saves an instruction on array allocations). + // INT_MAX should be sufficiently large. + // + if ((uint32_t)_maxObjectSizeGuaranteedNotToOverflow > (uint32_t)INT_MAX) + { + _maxObjectSizeGuaranteedNotToOverflow = (uint32_t)INT_MAX; + } + } + + OMR::X86::AMD64::CodeGenerator::CodeGenerator() : OMR::X86::CodeGenerator() { diff --git a/compiler/x/amd64/codegen/OMRCodeGenerator.hpp b/compiler/x/amd64/codegen/OMRCodeGenerator.hpp index 1ef59a18e29..fe3d88a4e38 100644 --- a/compiler/x/amd64/codegen/OMRCodeGenerator.hpp +++ b/compiler/x/amd64/codegen/OMRCodeGenerator.hpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2019 IBM Corp. and others + * Copyright (c) 2000, 2020 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -52,7 +52,14 @@ namespace AMD64 class OMR_EXTENSIBLE CodeGenerator : public OMR::X86::CodeGenerator { - public: + +protected: + + CodeGenerator(TR::Compilation *comp); + +public: + + void initialize(); CodeGenerator(); diff --git a/compiler/x/codegen/OMRCodeGenerator.cpp b/compiler/x/codegen/OMRCodeGenerator.cpp index 610944c84d5..916bdba29a2 100644 --- a/compiler/x/codegen/OMRCodeGenerator.cpp +++ b/compiler/x/codegen/OMRCodeGenerator.cpp @@ -509,6 +509,34 @@ OMR::X86::CodeGenerator::initializeX86(TR::Compilation *comp) } +OMR::X86::CodeGenerator::CodeGenerator(TR::Compilation *comp) : + OMR::CodeGenerator(comp), + _nanoTimeTemp(NULL), + _assignmentDirection(Backward), + _lastCatchAppendInstruction(NULL), + _betterSpillPlacements(NULL), + _dataSnippetList(getTypedAllocator(comp->allocator())), + _spilledIntRegisters(getTypedAllocator(comp->allocator())), + _liveDiscardableRegisters(getTypedAllocator(comp->allocator())), + _dependentDiscardableRegisters(getTypedAllocator(comp->allocator())), + _clobberingInstructions(getTypedAllocator(comp->allocator())), + _outlinedInstructionsList(getTypedAllocator(comp->allocator())), + _numReservedIPICTrampolines(0), + _flags(0) + { + _clobIterator = _clobberingInstructions.begin(); + } + + +void +OMR::X86::CodeGenerator::initialize() + { + self()->OMR::CodeGenerator::initialize(); + + _clobIterator = _clobberingInstructions.begin(); + } + + OMR::X86::CodeGenerator::CodeGenerator() : OMR::CodeGenerator(), _nanoTimeTemp(NULL), diff --git a/compiler/x/codegen/OMRCodeGenerator.hpp b/compiler/x/codegen/OMRCodeGenerator.hpp index 6f162f4b4e6..276cacc35f8 100644 --- a/compiler/x/codegen/OMRCodeGenerator.hpp +++ b/compiler/x/codegen/OMRCodeGenerator.hpp @@ -675,7 +675,11 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator */ bool directCallRequiresTrampoline(intptr_t targetAddress, intptr_t sourceAddress); - protected: + void initialize(); + +protected: + + CodeGenerator(TR::Compilation *comp); CodeGenerator(); diff --git a/compiler/x/i386/codegen/OMRCodeGenerator.cpp b/compiler/x/i386/codegen/OMRCodeGenerator.cpp index 4801ca0ed31..6e5a77e87e5 100644 --- a/compiler/x/i386/codegen/OMRCodeGenerator.cpp +++ b/compiler/x/i386/codegen/OMRCodeGenerator.cpp @@ -57,6 +57,83 @@ #include "x/codegen/X86Instruction.hpp" #include "x/codegen/X86Ops.hpp" + +OMR::X86::I386::CodeGenerator::CodeGenerator(TR::Compilation *comp) : + OMR::X86::CodeGenerator(comp) + { + } + + +void +OMR::X86::I386::CodeGenerator::initialize() + { + self()->OMR::X86::CodeGenerator::initialize(); + + TR::CodeGenerator *cg = self(); + TR::Compilation *comp = self()->comp(); + + // Common X86 initialization + // + cg->initializeX86(comp); + + cg->setUsesRegisterPairsForLongs(); + + if (debug("supportsArrayTranslateAndTest")) + cg->setSupportsArrayTranslateAndTest(); + if (debug("supportsArrayCmp")) + cg->setSupportsArrayCmp(); + + cg->setSupportsDoubleWordCAS(); + cg->setSupportsDoubleWordSet(); + + if (comp->target().isWindows()) + { + if (comp->getOption(TR_DisableTraps)) + { + _numberBytesReadInaccessible = 0; + _numberBytesWriteInaccessible = 0; + } + else + { + _numberBytesReadInaccessible = 4096; + _numberBytesWriteInaccessible = 4096; + cg->setHasResumableTrapHandler(); + cg->setEnableImplicitDivideCheck(); + } + cg->setSupportsDivCheck(); + cg->setJNILinkageCalleeCleanup(); + cg->setRealVMThreadRegister(cg->machine()->getRealRegister(TR::RealRegister::ebp)); + } + else if (comp->target().isLinux()) + { + if (comp->getOption(TR_DisableTraps)) + { + _numberBytesReadInaccessible = 0; + _numberBytesWriteInaccessible = 0; + } + else + { + _numberBytesReadInaccessible = 4096; + _numberBytesWriteInaccessible = 4096; + cg->setHasResumableTrapHandler(); + cg->setEnableImplicitDivideCheck(); + } + cg->setRealVMThreadRegister(cg->machine()->getRealRegister(TR::RealRegister::ebp)); + cg->setSupportsDivCheck(); + } + else + { + TR_ASSERT(0, "unknown target"); + } + + cg->setSupportsInlinedAtomicLongVolatiles(); + + static char *dontConsiderAllAutosForGRA = feGetEnv("TR_dontConsiderAllAutosForGRA"); + if (!dontConsiderAllAutosForGRA) + cg->setConsiderAllAutosAsTacticalGlobalRegisterCandidates(); + } + + OMR::X86::I386::CodeGenerator::CodeGenerator() : OMR::X86::CodeGenerator() { diff --git a/compiler/x/i386/codegen/OMRCodeGenerator.hpp b/compiler/x/i386/codegen/OMRCodeGenerator.hpp index 87f6eea59fe..8f25cc2ede8 100644 --- a/compiler/x/i386/codegen/OMRCodeGenerator.hpp +++ b/compiler/x/i386/codegen/OMRCodeGenerator.hpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2019 IBM Corp. and others + * Copyright (c) 2000, 2020 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -54,7 +54,13 @@ namespace I386 class OMR_EXTENSIBLE CodeGenerator : public OMR::X86::CodeGenerator { - public: +protected: + + CodeGenerator(TR::Compilation *comp); + +public: + + void initialize(); CodeGenerator(); diff --git a/compiler/z/codegen/OMRCodeGenerator.cpp b/compiler/z/codegen/OMRCodeGenerator.cpp index c83477c6f4d..f2a6057c795 100644 --- a/compiler/z/codegen/OMRCodeGenerator.cpp +++ b/compiler/z/codegen/OMRCodeGenerator.cpp @@ -394,6 +394,230 @@ bool OMR::Z::CodeGenerator::supportsDirectIntegralLoadStoresFromLiteralPool() return true; } +OMR::Z::CodeGenerator::CodeGenerator(TR::Compilation *comp) + : OMR::CodeGenerator(comp), + _extentOfLitPool(-1), + _recompPatchInsnList(getTypedAllocator(comp->allocator())), + _constantHash(comp->allocator()), + _constantHashCur(_constantHash), + _constantList(getTypedAllocator(comp->allocator())), + _writableList(getTypedAllocator(comp->allocator())), + _transientLongRegisters(comp->trMemory()), + _snippetDataList(getTypedAllocator(comp->allocator())), + _outOfLineCodeSectionList(getTypedAllocator(comp->allocator())), + _returnTypeInfoInstruction(NULL), + _interfaceSnippetToPICsListHashTab(NULL), + _currentCheckNode(NULL), + _currentBCDCHKHandlerLabel(NULL), + _nodesToBeEvaluatedInRegPairs(comp->allocator()), + _ccInstruction(NULL), + _previouslyAssignedTo(comp->allocator("LocalRA")), + _firstTimeLiveOOLRegisterList(NULL), + _methodBegin(NULL), + _methodEnd(NULL), + _afterRA(false) + { + } + +void +OMR::Z::CodeGenerator::initialize() + { + self()->OMR::CodeGenerator::initialize(); + + TR::CodeGenerator *cg = self(); + TR::Compilation *comp = self()->comp(); + + _cgFlags = 0; + + // Initialize Linkage for Code Generator + cg->initializeLinkage(); + + _unlatchedRegisterList = (TR::RealRegister**)cg->trMemory()->allocateHeapMemory(sizeof(TR::RealRegister*)*(TR::RealRegister::NumRegisters)); + _unlatchedRegisterList[0] = 0; // mark that list is empty + + bool enableBranchPreload = comp->getOption(TR_EnableBranchPreload); + bool disableBranchPreload = comp->getOption(TR_DisableBranchPreload); + + if (enableBranchPreload || (!disableBranchPreload && comp->isOptServer() && comp->target().cpu.isAtLeast(OMR_PROCESSOR_S390_ZEC12))) + cg->setEnableBranchPreload(); + else + cg->setDisableBranchPreload(); + + static bool bpp = (feGetEnv("TR_BPRP")!=NULL); + + if ((enableBranchPreload && bpp) || (bpp && !disableBranchPreload && comp->isOptServer() && comp->target().cpu.isAtLeast(OMR_PROCESSOR_S390_ZEC12))) + cg->setEnableBranchPreloadForCalls(); + else + cg->setDisableBranchPreloadForCalls(); + + if (cg->supportsBranchPreloadForCalls()) + { + _callsForPreloadList = new (cg->trHeapMemory()) TR::list(getTypedAllocator(comp->allocator())); + } + + cg->setOnDemandLiteralPoolRun(true); + cg->setGlobalStaticBaseRegisterOn(false); + + cg->setGlobalPrivateStaticBaseRegisterOn(false); + + cg->setMultiplyIsDestructive(); + + cg->setSupportsSelect(); + + cg->setSupportsByteswap(); + + cg->setIsOutOfLineHotPath(false); + + cg->setUsesRegisterPairsForLongs(); + cg->setSupportsDivCheck(); + cg->setSupportsLoweringConstIDiv(); + cg->setSupportsTestUnderMask(); + + // Initialize to be 8 bytes for bodyInfo / methodInfo + cg->setPreJitMethodEntrySize(8); + + // Support divided by power of 2 logic in ldivSimplifier + cg->setSupportsLoweringConstLDivPower2(); + + //enable LM/STM for volatile longs in 32 bit + cg->setSupportsInlinedAtomicLongVolatiles(); + + cg->setSupportsConstantOffsetInAddressing(); + + static char * noVGNOP = feGetEnv("TR_NOVGNOP"); + if (noVGNOP == NULL) + { + cg->setSupportsVirtualGuardNOPing(); + } + if (!comp->getOption(TR_DisableArraySetOpts)) + { + cg->setSupportsArraySet(); + } + cg->setSupportsArrayCmp(); + cg->setSupportsArrayCmpSign(); + if (!comp->compileRelocatableCode()) + { + cg->setSupportsArrayTranslateTRxx(); + } + + cg->setSupportsTestCharComparisonControl(); // TRXX instructions on Danu have mask to disable test char comparison. + cg->setSupportsReverseLoadAndStore(); + cg->setSupportsSearchCharString(); // CISC Transformation into SRSTU loop - only on z9. + cg->setSupportsTranslateAndTestCharString(); // CISC Transformation into TRTE loop - only on z6. + + if (!comp->getOption(TR_DisableTraps) && TR::Compiler->vm.hasResumableTrapHandler(comp)) + { + cg->setHasResumableTrapHandler(); + } + + if (comp->target().cpu.isAtLeast(OMR_PROCESSOR_S390_Z196)) + { + cg->setSupportsAtomicLoadAndAdd(); + } + else + { + // Max min optimization uses the maxMinHelper evaluator which + // requires conditional loads that are not supported below z196 + comp->setOption(TR_DisableMaxMinOptimization); + } + + if (comp->target().cpu.isAtLeast(OMR_PROCESSOR_S390_ZEC12)) + { + cg->setSupportsZonedDFPConversions(); + if (comp->target().cpu.supportsFeature(OMR_FEATURE_S390_TE) && !comp->getOption(TR_DisableTM)) + cg->setSupportsTM(); + } + + if (comp->target().cpu.isAtLeast(OMR_PROCESSOR_S390_Z13) && !comp->getOption(TR_DisableArch11PackedToDFP)) + cg->setSupportsFastPackedDFPConversions(); + + if (!comp->target().cpu.isAtLeast(OMR_PROCESSOR_S390_Z14)) + { + comp->setOption(TR_DisableVectorBCD); + } + + // Be pessimistic until we can prove we don't exit after doing code-generation + cg->setExitPointsInMethod(true); + +#ifdef DEBUG + // Clear internal counters for internal profiling of + // register allocation + cg->clearTotalSpills(); + cg->clearTotalRegisterXfers(); + cg->clearTotalRegisterMoves(); +#endif + + // Set up vector register support for machine after zEC12. + // This should also happen before prepareForGRA + if (comp->getOption(TR_DisableSIMD)) + { + comp->setOption(TR_DisableAutoSIMD); + comp->setOption(TR_DisableSIMDArrayCompare); + comp->setOption(TR_DisableSIMDArrayTranslate); + comp->setOption(TR_DisableSIMDUTF16BEEncoder); + comp->setOption(TR_DisableSIMDUTF16LEEncoder); + comp->setOption(TR_DisableSIMDStringHashCode); + comp->setOption(TR_DisableVectorRegGRA); + } + + cg->setSupportsRecompilation(); + + // This enables the tactical GRA + cg->setSupportsGlRegDeps(); + + cg->addSupportedLiveRegisterKind(TR_GPR); + cg->addSupportedLiveRegisterKind(TR_FPR); + cg->addSupportedLiveRegisterKind(TR_VRF); + + cg->setLiveRegisters(new (cg->trHeapMemory()) TR_LiveRegisters(comp), TR_GPR); + cg->setLiveRegisters(new (cg->trHeapMemory()) TR_LiveRegisters(comp), TR_FPR); + cg->setLiveRegisters(new (cg->trHeapMemory()) TR_LiveRegisters(comp), TR_VRF); + + cg->setSupportsPrimitiveArrayCopy(); + cg->setSupportsReferenceArrayCopy(); + + cg->setSupportsPartialInlineOfMethodHooks(); + + cg->setSupportsInliningOfTypeCoersionMethods(); + + cg->setPerformsChecksExplicitly(); + + _numberBytesReadInaccessible = 4096; + _numberBytesWriteInaccessible = 4096; + + // zLinux sTR requires this as well, otherwise cp00f054.C testcase fails in TR_FPStoreReloadElimination. + cg->setSupportsJavaFloatSemantics(); + + _localF2ISpill = NULL; + _localD2LSpill = NULL; + + _nextAvailableBlockIndex = -1; + _currentBlockIndex = -1; + + if (comp->getOption(TR_TraceRA)) + { + cg->setGPRegisterIterator(new (cg->trHeapMemory()) TR::RegisterIterator(cg->machine(), TR::RealRegister::FirstGPR, TR::RealRegister::LastAssignableGPR)); + cg->setFPRegisterIterator(new (cg->trHeapMemory()) TR::RegisterIterator(cg->machine(), TR::RealRegister::FirstFPR, TR::RealRegister::LastFPR)); + cg->setVRFRegisterIterator(new (cg->trHeapMemory()) TR::RegisterIterator(cg->machine(), TR::RealRegister::FirstVRF, TR::RealRegister::LastVRF)); + } + + if (!comp->getOption(TR_DisableTLHPrefetch) && !comp->compileRelocatableCode()) + { + cg->setEnableTLHPrefetching(); + } + + _reusableTempSlot = NULL; + cg->freeReusableTempSlot(); + + cg->setSupportsProfiledInlining(); + + cg->getS390Linkage()->setParameterLinkageRegisterIndex(comp->getJittedMethodSymbol()); + + cg->getS390Linkage()->initS390RealRegisterLinkage(); + cg->setAccessStaticsIndirectly(true); + } + + OMR::Z::CodeGenerator::CodeGenerator() : OMR::CodeGenerator(), _extentOfLitPool(-1), diff --git a/compiler/z/codegen/OMRCodeGenerator.hpp b/compiler/z/codegen/OMRCodeGenerator.hpp index 71efd16fe7e..40ca7535666 100644 --- a/compiler/z/codegen/OMRCodeGenerator.hpp +++ b/compiler/z/codegen/OMRCodeGenerator.hpp @@ -259,7 +259,16 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator void lowerTreesPropagateBlockToNode(TR::Node *node); +protected: + + CodeGenerator(TR::Compilation *comp); + +public: + CodeGenerator(); + + void initialize(); + TR::Linkage *createLinkage(TR_LinkageConventions lc); bool anyNonConstantSnippets();