From 04bbe606b7819a9773c22950d76954cbee47af1c Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Mon, 28 Jan 2019 13:02:38 -0500 Subject: [PATCH 01/23] Deprecate GRA HPR support This commit deprecates GRA HPR support and cleans up the related APIs in the common GRA infrastructure. We also clean up the HPR support in the register pressure simulator which is surprisingly intertwined with GRA HPR support. Signed-off-by: Filip Jeremic --- compiler/codegen/CodeGenRA.cpp | 186 ------------------ compiler/codegen/OMRCodeGenerator.cpp | 16 +- compiler/codegen/OMRCodeGenerator.hpp | 16 -- .../RegisterPressureSimulatorInner.hpp | 9 +- compiler/control/OMROptions.cpp | 2 - compiler/control/OMROptions.hpp | 4 +- compiler/il/OMRNode.cpp | 103 ---------- compiler/il/OMRNode.hpp | 8 - compiler/optimizer/RegisterCandidate.cpp | 40 +--- compiler/ras/Debug.cpp | 6 - compiler/z/codegen/OMRCodeGenerator.cpp | 70 +++---- compiler/z/codegen/OMRCodeGenerator.hpp | 3 - compiler/z/codegen/OMRInstruction.cpp | 66 ------- compiler/z/codegen/OMRLinkage.cpp | 50 ++--- compiler/z/codegen/OMRMachine.cpp | 149 +++++--------- compiler/z/codegen/OMRMachine.hpp | 22 +-- compiler/z/codegen/OMRRegisterDependency.cpp | 25 +-- compiler/z/codegen/OMRTreeEvaluator.cpp | 57 +----- .../z/codegen/S390GenerateInstructions.cpp | 2 + 19 files changed, 100 insertions(+), 734 deletions(-) diff --git a/compiler/codegen/CodeGenRA.cpp b/compiler/codegen/CodeGenRA.cpp index 2cb478bb989..7ebb4871643 100644 --- a/compiler/codegen/CodeGenRA.cpp +++ b/compiler/codegen/CodeGenRA.cpp @@ -1260,8 +1260,6 @@ OMR::CodeGenerator::pickRegister(TR_RegisterCandidate *rc, const bool canExitEarly = !rc->canBeReprioritized(); TR_BitVector alreadyAssignedOnEntry(self()->comp()->getSymRefCount(), self()->trMemory(), stackAlloc, growable); TR_BitVector alreadyAssignedOnExit(self()->comp()->getSymRefCount(), self()->trMemory(), stackAlloc, growable); - bool hprSimulated = false; - bool hprColdBlockSkipped = false; TR_BitVector blocksToVisit = rc->getBlocksLiveOnEntry(); blocksToVisit |= rc->getBlocksLiveOnExit(); @@ -1295,11 +1293,6 @@ OMR::CodeGenerator::pickRegister(TR_RegisterCandidate *rc, TR::Block *block = allBlocks[blockIterator.getNextElement()]; - // do not assign HPR to candidate if we skipped any block simulation for correctness - if (!block->isExtensionOfPreviousBlock() && blockIsIgnorablyCold(block, self())) - { - hprColdBlockSkipped = true; - } if (!block->isExtensionOfPreviousBlock() && !blockIsIgnorablyCold(block, self())) { // This block starts an extended BB. @@ -1381,24 +1374,7 @@ OMR::CodeGenerator::pickRegister(TR_RegisterCandidate *rc, // Perform the simulation for current block and accumulate into highWaterMark // TR_RegisterPressureSummary summary(state._gprPressure, state._fprPressure, state._vrfPressure); - if (self()->supportsHighWordFacility()) - { - TR::DataType dtype = rc->getSymbolReference()->getSymbol()->getDataType(); - if (dtype == TR::Int8 || - dtype == TR::Int16 || - dtype == TR::Int32) - { - // unless proven, candidate is HPR eligible - state.setCandidateIsHPREligible(true); - } - else - { - state.setCandidateIsHPREligible(false); - summary.spill(TR_hprSpill, self()); - } - } self()->simulateBlockEvaluation(block, &state, &summary); - hprSimulated = true; highWaterMark.accumulate(summary); #if defined(CACHE_CANDIDATE_SPECIFIC_RESULTS) @@ -1691,51 +1667,6 @@ OMR::CodeGenerator::pickRegister(TR_RegisterCandidate *rc, } } - if (self()->supportsHighWordFacility()) - { - TR_BitVector HPRMasks = *self()->getGlobalRegisters(TR_hprSpill, self()->comp()->getMethodSymbol()->getLinkageConvention()); - // We cannot assign an HPR if the corresponding GPR is alive. - // There is no safe way to anticipate whether instruction selection will clobber the High word - // e.g. generating 64-bit instructions for long arithmetics on 32-bit platform - // todo: maybe try checking candidate data type while assigning GPR? only clobber HPR candidate - // if the GPR candidate is long - - if (remainingRegisters.intersects(HPRMasks)) - { - for (int i = self()->getFirstGlobalGPR(); i < self()->getFirstGlobalHPR(); ++i) - { - if (!remainingRegisters.isSet(i)) - { - TR_GlobalRegisterNumber highWordReg = self()->getGlobalHPRFromGPR(i); - if (self()->traceSimulateTreeEvaluation()) - { - traceMsg(self()->comp(), " %s is not available, rejecting %s\n", - self()->getDebug()->getGlobalRegisterName(i), self()->getDebug()->getGlobalRegisterName(highWordReg)); - } - remainingRegisters.reset(highWordReg); - } - } - } - // hack: always give priorities to HPR over GPR - // if any HPR candidate is present - if (remainingRegisters.intersects(HPRMasks)) - { - TR::DataType dtype = rc->getSymbolReference()->getSymbol()->getDataType(); - if (hprSimulated && !hprColdBlockSkipped) - { - if (self()->traceSimulateTreeEvaluation()) - { - traceMsg(self()->comp(), " HPR candidates are available, rejecting all GPR\n"); - remainingRegisters &= HPRMasks; - } - } - else - { - // if simulation did not happen, do not use hpr (cold blocks etc) - remainingRegisters -= HPRMasks; - } - } - } if (self()->traceSimulateTreeEvaluation()) { traceMsg(self()->comp(), " final registers: "); @@ -2628,37 +2559,6 @@ OMR::CodeGenerator::simulateTreeEvaluation(TR::Node *node, TR_RegisterPressureSt return; } - if (self()->supportsHighWordFacility()) - { - // 390 Highword, maybe move this below to else .hasRegister? - if (self()->isCandidateLoad(node, state)) - { - if (node->getOpCodeValue() == TR::iload) - { - //potential HPR candidate - //state->setCandidateIsHPREligible(true); - node->setIsHPREligible(); - } - else - { - // not HPR candidate - state->setCandidateIsHPREligible(false); - summary->spill(TR_hprSpill, self()); - } - } - // if candidate is an object ref - if (state->_candidate && node->getOpCode().hasSymbolReference()) - { - if (node->getOpCode().isRef() && - node->getSymbolReference() == state->_candidate->getSymbolReference()) - { - // not HPR candidate - state->setCandidateIsHPREligible(false); - summary->spill(TR_hprSpill, self()); - } - } - } - TR_SimulatedNodeState &nodeState = self()->simulatedNodeState(node); if (nodeState.hasRegister()) { @@ -2753,63 +2653,12 @@ OMR::CodeGenerator::simulateTreeEvaluation(TR::Node *node, TR_RegisterPressureSt traceMsg(self()->comp(), " ++%s", self()->getDebug()->getName(child)); } - if (self()->supportsHighWordFacility()) - { - // first time visiting this node, clear the flag - if (node->getVisitCount() == state->_visitCountForInit && !self()->isCandidateLoad(node, state)) - { - node->resetIsHPREligible(); - } - } self()->simulateNodeEvaluation(node, state, summary); - if (self()->supportsHighWordFacility()) - { - bool needToCheckHPR = false; - for (uint16_t i = 0; i < node->getNumChildren(); i++) - { - TR::Node *child = node->getChild(i); - if (child->getIsHPREligible()) - { - //traceMsg(comp(), " child %d has isHPREligible set", i); - needToCheckHPR = true; - } - } - - // if enableHighwordRA 390 - if (needToCheckHPR && state->getCandidateIsHPREligible()) - { - if (node->isEligibleForHighWordOpcode()) - { - //traceMsg(comp(), " hpr"); - } - else - { - //traceMsg(comp(), " !hpr"); - node->resetIsHPREligible(); - state->setCandidateIsHPREligible(false); - summary->spill(TR_hprSpill, self()); - } - } - - if (node->getIsHPREligible()) - { - //traceMsg(comp(), " assignedToHPR"); - } - } node->setFutureUseCount(originalRefcount); // Parent will decrement - } else { - if (self()->supportsHighWordFacility()) - { - // first time visiting this node, clear the flag - if (node->getVisitCount() == state->_visitCountForInit && !self()->isCandidateLoad(node, state)) - { - node->resetIsHPREligible(); - } - } // Some kinds of nodes very commonly use temporaries, and sometimes // the number of temporaries depends on the registers used by // children, so compute this while the children are still live. @@ -2830,41 +2679,6 @@ OMR::CodeGenerator::simulateTreeEvaluation(TR::Node *node, TR_RegisterPressureSt } self()->simulateNodeEvaluation(node, state, summary); - - if (self()->supportsHighWordFacility()) - { - bool needToCheckHPR = false; - for (uint16_t i = 0; i < node->getNumChildren(); i++) - { - TR::Node *child = node->getChild(i); - if (child->getIsHPREligible()) - { - //traceMsg(comp(), " child %d has isHPREligible set", i); - needToCheckHPR = true; - } - } - - if (needToCheckHPR && state->getCandidateIsHPREligible()) - { - // if enableHighwordRA 390 - if (node->isEligibleForHighWordOpcode()) - { - //traceMsg(comp(), " hpr"); - } - else - { - node->resetIsHPREligible(); - state->setCandidateIsHPREligible(false); - summary->spill(TR_hprSpill, self()); - //traceMsg(comp(), " !hpr"); - } - } - - if (node->getIsHPREligible()) - { - //traceMsg(comp(), " assignedToHPR"); - } - } } // Accumulate the current state into the summary diff --git a/compiler/codegen/OMRCodeGenerator.cpp b/compiler/codegen/OMRCodeGenerator.cpp index a8d584166ce..f63cb61d405 100644 --- a/compiler/codegen/OMRCodeGenerator.cpp +++ b/compiler/codegen/OMRCodeGenerator.cpp @@ -1098,7 +1098,7 @@ OMR::CodeGenerator::isGlobalVRF(TR_GlobalRegisterNumber n) bool OMR::CodeGenerator::isGlobalFPR(TR_GlobalRegisterNumber n) { - return !self()->isGlobalGPR(n) && !self()->isGlobalHPR(n); + return !self()->isGlobalGPR(n); } TR_BitVector * @@ -1123,7 +1123,6 @@ bool OMR::CodeGenerator::supportsInternalPointers() return self()->internalPointerSupportImplemented(); } - uint16_t OMR::CodeGenerator::getNumberOfGlobalRegisters() { @@ -1133,25 +1132,12 @@ OMR::CodeGenerator::getNumberOfGlobalRegisters() return _lastGlobalFPR + 1; } - -#ifdef TR_HOST_S390 -uint16_t OMR::CodeGenerator::getNumberOfGlobalGPRs() - { - if (self()->supportsHighWordFacility()) - { - return _firstGlobalHPR; - } - return _lastGlobalGPR + 1; - } -#endif - int32_t OMR::CodeGenerator::getMaximumNumberOfGPRsAllowedAcrossEdge(TR::Block *block) { TR::Node *node = block->getLastRealTreeTop()->getNode(); return self()->getMaximumNumberOfGPRsAllowedAcrossEdge(node); } - TR::Register *OMR::CodeGenerator::allocateCollectedReferenceRegister() { TR::Register * temp = self()->allocateRegister(); diff --git a/compiler/codegen/OMRCodeGenerator.hpp b/compiler/codegen/OMRCodeGenerator.hpp index 3a8fabe8b35..3b2cc85a091 100644 --- a/compiler/codegen/OMRCodeGenerator.hpp +++ b/compiler/codegen/OMRCodeGenerator.hpp @@ -116,7 +116,6 @@ enum TR_SpillKinds // For register pressure simulation { // Mandatory spill kinds are certain to cause a spill to memory // - TR_hprSpill, // zGryphon 390 All integer highword regs TR_gprSpill, // All integer regs TR_fprSpill, // All floating-point regs TR_vrfSpill, // All vector regs @@ -918,14 +917,6 @@ class OMR_EXTENSIBLE CodeGenerator TR_GlobalRegisterNumber getLastGlobalGPR() {return _lastGlobalGPR;} TR_GlobalRegisterNumber setLastGlobalGPR(TR_GlobalRegisterNumber n) {return (_lastGlobalGPR = n);} - TR_GlobalRegisterNumber getFirstGlobalHPR() {return _firstGlobalHPR;} - TR_GlobalRegisterNumber setFirstGlobalHPR(TR_GlobalRegisterNumber n) {return (_firstGlobalHPR = n);} - TR_GlobalRegisterNumber getLastGlobalHPR() {return _lastGlobalHPR;} - TR_GlobalRegisterNumber setLastGlobalHPR(TR_GlobalRegisterNumber n) {return (_lastGlobalHPR = n);} - - TR_GlobalRegisterNumber getGlobalHPRFromGPR (TR_GlobalRegisterNumber n) {return 0;} - TR_GlobalRegisterNumber getGlobalGPRFromHPR (TR_GlobalRegisterNumber n) {return 0;} - TR_GlobalRegisterNumber getFirstGlobalFPR() {return _lastGlobalGPR + 1;} TR_GlobalRegisterNumber setFirstGlobalFPR(TR_GlobalRegisterNumber n) {return (_firstGlobalFPR = n);} TR_GlobalRegisterNumber getLastGlobalFPR() {return _lastGlobalFPR;} @@ -952,11 +943,7 @@ class OMR_EXTENSIBLE CodeGenerator uint16_t getNumberOfGlobalRegisters(); -#ifdef TR_HOST_S390 - uint16_t getNumberOfGlobalGPRs(); -#else uint16_t getNumberOfGlobalGPRs() {return _lastGlobalGPR + 1;} -#endif uint16_t getNumberOfGlobalFPRs() {return _lastGlobalFPR - _lastGlobalGPR;} uint16_t getNumberOfGlobalVRFs() {return _lastGlobalVRF - _firstGlobalVRF;} @@ -967,7 +954,6 @@ class OMR_EXTENSIBLE CodeGenerator uint8_t setGlobalFPRPartitionLimit(uint8_t l) {return (_globalFPRPartitionLimit = l);} bool isGlobalGPR(TR_GlobalRegisterNumber n) {return n <= _lastGlobalGPR;} - bool isGlobalHPR(TR_GlobalRegisterNumber n) {return (n >= _firstGlobalHPR && n <= _lastGlobalHPR);} bool isAliasedGRN(TR_GlobalRegisterNumber n); TR_GlobalRegisterNumber getOverlappedAliasForGRN(TR_GlobalRegisterNumber n); @@ -1941,8 +1927,6 @@ class OMR_EXTENSIBLE CodeGenerator TR_RegisterMask _liveRealRegisters[NumRegisterKinds]; TR_GlobalRegisterNumber _lastGlobalGPR; - TR_GlobalRegisterNumber _firstGlobalHPR; - TR_GlobalRegisterNumber _lastGlobalHPR; TR_GlobalRegisterNumber _firstGlobalFPR; TR_GlobalRegisterNumber _lastGlobalFPR; TR_GlobalRegisterNumber _firstOverlappedGlobalFPR; diff --git a/compiler/codegen/RegisterPressureSimulatorInner.hpp b/compiler/codegen/RegisterPressureSimulatorInner.hpp index d25753171a0..295052e9a8d 100644 --- a/compiler/codegen/RegisterPressureSimulatorInner.hpp +++ b/compiler/codegen/RegisterPressureSimulatorInner.hpp @@ -68,7 +68,6 @@ uint32_t _memrefNestDepth; // Recursion depth of simulateMemoryReference; used for diagnostics TR_SimulatedMemoryReference *_currentMemref; - bool _candidateIsHPREligible; // 390 zGryphon Highword GRA TR_RegisterPressureState(TR_RegisterCandidate *candidate, bool candidateIsLiveOnEntry, TR_BitVector &alreadyAssignedOnEntry, TR_BitVector &alreadyAssignedOnExit, TR_LinkHead *candidatesAlreadyAssigned, uint32_t gprLimit, uint32_t fprLimit, uint32_t vrfLimit, vcount_t visitCountForInit): _currentBlock(NULL), @@ -90,8 +89,7 @@ _visitCountForInit(visitCountForInit), _memrefNestDepth(0), _rematNestDepth(0), - _currentMemref(0), - _candidateIsHPREligible(0) + _currentMemref(0) {} TR_RegisterPressureState(const TR_RegisterPressureState &other, TR_RegisterCandidate *candidate, bool candidateIsLiveOnEntry, vcount_t visitCountForInit): _currentBlock (other._currentBlock), @@ -113,8 +111,7 @@ _numLiveCandidateLoads (other._numLiveCandidateLoads), _memrefNestDepth (other._memrefNestDepth), _rematNestDepth (other._rematNestDepth), - _currentMemref (other._currentMemref), - _candidateIsHPREligible (0) + _currentMemref (other._currentMemref) {} TR::SymbolReference *getCandidateSymRef(); @@ -144,8 +141,6 @@ bool pressureIsAtRisk() { return _pressureRiskFromStart || (_pressureRiskUntilEnd > 0); } bool candidateIsLiveAfterGRA(){ return pressureIsAtRisk() || (_numLiveCandidateLoads > 0); } - bool getCandidateIsHPREligible() { return _candidateIsHPREligible;} - void setCandidateIsHPREligible(bool b) { _candidateIsHPREligible = b;} void updateRegisterPressure(TR::Symbol *symbol); diff --git a/compiler/control/OMROptions.cpp b/compiler/control/OMROptions.cpp index ce0129bffb9..3874af2a877 100644 --- a/compiler/control/OMROptions.cpp +++ b/compiler/control/OMROptions.cpp @@ -697,8 +697,6 @@ TR::OptionTable OMR::Options::_jitOptions[] = { {"enableLastRetrialLogging", "O\tenable fullTrace logging for last compilation attempt. Needs to have a log defined on the command line", SET_OPTION_BIT(TR_EnableLastCompilationRetrialLogging), "F"}, {"enableLinkagePreserveStrategy2", "O\tenable linkage strategy 2", SET_OPTION_BIT(TR_LinkagePreserveStrategy2), "F"}, {"enableLocalVPSkipLowFreqBlock", "O\tSkip processing of low frequency blocks in localVP", SET_OPTION_BIT(TR_EnableLocalVPSkipLowFreqBlock), "F" }, - {"enableLongRegAllocation", "O\tenable allocation of 64-bit regs on 32-bit", SET_OPTION_BIT(TR_Enable64BitRegsOn32Bit), "F"}, - {"enableLongRegAllocationHeuristic", "O\tenable heuristic for long register allocation", SET_OPTION_BIT(TR_Enable64BitRegsOn32BitHeuristic), "F"}, {"enableLoopEntryAlignment", "O\tenable loop Entry alignment", SET_OPTION_BIT(TR_EnableLoopEntryAlignment), "F"}, {"enableLoopVersionerCountAllocFences", "O\tallow loop versioner to count allocation fence nodes on PPC toward a profiled guard's block total", SET_OPTION_BIT(TR_EnableLoopVersionerCountAllocationFences), "F"}, {"enableLowerCompilationLimitsDecisionMaking", "O\tenable the piece of code that lowers compilation limits when low on virtual memory (on Linux and z/OS)", diff --git a/compiler/control/OMROptions.hpp b/compiler/control/OMROptions.hpp index fa6e344ca39..c6cc9b8f5b5 100644 --- a/compiler/control/OMROptions.hpp +++ b/compiler/control/OMROptions.hpp @@ -393,7 +393,7 @@ enum TR_CompilationOptions TR_Randomize = 0x00200000 + 9, TR_BreakOnWriteBarrier = 0x00400000 + 9, BreakOnWriteBarrierSnippet = 0x00800000 + 9, - TR_Enable64BitRegsOn32Bit = 0x01000000 + 9, + // Available = 0x01000000 + 9, TR_CountWriteBarriersRT = 0x02000000 + 9, TR_DisableNoServerDuringStartup = 0x04000000 + 9, // set TR_NoOptServer during startup and insert GCR trees TR_BreakOnNew = 0x08000000 + 9, @@ -418,7 +418,7 @@ enum TR_CompilationOptions // Available = 0x00010000 + 10, TR_EnableSequentialLoadStoreWarm = 0x00020000 + 10, TR_EnableSequentialLoadStoreCold = 0x00040000 + 10, - TR_Enable64BitRegsOn32BitHeuristic = 0x00080000 + 10, + // Available = 0x00080000 + 10, TR_EnableNewX86PrefetchTLH = 0x00100000 + 10, // Available = 0x00200000 + 10, TR_ConservativeCompilation = 0x00400000 + 10, diff --git a/compiler/il/OMRNode.cpp b/compiler/il/OMRNode.cpp index b6b89da76d3..941b76b5d56 100644 --- a/compiler/il/OMRNode.cpp +++ b/compiler/il/OMRNode.cpp @@ -5395,109 +5395,6 @@ OMR::Node::printIsInvalid8BitGlobalRegister() return self()->isInvalid8BitGlobalRegister() ? "invalid8BitGlobalRegister " : ""; } - - -const char * -OMR::Node::printIsHPREligible () - { - return self()->getIsHPREligible() ? "canBeAssignedToHPR " : ""; - } - -/** - * Call this after all of the node's children are simulated during GRA - */ -bool -OMR::Node::isEligibleForHighWordOpcode() - { - if (self()->getNumChildren() >2) - { - self()->resetIsHPREligible(); - return false; - } - - TR::Node * firstChild = NULL; - TR::Node * secondChild = NULL; - - if (self()->getNumChildren() >= 1) - { - firstChild = self()->getFirstChild(); - } - if (self()->getNumChildren() == 2) - { - secondChild = self()->getSecondChild(); - } - - switch (self()->getOpCodeValue()) - { - case TR::iconst: - self()->setIsHPREligible(); - return true; - break; - case TR::iadd: - case TR::isub: - if (firstChild->getIsHPREligible()) - { - self()->setIsHPREligible(); - return true; - } - break; - case TR::imul: - case TR::idiv: - if (firstChild->getIsHPREligible()) - { - if (secondChild->isPowerOfTwo() || - (secondChild->getOpCodeValue() == TR::iconst && - ((secondChild->getInt() % 2) == 0))) - { - // this guy can actually stay in either low or high word - self()->resetIsHPREligible(); - return true; - } - } - break; - case TR::ificmpeq: - case TR::ificmpne: - case TR::ificmpge: - case TR::ificmpgt: - case TR::ificmple: - case TR::ificmplt: - if (firstChild->getIsHPREligible()) - { - self()->resetIsHPREligible(); - return true; - } - break; - case TR::iload: - self()->setIsHPREligible(); - return true; - case TR::istore: - if (firstChild->getIsHPREligible()) - { - self()->resetIsHPREligible(); - return true; - } - break; - case TR::istorei: - if (secondChild->getIsHPREligible()) - { - self()->resetIsHPREligible(); - return true; - } - break; - case TR::treetop: - self()->resetIsHPREligible(); - return true; - default: - self()->resetIsHPREligible(); - return false; - break; - } - self()->resetIsHPREligible(); - return false; - } - - - bool OMR::Node::isDirectMemoryUpdate() { diff --git a/compiler/il/OMRNode.hpp b/compiler/il/OMRNode.hpp index 8881e1063ac..52326e865d0 100644 --- a/compiler/il/OMRNode.hpp +++ b/compiler/il/OMRNode.hpp @@ -1024,13 +1024,6 @@ class OMR_EXTENSIBLE Node void setIsInvalid8BitGlobalRegister(bool v); const char * printIsInvalid8BitGlobalRegister(); - // 390 zGryphon Highword register GRA - bool getIsHPREligible() { return _flags.testAny(isHPREligible); } - void setIsHPREligible() { _flags.set(isHPREligible); } - void resetIsHPREligible() { _flags.reset(isHPREligible); } - const char * printIsHPREligible(); - bool isEligibleForHighWordOpcode(); - // Result of this node is being stored into the same location as its left child bool isDirectMemoryUpdate(); void setDirectMemoryUpdate(bool v); @@ -1857,7 +1850,6 @@ class OMR_EXTENSIBLE Node nodePointsToNonNull = 0x00000004, nodeContainsCall = 0x00000008, ///< Only used during local analysis invalid8BitGlobalRegister = 0x00000010, ///< value is in a global register which cannot be used on an 8 bit instruction - isHPREligible = 0x00000010, ///< 390 zGryphon Highword register GRA nodeHasExtension = 0x00000020, directMemoryUpdate = 0x00000040, ///< Result of this node is being stored into the same ///< location as its left child diff --git a/compiler/optimizer/RegisterCandidate.cpp b/compiler/optimizer/RegisterCandidate.cpp index da829552a54..70b4808c444 100644 --- a/compiler/optimizer/RegisterCandidate.cpp +++ b/compiler/optimizer/RegisterCandidate.cpp @@ -2852,44 +2852,6 @@ TR_RegisterCandidates::assign(TR::Block ** cfgBlocks, int32_t numberOfBlocks, in TR::CodeGenerator * cg = comp()->cg(); cg->removeUnavailableRegisters(rc, blocks, availableRegisters); - if (comp()->cg()->supportsHighWordFacility() && !comp()->getOption(TR_DisableRegisterPressureSimulation)) - { - if (!rc->getType().isInt8() && !rc->getType().isInt16() && !rc->getType().isInt32()) - { - for (int8_t i = firstRegister; i <= lastRegister; ++i) - { - // Eliminate all GPRs from consideration whose HPRs are not available since the GPR and HPR overlap - // and our register candidate is a 64-bit symbol - if (cg->isGlobalHPR(i) && !availableRegisters.isSet(i)) - { - TR_GlobalRegisterNumber clobberedGPR = cg->getGlobalGPRFromHPR(i); - - if (trace) - { - traceMsg(comp(), "RC is 64bit and %s is unavailable - removing %s from available list\n", cg->getDebug()->getGlobalRegisterName(i), cg->getDebug()->getGlobalRegisterName(clobberedGPR)); - } - - availableRegisters.reset(clobberedGPR); - } - } - - // Now the only candidates remaining should be GPR-HPR pairs which are both available - for (int8_t i = firstRegister; i <= lastRegister; ++i) - { - // We should not consider HPRs for 64-bit register candidates - if (cg->isGlobalHPR(i) && availableRegisters.isSet(i)) - { - availableRegisters.reset(i); - - if (trace) - { - traceMsg(comp(), "RC is 64bit - removing %s from available list\n", cg->getDebug()->getGlobalRegisterName(i)); - } - } - } - } - } - static const char * vrbVecGRA = feGetEnv("TR_traceVectorGRA"); if (enableVectorGRA) @@ -3769,7 +3731,7 @@ TR_RegisterCandidates::computeAvailableRegisters(TR_RegisterCandidate *rc, int32 while (bvi.hasMoreElements()) { int32_t reg = bvi.getNextElement(); - if (reg != parmReg) + if (reg != parmReg && (reg >= comp()->cg()->getFirstGlobalGPR() && reg <= comp()->cg()->getLastGlobalGPR())) _liveOnEntryConflicts[reg].set(entryBlockNumber); } } diff --git a/compiler/ras/Debug.cpp b/compiler/ras/Debug.cpp index eb29522960e..6c500ed8ff4 100644 --- a/compiler/ras/Debug.cpp +++ b/compiler/ras/Debug.cpp @@ -999,11 +999,7 @@ TR_Debug::nodePrintAllFlags(TR::Node *node, TR_PrettyPrinterString &output) output.append(format, node->printCannotOverflow()); output.append(format, node->printPointsToNonNull()); -#ifdef TR_TARGET_S390 - output.append(format, node->printIsHPREligible()); -#else output.append(format, node->printIsInvalid8BitGlobalRegister()); -#endif output.append(format, node->printIsDirectMemoryUpdate()); output.append(format, node->printIsTheVirtualCallNodeForAGuardedInlinedCall()); if (!inDebugExtension()) @@ -4338,8 +4334,6 @@ TR_Debug::getSpillKindName(uint8_t kind) return "gpr"; case TR_fprSpill: return "fpr"; - case TR_hprSpill: - return "hpr"; case TR_vrfSpill: return "vrf"; case TR_volatileSpill: diff --git a/compiler/z/codegen/OMRCodeGenerator.cpp b/compiler/z/codegen/OMRCodeGenerator.cpp index 1a08fc29e34..053d8adfbd0 100644 --- a/compiler/z/codegen/OMRCodeGenerator.cpp +++ b/compiler/z/codegen/OMRCodeGenerator.cpp @@ -549,6 +549,8 @@ OMR::Z::CodeGenerator::CodeGenerator() TR::Compilation *comp = self()->comp(); _cgFlags = 0; + TR::DebugCounter::incStaticDebugCounter(comp, "hpr/total-compilations"); + // Initialize Linkage for Code Generator self()->initializeLinkage(); @@ -836,27 +838,6 @@ OMR::Z::CodeGenerator::getSupportsBitPermute() return true; } -TR_GlobalRegisterNumber -OMR::Z::CodeGenerator::getGlobalHPRFromGPR (TR_GlobalRegisterNumber n) - { - TR_ASSERT(self()->isGlobalGPR(n), "getGlobalHPRFromGPR: n != GPR?"); - TR::RealRegister *gpr = toRealRegister(self()->machine()->getGPRFromGlobalRegisterNumber(n)); - TR::RealRegister *hpr = gpr->getHighWordRegister(); - return self()->machine()->getGlobalReg(hpr->getRegisterNumber()); - } - -TR_GlobalRegisterNumber -OMR::Z::CodeGenerator::getGlobalGPRFromHPR (TR_GlobalRegisterNumber n) - { - TR_ASSERT(self()->isGlobalHPR(n), "getGlobalGPRFromHPR: n != HPR?"); - //traceMsg(comp(), "getGlobalGPRFromHPR called with n=%d ",n); - TR::RealRegister *hpr = toRealRegister(self()->machine()->getHPRFromGlobalRegisterNumber(n)); - //traceMsg(comp(), "hpr = %s ", getDebug()->getName(hpr)); - TR::RealRegister *gpr = hpr->getLowWordRegister(); - //traceMsg(comp(), "gpr = %s\n", getDebug()->getName(gpr)); - return self()->machine()->getGlobalReg(gpr->getRegisterNumber()); - } - bool OMR::Z::CodeGenerator::prepareForGRA() { bool enableVectorGRA = self()->getSupportsVectorRegisters() && !self()->comp()->getOption(TR_DisableVectorRegGRA); @@ -865,8 +846,6 @@ bool OMR::Z::CodeGenerator::prepareForGRA() { self()->machine()->initializeGlobalRegisterTable(); self()->setGlobalRegisterTable(self()->machine()->getGlobalRegisterTable()); - self()->setFirstGlobalHPR(self()->machine()->getFirstGlobalHPRRegisterNumber()); - self()->setLastGlobalHPR(self()->machine()->getLastGlobalHPRRegisterNumber()); self()->setLastGlobalGPR(self()->machine()->getLastGlobalGPRRegisterNumber()); self()->setLast8BitGlobalGPR(self()->machine()->getLast8BitGlobalGPRRegisterNumber()); self()->setFirstGlobalFPR(self()->machine()->getFirstGlobalFPRRegisterNumber()); @@ -912,16 +891,8 @@ bool OMR::Z::CodeGenerator::prepareForGRA() // Initialize _globalGPRsPreservedAcrossCalls and _globalFPRsPreservedAcrossCalls // We call init here because getNumberOfGlobal[FG]PRs() is initialized during the call to initialize() above. // - if (self()->supportsHighWordFacility()) - { - _globalGPRsPreservedAcrossCalls.init(NUM_S390_GPR + NUM_S390_FPR + NUM_S390_HPR, self()->trMemory()); - _globalFPRsPreservedAcrossCalls.init(NUM_S390_GPR + NUM_S390_FPR + NUM_S390_HPR, self()->trMemory()); - } - else - { - _globalGPRsPreservedAcrossCalls.init(NUM_S390_GPR + NUM_S390_FPR, self()->trMemory()); - _globalFPRsPreservedAcrossCalls.init(NUM_S390_GPR + NUM_S390_FPR, self()->trMemory()); - } + _globalGPRsPreservedAcrossCalls.init(NUM_S390_GPR + NUM_S390_FPR, self()->trMemory()); + _globalFPRsPreservedAcrossCalls.init(NUM_S390_GPR + NUM_S390_FPR, self()->trMemory()); TR_GlobalRegisterNumber grn; for (grn = self()->getFirstGlobalGPR(); grn <= self()->getLastGlobalGPR(); grn++) @@ -953,15 +924,7 @@ bool OMR::Z::CodeGenerator::prepareForGRA() TR_ASSERT(reg != -1, "Register pressure simulator doesn't support gaps in the global register table; reg %d must be removed", grn); if (self()->getFirstGlobalGPR() <= grn && grn <= self()->getLastGlobalGPR()) { - if (self()->supportsHighWordFacility() && self()->getFirstGlobalHPR() <= grn) - { - // this is a bit tricky, we consider Global HPRs part of Global GPRs - _globalRegisterBitVectors[ TR_hprSpill ].set(grn); - } - else - { - _globalRegisterBitVectors[ TR_gprSpill ].set(grn); - } + _globalRegisterBitVectors[ TR_gprSpill ].set(grn); } else if (self()->getFirstGlobalFPR() <= grn && grn <= self()->getLastGlobalFPR()) { @@ -976,11 +939,6 @@ bool OMR::Z::CodeGenerator::prepareForGRA() _globalRegisterBitVectors[ TR_volatileSpill ].set(grn); if (linkage->getIntegerArgument(reg) || linkage->getFloatArgument(reg)) { - if ((self()->supportsHighWordFacility()) && (grn >= self()->getFirstGlobalGPR() && grn <= self()->getLastGlobalGPR())) - { - TR_GlobalRegisterNumber grnHPR = self()->getFirstGlobalHPR() - self()->getFirstGlobalGPR() + grn; - _globalRegisterBitVectors[ TR_linkageSpill ].set(grnHPR); - } _globalRegisterBitVectors[ TR_linkageSpill ].set(grn); } if (reg == linkage->getMethodMetaDataRegister()) @@ -2345,6 +2303,24 @@ OMR::Z::CodeGenerator::upgradeToHPRInstruction(TR::Instruction * inst) self()->replaceInst(inst, newInst); + TR::DebugCounter::incStaticDebugCounter(self()->comp(), "hpr/upgrade"); + + if (srcUpgradable) + { + if (self()->machine()->findBestFreeRegister(inst, TR_GPR, srcReg) != NULL) + { + TR::DebugCounter::incStaticDebugCounter(self()->comp(), "hpr/upgrade-found-free-source-GPR"); + } + } + + if (targetUpgradable) + { + if (self()->machine()->findBestFreeRegister(inst, TR_GPR, targetReg) != NULL) + { + TR::DebugCounter::incStaticDebugCounter(self()->comp(), "hpr/upgrade-found-free-target-GPR"); + } + } + if (self()->getDebug()) self()->getDebug()->addInstructionComment(s390NewInst, "HPR Upgraded"); diff --git a/compiler/z/codegen/OMRCodeGenerator.hpp b/compiler/z/codegen/OMRCodeGenerator.hpp index 163f07dbcb4..e8e4f6ca432 100644 --- a/compiler/z/codegen/OMRCodeGenerator.hpp +++ b/compiler/z/codegen/OMRCodeGenerator.hpp @@ -503,9 +503,6 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator TR_BitVector *getGlobalGPRsPreservedAcrossCalls(){ return &_globalGPRsPreservedAcrossCalls; } TR_BitVector *getGlobalFPRsPreservedAcrossCalls(){ return &_globalFPRsPreservedAcrossCalls; } - TR_GlobalRegisterNumber getGlobalHPRFromGPR (TR_GlobalRegisterNumber n); - TR_GlobalRegisterNumber getGlobalGPRFromHPR (TR_GlobalRegisterNumber n); - bool considerTypeForGRA(TR::Node *node); bool considerTypeForGRA(TR::DataType dt); bool considerTypeForGRA(TR::SymbolReference *symRef); diff --git a/compiler/z/codegen/OMRInstruction.cpp b/compiler/z/codegen/OMRInstruction.cpp index d195160630e..28cc3257b1a 100644 --- a/compiler/z/codegen/OMRInstruction.cpp +++ b/compiler/z/codegen/OMRInstruction.cpp @@ -1478,32 +1478,6 @@ OMR::Z::Instruction::assignOrderedRegisters(TR_RegisterKinds kindToBeAssigned) postInstrFreeReg = _targetReg[0]; } - // Keep track of the first and second non-pair source registers for later - // when determining if "setAssignToHPR" should be called. - TR::Register * firstNonPairSourceRegister = 0; - TR::Register * secondNonPairSourceRegister = 0; - - for (i = 0; i < _sourceRegSize; i++) - { - if (_sourceReg[i]->getRegisterPair()) - continue; - - if (firstNonPairSourceRegister == 0) - { - firstNonPairSourceRegister = _sourceReg[i]; - } - else if (secondNonPairSourceRegister == 0) - { - secondNonPairSourceRegister = _sourceReg[i]; - break; - } - } - - if (firstNonPairSourceRegister == secondNonPairSourceRegister) - { - secondNonPairSourceRegister = 0; - } - // If there is only 1 target register we don't need to block // if (numTrgtPairs==0 && _targetReg && @@ -1669,24 +1643,6 @@ OMR::Z::Instruction::assignOrderedRegisters(TR_RegisterKinds kindToBeAssigned) if (_sourceReg) { registerOperandNum = (_targetReg < _sourceReg) ? _targetRegSize+1 : 1; - if (self()->cg()->supportsHighWordFacility()) - { - if (firstNonPairSourceRegister) - { - if ((self()->getOpCodeValue() == TR::InstOpCode::RISBLG || self()->getOpCodeValue() == TR::InstOpCode::RISBHG) && - ((TR::S390RIEInstruction *)self())->getExtendedHighWordOpCode().getOpCodeValue() != TR::InstOpCode::BAD) - { - firstNonPairSourceRegister->setAssignToHPR(((TR::S390RIEInstruction *)self())->getExtendedHighWordOpCode().isOperandHW(registerOperandNum)); - } - else - firstNonPairSourceRegister->setAssignToHPR(_opcode.isOperandHW(registerOperandNum)); - } - - if (secondNonPairSourceRegister) - { - secondNonPairSourceRegister->setAssignToHPR(_opcode.isOperandHW(registerOperandNum+1)); - } - } for (i = 0; i < _sourceRegSize; ++i) { @@ -1705,17 +1661,6 @@ OMR::Z::Instruction::assignOrderedRegisters(TR_RegisterKinds kindToBeAssigned) { for (i = 0; i < _sourceMemSize; ++i) { - if (self()->cg()->supportsHighWordFacility()) - { - if (_sourceMem[i]->getBaseRegister()) - { - _sourceMem[i]->getBaseRegister()->setAssignToHPR(false); - } - if (_sourceMem[i]->getIndexRegister()) - { - _sourceMem[i]->getIndexRegister()->setAssignToHPR(false); - } - } _sourceMem[i]->assignRegisters(self(), self()->cg()); _sourceMem[i]->blockRegisters(); } @@ -1724,17 +1669,6 @@ OMR::Z::Instruction::assignOrderedRegisters(TR_RegisterKinds kindToBeAssigned) { for (i = 0; i < _targetMemSize; ++i) { - if (self()->cg()->supportsHighWordFacility()) - { - if (_targetMem[i]->getBaseRegister()) - { - _targetMem[i]->getBaseRegister()->setAssignToHPR(false); - } - if (_targetMem[i]->getIndexRegister()) - { - _targetMem[i]->getIndexRegister()->setAssignToHPR(false); - } - } _targetMem[i]->assignRegisters(self(), self()->cg()); _targetMem[i]->blockRegisters(); } diff --git a/compiler/z/codegen/OMRLinkage.cpp b/compiler/z/codegen/OMRLinkage.cpp index d2c225cab65..754952b9cdb 100644 --- a/compiler/z/codegen/OMRLinkage.cpp +++ b/compiler/z/codegen/OMRLinkage.cpp @@ -412,27 +412,17 @@ OMR::Z::Linkage::saveArguments(void * cursor, bool genBinary, bool InPreProlog, // -> set means free // Keep a list of global registers // - if (self()->cg()->supportsHighWordFacility()) + if (enableVectorLinkage) { - freeScratchable.init(TR::RealRegister::LastHPR + 1, self()->trMemory()); - globalAllocatedRegisters.init(TR::RealRegister::LastHPR + 1, self()->trMemory()); - lastReg = TR::RealRegister::LastHPR; + freeScratchable.init(TR::RealRegister::LastVRF + 1, self()->trMemory()); + globalAllocatedRegisters.init(TR::RealRegister::LastVRF + 1, self()->trMemory()); } else { - if (enableVectorLinkage) - { - freeScratchable.init(TR::RealRegister::LastVRF + 1, self()->trMemory()); - globalAllocatedRegisters.init(TR::RealRegister::LastVRF + 1, self()->trMemory()); - } - else - { - freeScratchable.init(TR::RealRegister::LastFPR + 1, self()->trMemory()); - globalAllocatedRegisters.init(TR::RealRegister::LastFPR + 1, self()->trMemory()); - } + freeScratchable.init(TR::RealRegister::LastFPR + 1, self()->trMemory()); + globalAllocatedRegisters.init(TR::RealRegister::LastFPR + 1, self()->trMemory()); } - for (i1 = TR::RealRegister::FirstGPR; i1 <= lastReg; i1++) { // TODO: remove hard-coded GPR6, valid on zOS for non-XPLINK? @@ -574,10 +564,6 @@ OMR::Z::Linkage::saveArguments(void * cursor, bool genBinary, bool InPreProlog, break; } - if (ai >= 0 && - loadOpCode == TR::InstOpCode::L && self()->cg()->supportsHighWordFacility() && self()->getRealRegister(REGNUM(ai))->isHighWordRegister()) - loadOpCode = TR::InstOpCode::LFH; - if (((self()->isSmallIntParmsAlignedRight() && paramCursor->getType().isIntegral()) || (self()->isPadFloatParms() && paramCursor->getType().isFloatingPoint())) && (gprSize > paramCursor->getSize())) { @@ -923,16 +909,8 @@ OMR::Z::Linkage::saveArguments(void * cursor, bool genBinary, bool InPreProlog, } else { - if (self()->cg()->supportsHighWordFacility() && self()->getRealRegister(REGNUM(ai))->isHighWordRegister()) - { - cursor = generateExtendedHighWordInstruction(firstNode, self()->cg(), TR::InstOpCode::LHLR, self()->getRealRegister(REGNUM(ai)), - self()->getRealRegister(regNum), 0, (TR::Instruction *) cursor); - } - else - { - cursor = generateRRInstruction(self()->cg(), TR::InstOpCode::getLoadRegOpCode(), firstNode, self()->getRealRegister(REGNUM(ai)), - self()->getRealRegister(regNum), (TR::Instruction *) cursor); - } + cursor = generateRRInstruction(self()->cg(), TR::InstOpCode::getLoadRegOpCode(), firstNode, self()->getRealRegister(REGNUM(ai)), + self()->getRealRegister(regNum), (TR::Instruction *) cursor); freeScratchable.reset(ai); freeScratchable.set(regNum); @@ -1215,19 +1193,13 @@ OMR::Z::Linkage::saveArguments(void * cursor, bool genBinary, bool InPreProlog, switch(busyMoves[2][i1]) { case 0: // Reg 2 Reg - if (self()->cg()->supportsHighWordFacility() && self()->getRealRegister(REGNUM(target))->isHighWordRegister()) - { - cursor = generateExtendedHighWordInstruction(firstNode, self()->cg(), TR::InstOpCode::LHLR, self()->getRealRegister(REGNUM(target)), - self()->getRealRegister(REGNUM(source)), 0, (TR::Instruction *) cursor); - } - else - { - cursor = generateRRInstruction(self()->cg(), TR::InstOpCode::getLoadRegOpCode(), firstNode, self()->getRealRegister(REGNUM(target)), - self()->getRealRegister(REGNUM(source)), (TR::Instruction *) cursor); + { + cursor = generateRRInstruction(self()->cg(), TR::InstOpCode::getLoadRegOpCode(), firstNode, self()->getRealRegister(REGNUM(target)), + self()->getRealRegister(REGNUM(source)), (TR::Instruction *) cursor); - } freeScratchable.set(source); break; + } case 1: // Int or Addr Reg from Stack Slot { TR::MemoryReference *mr = generateS390MemoryReference(stackPtr, source, self()->cg()); diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index 742e5ceb494..fc7f644be79 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -148,10 +148,12 @@ OMR::Z::Machine::registerCopy(TR::CodeGenerator* cg, TR::InstOpCode::LR; cursor = generateRRInstruction(cg, mnemonic, node, targetReg, sourceReg, precedingInstruction); + TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/GPR"); } else { cursor = generateExtendedHighWordInstruction(node, cg, TR::InstOpCode::LLHFR, targetReg, sourceReg, 0, precedingInstruction); + TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/HPR"); } break; } @@ -164,14 +166,16 @@ OMR::Z::Machine::registerCopy(TR::CodeGenerator* cg, TR::InstOpCode::LHHR; cursor = generateExtendedHighWordInstruction(node, cg, mnemonic, targetReg, sourceReg, 0, precedingInstruction); + TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/HPR"); break; } case TR_FPR: cursor = generateRRInstruction(cg, TR::InstOpCode::LDR, node, targetReg, sourceReg, precedingInstruction); + TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/FPR"); break; case TR_VRF: cursor = generateVRRaInstruction(cg, TR::InstOpCode::VLR, node, targetReg, sourceReg, precedingInstruction); - + TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/VRF"); break; } @@ -229,6 +233,8 @@ OMR::Z::Machine::registerExchange(TR::CodeGenerator* cg, } else { + TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/FPR", 3); + TR::Instruction * currentInstruction = precedingInstruction; TR_BackingStore * location; location = cg->allocateSpill(8, false, NULL); @@ -265,6 +271,8 @@ OMR::Z::Machine::registerExchange(TR::CodeGenerator* cg, } else { + TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/VRF", 3); + TR_BackingStore * location; location = cg->allocateSpill(16, false, NULL); TR::MemoryReference * tempMR = generateS390MemoryReference(currentNode, location->getSymbolReference(), cg); @@ -358,6 +366,15 @@ OMR::Z::Machine::registerExchange(TR::CodeGenerator* cg, cg->traceRAInstruction(currentInstruction); cg->freeSpill(location, TR::Compiler->om.sizeofReferenceAddress(), 0); + + if (srcRegIsHPR || tgtRegIsHPR) + { + TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/HPR"); + } + else + { + TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/GPR"); + } } else { @@ -367,6 +384,14 @@ OMR::Z::Machine::registerExchange(TR::CodeGenerator* cg, if (enableHighWordRA) { + if (srcRegIsHPR || tgtRegIsHPR) + { + TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/HPR"); + } + else + { + TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/GPR"); + } if (srcRegIsHPR != middleRegIsHPR) { currentInstruction = @@ -418,6 +443,14 @@ OMR::Z::Machine::registerExchange(TR::CodeGenerator* cg, } else { + if (srcRegIsHPR || tgtRegIsHPR) + { + TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/HPR"); + } + else + { + TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/GPR"); + } currentInstruction = generateRRInstruction(cg, opLoadReg, currentNode, sourceReg, middleReg, precedingInstruction); cg->traceRAInstruction(currentInstruction); @@ -561,7 +594,6 @@ OMR::Z::Machine::Machine(TR::CodeGenerator * cg) _lastGlobalFPRRegisterNumber(-1), _lastGlobalCCRRegisterNumber(-1), _lastVolatileNonLinkGPR(-1), _lastLinkageGPR(-1), _lastVolatileNonLinkFPR(-1), _lastLinkageFPR(-1), _globalEnvironmentRegisterNumber(-1), _globalCAARegisterNumber(-1), _globalParentDSARegisterNumber(-1), _globalReturnAddressRegisterNumber(-1),_globalEntryPointRegisterNumber(-1) - ,_lastGlobalHPRRegisterNumber(-1), _firstGlobalHPRRegisterNumber(-1) { self()->initializeRegisterFile(); self()->initializeFPRegPairTable(); @@ -3648,6 +3680,8 @@ OMR::Z::Machine::spillRegister(TR::Instruction * currentInstruction, TR::Registe } self()->cg()->traceRegisterAssignment("\nHW RA: HW spill: %R(%R) into %R\n", virtReg, best, freeHighWordReg); + TR::DebugCounter::incStaticDebugCounter(comp, "hpr/spill/HPR/register"); + // spill to HW if (alreadySpilledToHPR) { @@ -3749,17 +3783,27 @@ OMR::Z::Machine::spillRegister(TR::Instruction * currentInstruction, TR::Registe { if (best->isHighWordRegister()) { + TR::DebugCounter::incStaticDebugCounter(comp, "hpr/spill/HPR/memory"); opCode = TR::InstOpCode::LFH; } else if (best->isLowWordRegister() && best->getHighWordRegister()->getAssignedRegister() != virtReg) { + TR::DebugCounter::incStaticDebugCounter(comp, "hpr/spill/GPR"); opCode = TR::InstOpCode::L; } + else + { + TR::DebugCounter::incStaticDebugCounter(comp, "hpr/spill/GPR"); + } //TR_ASSERTC( TR::Compiler->target.is64Bit(),comp, "\nallocateSpill has incorrect spill slot size"); //this assume kicks in for SLLG, MGHI etc on 31bit if (debugObj) self()->cg()->traceRegisterAssignment(" HW RA: spilling %R:%R", virtReg, best); } + else + { + TR::DebugCounter::incStaticDebugCounter(comp, "hpr/spill/GPR"); + } break; case TR_FPR: if (!comp->getOption(TR_DisableOOL) && @@ -3773,6 +3817,7 @@ OMR::Z::Machine::spillRegister(TR::Instruction * currentInstruction, TR::Registe } else { + TR::DebugCounter::incStaticDebugCounter(comp, "hpr/spill/FPR"); location = self()->cg()->allocateSpill(8, false, NULL, true); // TODO: Use 4 for single-precision values if (debugObj) self()->cg()->traceRegisterAssignment("\nSpilling FPR %s to (%p)\n", debugObj->getName(virtReg),location); @@ -3780,6 +3825,7 @@ OMR::Z::Machine::spillRegister(TR::Instruction * currentInstruction, TR::Registe opCode = TR::InstOpCode::LD; break; case TR_VRF: + TR::DebugCounter::incStaticDebugCounter(comp, "hpr/spill/VRF"); // Spill of size 16 has never been done before. The call hierarchy seems to support it but this should be watched closely. location = self()->cg()->allocateSpill(16, false, NULL, true); if (debugObj) @@ -5697,59 +5743,6 @@ OMR::Z::Machine::initializeGlobalRegisterTable() if (linkage->isXPLinkLinkageType()) p = self()->addGlobalRegLater(TR::RealRegister::GPR7, p); - // Register pressure simulation is a prerequisite for HPR GRA because GRA and local RA need to make consistent - // choices and register pressure simulation is the only part of GRA that is HPR aware. As concrete examples, among - // others, consider the following: - // - // 1. A collected reference coming in as a parameter - // - // In this case GRA needs to know that on 64-bit such a register candidate should not be considered for HPRs, since - // they are really 32-bit registers. However GRA does not know anything about this. It is the register pressure - // simulation algorithm [1] that coordinates with the codegen on whether collected references are HPR elligible. - // - // 2. A valid HPR candidate is being used as a return value - // - // In this case GRA needs to be aware of the choices local RA will make. Because a value feeds into a return point - // of a method local RA must enforce that the virtual register corresponding to the return value is 64-bit [3]. - // Otherwise the high order half of the register may get locally allocated to an HPR spill, and of course this - // would not be valid. As such GRA must know this fact and it must not globally allocate the return value to an - // HPR, otherwise we will get into an impossible scenario where local RA is forced to coerce a 64-bit GPR (the - // return value) into a 32-bit HPR. - // - // The register pressure algorithm is once again aware of these interactions and prevents such values feeding - // into return points from being globally HPR allocated [2]. - // - // [1] https://github.com/eclipse/omr/blob/9d1d8cf3048781bc6d87e6a1079167586cc5aa4d/compiler/codegen/CodeGenRA.cpp#L2691-L2702 - // [2] https://github.com/eclipse/omr/blob/9d1d8cf3048781bc6d87e6a1079167586cc5aa4d/compiler/codegen/CodeGenRA.cpp#L2889-L2903 - // [3] https://github.com/eclipse/omr/blob/9d1d8cf3048781bc6d87e6a1079167586cc5aa4d/compiler/z/codegen/ControlFlowEvaluator.cpp#L1098-L1102 - - if (self()->cg()->supportsHighWordFacility() && !comp->getOption(TR_DisableRegisterPressureSimulation)) - { - // HPR - // this is a bit tricky, we consider Global HPRs part of Global GPRs - self()->setFirstGlobalHPRRegisterNumber(p); - // volatile HPRs - // might use HPR4 on 31-bit zLinux - p = self()->addGlobalReg(TR::RealRegister::HPR3, p); - p = self()->addGlobalReg(TR::RealRegister::HPR2, p); - p = self()->addGlobalReg(TR::RealRegister::HPR1, p); - // for preserved regs, we can only use HPR6-12 because VM only saves/restores those - if (TR::Compiler->target.is32Bit()) - { - // might use GPR6 on 64-bit for lit pool reg - p = self()->addGlobalReg(TR::RealRegister::HPR6, p); - } - - p = self()->addGlobalReg(TR::RealRegister::HPR7, p); - p = self()->addGlobalReg(TR::RealRegister::HPR8, p); - p = self()->addGlobalReg(TR::RealRegister::HPR9, p); - p = self()->addGlobalReg(TR::RealRegister::HPR10, p); - p = self()->addGlobalReg(TR::RealRegister::HPR11, p); - p = self()->addGlobalReg(TR::RealRegister::HPR12, p); - self()->setLastGlobalHPRRegisterNumber(p-1); - // might use HPR15 on 31-bit zOS - } - self()->setLastGlobalGPRRegisterNumber(p-1); // Volatiles that aren't linkage regs @@ -5942,24 +5935,12 @@ OMR::Z::Machine::setLastGlobalGPRRegisterNumber(TR_GlobalRegisterNumber reg) return _lastGlobalGPRRegisterNumber = reg; } -TR_GlobalRegisterNumber -OMR::Z::Machine::setLastGlobalHPRRegisterNumber(TR_GlobalRegisterNumber reg) - { - return _lastGlobalHPRRegisterNumber = reg; - } - TR_GlobalRegisterNumber OMR::Z::Machine::setFirstGlobalGPRRegisterNumber(TR_GlobalRegisterNumber reg) { return _firstGlobalGPRRegisterNumber = reg; } -TR_GlobalRegisterNumber -OMR::Z::Machine::setFirstGlobalHPRRegisterNumber(TR_GlobalRegisterNumber reg) - { - return _firstGlobalHPRRegisterNumber = reg; - } - TR_GlobalRegisterNumber OMR::Z::Machine::setFirstGlobalFPRRegisterNumber(TR_GlobalRegisterNumber reg) { @@ -5992,40 +5973,6 @@ OMR::Z::Machine::setLastGlobalCCRRegisterNumber(TR_GlobalRegisterNumber reg) return _lastGlobalCCRRegisterNumber=reg; } -TR::Register* -OMR::Z::Machine::getGPRFromGlobalRegisterNumber(TR_GlobalRegisterNumber reg) - { - auto firstGlobalGPR = self()->getFirstGlobalGPRRegisterNumber(); - auto firstGlobalHPR = self()->getFirstGlobalHPRRegisterNumber(); - - if (firstGlobalHPR != -1 && - reg >= firstGlobalGPR && - reg <= firstGlobalHPR && - _globalRegisterNumberToRealRegisterMap[reg] >= 0) - { - return _registerFile[_globalRegisterNumberToRealRegisterMap[reg]]; - } - - return NULL; - } - -TR::Register* -OMR::Z::Machine::getHPRFromGlobalRegisterNumber(TR_GlobalRegisterNumber reg) - { - auto firstGlobalHPR = self()->getFirstGlobalHPRRegisterNumber(); - auto lastGlobalHPR = self()->getLastGlobalHPRRegisterNumber(); - - if (firstGlobalHPR != -1 && - reg >= firstGlobalHPR && - reg <= lastGlobalHPR && - _globalRegisterNumberToRealRegisterMap[reg] >= 0) - { - return _registerFile[_globalRegisterNumberToRealRegisterMap[reg]]; - } - - return NULL; - } - // Register Association //////////////////////////////////////////// void OMR::Z::Machine::setRegisterWeightsFromAssociations() diff --git a/compiler/z/codegen/OMRMachine.hpp b/compiler/z/codegen/OMRMachine.hpp index 14a650e9203..b04aef5357f 100644 --- a/compiler/z/codegen/OMRMachine.hpp +++ b/compiler/z/codegen/OMRMachine.hpp @@ -198,8 +198,6 @@ class OMR_EXTENSIBLE Machine : public OMR::Machine TR_GlobalRegisterNumber _firstGlobalGPRRegisterNumber; TR_GlobalRegisterNumber _lastGlobalGPRRegisterNumber; - TR_GlobalRegisterNumber _firstGlobalHPRRegisterNumber; - TR_GlobalRegisterNumber _lastGlobalHPRRegisterNumber; TR_GlobalRegisterNumber _last8BitGlobalGPRRegisterNumber; TR_GlobalRegisterNumber _firstGlobalFPRRegisterNumber; TR_GlobalRegisterNumber _firstOverlappedGlobalFPRRegisterNumber; @@ -377,14 +375,7 @@ class OMR_EXTENSIBLE Machine : public OMR::Machine } TR_GlobalRegisterNumber setLastGlobalGPRRegisterNumber(TR_GlobalRegisterNumber reg); - - TR_GlobalRegisterNumber getLastGlobalHPRRegisterNumber() - { - return _lastGlobalHPRRegisterNumber; - } - - TR_GlobalRegisterNumber setLastGlobalHPRRegisterNumber(TR_GlobalRegisterNumber reg); - + TR_GlobalRegisterNumber getFirstGlobalGPRRegisterNumber() { return _firstGlobalGPRRegisterNumber; @@ -392,13 +383,6 @@ class OMR_EXTENSIBLE Machine : public OMR::Machine TR_GlobalRegisterNumber setFirstGlobalGPRRegisterNumber(TR_GlobalRegisterNumber reg); - TR_GlobalRegisterNumber getFirstGlobalHPRRegisterNumber() - { - return _firstGlobalHPRRegisterNumber; - } - - TR_GlobalRegisterNumber setFirstGlobalHPRRegisterNumber(TR_GlobalRegisterNumber reg); - TR_GlobalRegisterNumber getLast8BitGlobalGPRRegisterNumber() { return _last8BitGlobalGPRRegisterNumber; @@ -581,10 +565,6 @@ class OMR_EXTENSIBLE Machine : public OMR::Machine return _lastLinkageFPR=reg; } - TR::Register * getGPRFromGlobalRegisterNumber(TR_GlobalRegisterNumber reg); - - TR::Register * getHPRFromGlobalRegisterNumber(TR_GlobalRegisterNumber reg); - //////////////////////////////// // Register Association Stuff /////////////// diff --git a/compiler/z/codegen/OMRRegisterDependency.cpp b/compiler/z/codegen/OMRRegisterDependency.cpp index 9d8fb247a1a..3393f69212f 100644 --- a/compiler/z/codegen/OMRRegisterDependency.cpp +++ b/compiler/z/codegen/OMRRegisterDependency.cpp @@ -133,32 +133,14 @@ OMR::Z::RegisterDependencyConditions::RegisterDependencyConditions(TR::CodeGener } TR::RegisterPair * regPair = reg->getRegisterPair(); - resolveSplitDependencies(cg, node, child, regPair, regList, - reg, highReg, copyReg, highCopyReg, iCursor, regNum); + resolveSplitDependencies(cg, node, child, regPair, regList, reg, highReg, copyReg, highCopyReg, iCursor, regNum); - TR::Register * copyHPR = NULL; - if (cg->machine()->getHPRFromGlobalRegisterNumber(child->getGlobalRegisterNumber())) - { - if (reg->is64BitReg() && !reg->containsCollectedReference()) - { - //if GRA wants a 64-bit scalar into an HPR we must split this register - copyHPR = cg->allocateRegister(TR_GPR); - iCursor = generateRRInstruction(cg, TR::InstOpCode::LR, node, copyHPR, reg, iCursor); - reg = copyHPR; - } - reg->setAssignToHPR(true); - } reg->setAssociation(regNum); cg->setRealRegisterAssociation(reg, regNum); addPreCondition(reg, regNum); addPostCondition(reg, regNum); - if (copyHPR != NULL) - { - cg->stopUsingRegister(copyHPR); - } - if (copyReg != NULL) { cg->stopUsingRegister(copyReg); @@ -408,11 +390,6 @@ void OMR::Z::RegisterDependencyConditions::resolveSplitDependencies( copyReg->setPinningArrayPointer(reg->getPinningArrayPointer()); } - if (cg->machine()->getHPRFromGlobalRegisterNumber(child->getGlobalRegisterNumber()) != NULL) - { - copyReg->setAssignToHPR(true); - } - switch (kind) { case TR_GPR: diff --git a/compiler/z/codegen/OMRTreeEvaluator.cpp b/compiler/z/codegen/OMRTreeEvaluator.cpp index a3d80d823e7..01da9956ccc 100644 --- a/compiler/z/codegen/OMRTreeEvaluator.cpp +++ b/compiler/z/codegen/OMRTreeEvaluator.cpp @@ -9800,10 +9800,7 @@ OMR::Z::TreeEvaluator::passThroughEvaluator(TR::Node * node, TR::CodeGenerator * copyReg->setContainsInternalPointer(); copyReg->setPinningArrayPointer(reg->getPinningArrayPointer()); } - if (cg->machine()->getHPRFromGlobalRegisterNumber(node->getGlobalRegisterNumber()) != NULL) - { - copyReg->setAssignToHPR(true); - } + switch (kind) { case TR_GPR: @@ -12004,10 +12001,6 @@ OMR::Z::TreeEvaluator::iRegLoadEvaluator(TR::Node * node, TR::CodeGenerator * cg node->setRegister(globalReg); globalReg->setAssignToHPR(false); - if (cg->machine()->getHPRFromGlobalRegisterNumber(globalRegNum) != NULL) - { - globalReg->setAssignToHPR(true); - } } return globalReg; @@ -12089,50 +12082,21 @@ OMR::Z::TreeEvaluator::iRegStoreEvaluator(TR::Node * node, TR::CodeGenerator * c } } - bool useHPR = !cg->comp()->compileRelocatableCode() && cg->machine()->getHPRFromGlobalRegisterNumber(globalRegNum) != NULL; - - if (useHPR && child->getOpCode().isLoadConst()) + if (!useLGHI) { - // change LHI into IIHF if GRA assigned an HPR to globalReg - globalReg = child->getRegister(); - if (globalReg == NULL) - { - globalReg = cg->allocateRegister(); - generateRILInstruction(cg, TR::InstOpCode::IIHF, child, globalReg, static_cast((getIntegralValue(child)))); - child->setRegister(globalReg); - } - globalReg->setAssignToHPR(true); + globalReg = cg->evaluate(child); } - else if (useHPR && child->getOpCode().isLoadVar() && child->getType().isInt32()) + else { - TR_ASSERT(!needsLGFR, " GlobalHPR should not need signExt! \n"); - needsLGFR = false; globalReg = child->getRegister(); if (globalReg == NULL) { - globalReg = cg->allocateRegister(); - generateRXInstruction(cg, TR::InstOpCode::LFH, child, globalReg, generateS390MemoryReference(child,cg)); - child->setRegister(globalReg); - } - globalReg->setAssignToHPR(true); - } - else - { - if (!useLGHI) - { - globalReg = cg->evaluate(child); - } - else - { - globalReg = child->getRegister(); - if (globalReg == NULL) - { - globalReg = child->setRegister(cg->allocateRegister()); - } - globalReg->setIs64BitReg(true); - genLoadLongConstant(cg, child, getIntegralValue(child), globalReg); + globalReg = child->setRegister(cg->allocateRegister()); } + globalReg->setIs64BitReg(true); + genLoadLongConstant(cg, child, getIntegralValue(child), globalReg); } + // Without extensive evaluation of children & context, assume that we might have swapped signs globalReg->resetAlreadySignExtended(); @@ -12141,11 +12105,6 @@ OMR::Z::TreeEvaluator::iRegStoreEvaluator(TR::Node * node, TR::CodeGenerator * c ((child->getOpCodeValue() == TR::su2i) && (child->getFirstChild()->getOpCodeValue() == TR::cloadi)) || ((child->getOpCodeValue() == TR::l2i) && (child->getFirstChild()->getOpCodeValue() == TR::i2l)); - if (cg->supportsHighWordFacility()) - { - child_sign_extended = false; - } - if (needsLGFR) { if ((noLGFgenerated) && (!child_sign_extended)) diff --git a/compiler/z/codegen/S390GenerateInstructions.cpp b/compiler/z/codegen/S390GenerateInstructions.cpp index ad7e49ff71a..ec3e157d1fb 100644 --- a/compiler/z/codegen/S390GenerateInstructions.cpp +++ b/compiler/z/codegen/S390GenerateInstructions.cpp @@ -3246,6 +3246,8 @@ generateExtendedHighWordInstruction(TR::Node * node, TR::CodeGenerator *cg, TR:: ((TR::S390RIEInstruction *)cursor)->setExtendedHighWordOpCode(op); + TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/HPR"); + if (debugObj) { debugObj->addInstructionComment(cursor, COMMENT); From c688fdfbd93942fbdd02b15acde52c4e8d5a39e0 Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Thu, 28 Feb 2019 09:14:31 -0500 Subject: [PATCH 02/23] Deprecate HPR upgrades Signed-off-by: Filip Jeremic --- compiler/z/codegen/OMRCodeGenerator.cpp | 561 ------------------- compiler/z/codegen/OMRCodeGenerator.hpp | 2 - compiler/z/codegen/OMRInstruction.cpp | 34 +- compiler/z/codegen/OMRRegister.cpp | 12 - compiler/z/codegen/OMRRegister.hpp | 4 - compiler/z/codegen/OMRRegisterDependency.cpp | 3 - compiler/z/codegen/OMRRegisterDependency.hpp | 2 - compiler/z/codegen/OMRRegisterPair.cpp | 70 --- compiler/z/codegen/OMRRegisterPair.hpp | 65 --- fvtest/compilertest/build/IWYU_Mappings.imp | 1 - fvtest/compilertest/build/files/target/z.mk | 1 - 11 files changed, 1 insertion(+), 754 deletions(-) delete mode 100644 compiler/z/codegen/OMRRegisterPair.cpp delete mode 100644 compiler/z/codegen/OMRRegisterPair.hpp diff --git a/compiler/z/codegen/OMRCodeGenerator.cpp b/compiler/z/codegen/OMRCodeGenerator.cpp index 053d8adfbd0..058b924996a 100644 --- a/compiler/z/codegen/OMRCodeGenerator.cpp +++ b/compiler/z/codegen/OMRCodeGenerator.cpp @@ -1777,559 +1777,6 @@ OMR::Z::CodeGenerator::isLitPoolFreeForAssignment() return litPoolRegIsFree; } - -TR::Instruction * -OMR::Z::CodeGenerator::upgradeToHPRInstruction(TR::Instruction * inst) - { - TR::Instruction * s390Inst = inst; - TR::Register * targetReg = s390Inst->getRegisterOperand(1); - TR::Register * srcReg = s390Inst->getRegisterOperand(2); - bool targetUpgradable = false; - bool srcUpgradable = false; - TR::InstOpCode::Mnemonic newOpCode = TR::InstOpCode::BAD; - TR::Instruction * newInst = NULL; - TR::Node * node = inst->getNode(); - int32_t immValue = 0; - TR::MemoryReference *mr; - - if (s390Inst->getOpCode().is64bit() || - (targetReg && targetReg->is64BitReg()) || - (srcReg && srcReg->is64BitReg())) - { - return NULL; - } - - if (targetReg && targetReg->isHighWordUpgradable()) - { - targetUpgradable = true; - TR::RealRegister * targetRealReg = targetReg->getAssignedRealRegister(); - - if (targetRealReg) - { - if (targetRealReg->getState() == TR::RealRegister::Locked) - { - targetUpgradable = false; - } - } - } - - if (srcReg && srcReg->isHighWordUpgradable()) - { - srcUpgradable = true; - - TR::RealRegister * srcRealReg = srcReg->getAssignedRealRegister();; - if (srcRealReg) - { - if (srcRealReg->getState() == TR::RealRegister::Locked) - { - srcUpgradable = false; - } - } - } - - if (targetUpgradable) - { - switch (s390Inst->getOpCodeValue()) - { - case TR::InstOpCode::AR: - if (srcUpgradable) - { - newOpCode = TR::InstOpCode::AHHHR; - } - else - { - newOpCode = TR::InstOpCode::AHHLR; - } - newInst = generateRRRInstruction(self(), newOpCode, node, targetReg, targetReg, srcReg, inst->getPrev()); - srcReg->decTotalUseCount(); - targetReg->decTotalUseCount(); - targetReg->incFutureUseCount(); - break; - case TR::InstOpCode::ALR: - if (srcUpgradable) - { - newOpCode = TR::InstOpCode::ALHHHR; - } - else - { - newOpCode = TR::InstOpCode::ALHHLR; - } - newInst = generateRRRInstruction(self(), newOpCode, node, targetReg, targetReg, srcReg, inst->getPrev()); - targetReg->decTotalUseCount(); - srcReg->decTotalUseCount(); - targetReg->incFutureUseCount(); - break; - case TR::InstOpCode::AHI: - case TR::InstOpCode::AFI: - newOpCode = TR::InstOpCode::AIH; - immValue = ((TR::S390RIInstruction*)inst)->getSourceImmediate(); - // signed extend 32-bit - newInst = generateRILInstruction(self(), newOpCode, node, targetReg, immValue,inst->getPrev()); - targetReg->decTotalUseCount(); - break; - case TR::InstOpCode::BRCT: - newOpCode = TR::InstOpCode::BRCTH; - //BRCTH has extended immediate - newInst= generateS390BranchInstruction(self(), TR::InstOpCode::BRCTH, node, targetReg, ((TR::S390LabeledInstruction*)inst)->getLabelSymbol(), inst->getPrev()); - targetReg->decTotalUseCount(); - break; - case TR::InstOpCode::CR: - if (srcUpgradable) - { - newOpCode = TR::InstOpCode::CHHR; - } - else - { - newOpCode = TR::InstOpCode::CHLR; - } - newInst = generateRRInstruction(self(), newOpCode, node, targetReg, srcReg, inst->getPrev()); - targetReg->decTotalUseCount(); - srcReg->decTotalUseCount(); - break; - case TR::InstOpCode::CLR: - if (srcUpgradable) - { - newOpCode = TR::InstOpCode::CLHHR; - } - else - { - newOpCode = TR::InstOpCode::CLHLR; - } - newInst = generateRRInstruction(self(), newOpCode, node, targetReg, srcReg, inst->getPrev()); - targetReg->decTotalUseCount(); - srcReg->decTotalUseCount(); - break; - case TR::InstOpCode::C: - case TR::InstOpCode::CY: - mr = ((TR::S390RXInstruction *)inst)->getMemoryReference(); - mr->resetMemRefUsedBefore(); - // mr re-use? - newOpCode = TR::InstOpCode::CHF; - newInst = generateRXInstruction(self(), newOpCode, node, targetReg, mr, inst->getPrev()); - targetReg->decTotalUseCount(); - // mem ref need to dec ref count too - if (mr->getBaseRegister()) - { - mr->getBaseRegister()->decTotalUseCount(); - } - if (mr->getIndexRegister()) - { - mr->getIndexRegister()->decTotalUseCount(); - } - break; - case TR::InstOpCode::CL: - case TR::InstOpCode::CLY: - mr = ((TR::S390RXInstruction *)inst)->getMemoryReference(); - mr->resetMemRefUsedBefore(); - // mr re-use? - newOpCode = TR::InstOpCode::CLHF; - newInst = generateRXInstruction(self(), newOpCode, node, targetReg, mr, inst->getPrev()); - targetReg->decTotalUseCount(); - // mem ref need to dec ref count too - if (mr->getBaseRegister()) - { - mr->getBaseRegister()->decTotalUseCount(); - } - if (mr->getIndexRegister()) - { - mr->getIndexRegister()->decTotalUseCount(); - } - break; - case TR::InstOpCode::CFI: - immValue = ((TR::S390RILInstruction*)inst)->getSourceImmediate(); - newOpCode = TR::InstOpCode::CIH; - newInst = generateRILInstruction(self(), newOpCode, node, targetReg, immValue, inst->getPrev()); - targetReg->decTotalUseCount(); - break; - case TR::InstOpCode::CLFI: - immValue = ((TR::S390RILInstruction*)inst)->getSourceImmediate(); - newOpCode = TR::InstOpCode::CLIH; - newInst = generateRILInstruction(self(), newOpCode, node, targetReg, immValue, inst->getPrev()); - targetReg->decTotalUseCount(); - break; - case TR::InstOpCode::LB: - newOpCode = TR::InstOpCode::LBH; - mr = ((TR::S390RXInstruction *)inst)->getMemoryReference(); - mr->resetMemRefUsedBefore(); - // mr re-use? - newInst = generateRXInstruction(self(), newOpCode, node, targetReg, mr, inst->getPrev()); - targetReg->decTotalUseCount(); - // mem ref need to dec ref count too - if (mr->getBaseRegister()) - { - mr->getBaseRegister()->decTotalUseCount(); - } - if (mr->getIndexRegister()) - { - mr->getIndexRegister()->decTotalUseCount(); - } - break; - case TR::InstOpCode::LH: - case TR::InstOpCode::LHY: - newOpCode = TR::InstOpCode::LHH; - mr = ((TR::S390RXInstruction *)inst)->getMemoryReference(); - mr->resetMemRefUsedBefore(); - // mr re-use? - newInst = generateRXInstruction(self(), newOpCode, node, targetReg, mr, inst->getPrev()); - targetReg->decTotalUseCount(); - // mem ref need to dec ref count too - if (mr->getBaseRegister()) - { - mr->getBaseRegister()->decTotalUseCount(); - } - if (mr->getIndexRegister()) - { - mr->getIndexRegister()->decTotalUseCount(); - } - break; - case TR::InstOpCode::L: - case TR::InstOpCode::LY: - newOpCode = TR::InstOpCode::LFH; - mr = ((TR::S390RXInstruction *)inst)->getMemoryReference(); - mr->resetMemRefUsedBefore(); - // mr re-use? - newInst = generateRXInstruction(self(), newOpCode, node, targetReg, mr, inst->getPrev()); - targetReg->decTotalUseCount(); - // mem ref need to dec ref count too - if (mr->getBaseRegister()) - { - mr->getBaseRegister()->decTotalUseCount(); - } - if (mr->getIndexRegister()) - { - mr->getIndexRegister()->decTotalUseCount(); - } - break; - case TR::InstOpCode::LAT: - newOpCode = TR::InstOpCode::LFHAT; - mr = ((TR::S390RXInstruction *)inst)->getMemoryReference(); - mr->resetMemRefUsedBefore(); - // mr re-use? - newInst = generateRXInstruction(self(), newOpCode, node, targetReg, mr, inst->getPrev()); - targetReg->decTotalUseCount(); - // mem ref need to dec ref count too - if (mr->getBaseRegister()) - { - mr->getBaseRegister()->decTotalUseCount(); - } - if (mr->getIndexRegister()) - { - mr->getIndexRegister()->decTotalUseCount(); - } - break; - case TR::InstOpCode::LLC: - newOpCode = TR::InstOpCode::LLCH; - mr = ((TR::S390RXInstruction *)inst)->getMemoryReference(); - mr->resetMemRefUsedBefore(); - // mr re-use? - newInst = generateRXInstruction(self(), newOpCode, node, targetReg, mr, inst->getPrev()); - targetReg->decTotalUseCount(); - // mem ref need to dec ref count too - if (mr->getBaseRegister()) - { - mr->getBaseRegister()->decTotalUseCount(); - } - if (mr->getIndexRegister()) - { - mr->getIndexRegister()->decTotalUseCount(); - } - break; - case TR::InstOpCode::LLH: - newOpCode = TR::InstOpCode::LLHH; - mr = ((TR::S390RXInstruction *)inst)->getMemoryReference(); - mr->resetMemRefUsedBefore(); - // mr re-use? - newInst = generateRXInstruction(self(), newOpCode, node, targetReg, mr, inst->getPrev()); - targetReg->decTotalUseCount(); - // mem ref need to dec ref count too - if (mr->getBaseRegister()) - { - mr->getBaseRegister()->decTotalUseCount(); - } - if (mr->getIndexRegister()) - { - mr->getIndexRegister()->decTotalUseCount(); - } - break; - case TR::InstOpCode::LR: - if (srcUpgradable) - { - newOpCode = TR::InstOpCode::LHHR; - } - else - { - newOpCode = TR::InstOpCode::LHLR; - } - newInst = generateExtendedHighWordInstruction(node, self(), newOpCode, targetReg, srcReg, 0, inst->getPrev()); - targetReg->decTotalUseCount(); - srcReg->decTotalUseCount(); - break; - case TR::InstOpCode::LLCR: - if (srcUpgradable) - { - newOpCode = TR::InstOpCode::LLCHHR; - srcReg->decTotalUseCount(); - } - else - { - newOpCode = TR::InstOpCode::LLCHLR; - } - newInst = generateExtendedHighWordInstruction(node, self(), newOpCode, targetReg, srcReg, 0, inst->getPrev()); - targetReg->decTotalUseCount(); - srcReg->decTotalUseCount(); - break; - case TR::InstOpCode::LLHR: - if (srcUpgradable) - { - newOpCode = TR::InstOpCode::LLHHHR; - } - else - { - newOpCode = TR::InstOpCode::LLHHLR; - } - newInst = generateExtendedHighWordInstruction(node, self(), newOpCode, targetReg, srcReg, 0, inst->getPrev()); - targetReg->decTotalUseCount(); - srcReg->decTotalUseCount(); - break; - case TR::InstOpCode::LHI: - //IIHF need to be sign-extend - newOpCode = TR::InstOpCode::IIHF; - immValue = ((TR::S390RIInstruction*)inst)->getSourceImmediate(); - newInst = generateRILInstruction(self(), newOpCode, node, targetReg, immValue, inst->getPrev()); - targetReg->decTotalUseCount(); - break; - /*-------- these guys are cracked instructions, not worth it - case TR::InstOpCode::NR: - if (srcUpgradable) - { - newOpCode = TR::InstOpCode::NHHR; - } - else - { - newOpCode = TR::InstOpCode::NHLR; - } - newInst = generateExtendedHighWordInstruction(node, self(), newOpCode, targetReg, srcReg, 0, inst->getPrev()); - targetReg->decTotalUseCount(); - srcReg->decTotalUseCount(); - break; - case TR::InstOpCode::OR: - if (srcUpgradable) - { - newOpCode = TR::InstOpCode::OHHR; - } - else - { - newOpCode = TR::InstOpCode::OHLR; - } - newInst = generateExtendedHighWordInstruction(node, self(), newOpCode, targetReg, srcReg, 0, inst->getPrev()); - targetReg->decTotalUseCount(); - srcReg->decTotalUseCount(); - break; - case TR::InstOpCode::XR: - if (srcUpgradable) - { - newOpCode = TR::InstOpCode::XHHR; - } - else - { - newOpCode = TR::InstOpCode::XHLR; - } - newInst = generateExtendedHighWordInstruction(node, self(), newOpCode, targetReg, srcReg, 0, inst->getPrev()); - targetReg->decTotalUseCount(); - srcReg->decTotalUseCount(); - break; - --------------*/ - case TR::InstOpCode::ST: - case TR::InstOpCode::STY: - newOpCode = TR::InstOpCode::STFH; - mr = ((TR::S390RXInstruction *)inst)->getMemoryReference(); - mr->resetMemRefUsedBefore(); - // mr re-use? - newInst = generateRXInstruction(self(), newOpCode, node, targetReg, mr, inst->getPrev()); - targetReg->decTotalUseCount(); - // mem ref need to dec ref count too - if (mr->getBaseRegister()) - { - mr->getBaseRegister()->decTotalUseCount(); - } - if (mr->getIndexRegister()) - { - mr->getIndexRegister()->decTotalUseCount(); - } - break; - case TR::InstOpCode::STC: - case TR::InstOpCode::STCY: - newOpCode = TR::InstOpCode::STCH; - mr = ((TR::S390RXInstruction *)inst)->getMemoryReference(); - mr->resetMemRefUsedBefore(); - // mr re-use? - newInst = generateRXInstruction(self(), newOpCode, node, targetReg, mr, inst->getPrev()); - targetReg->decTotalUseCount(); - // mem ref need to dec ref count too - if (mr->getBaseRegister()) - { - mr->getBaseRegister()->decTotalUseCount(); - } - if (mr->getIndexRegister()) - { - mr->getIndexRegister()->decTotalUseCount(); - } - break; - case TR::InstOpCode::STH: - case TR::InstOpCode::STHY: - newOpCode = TR::InstOpCode::STHH; - mr = ((TR::S390RXInstruction *)inst)->getMemoryReference(); - mr->resetMemRefUsedBefore(); - // mr re-use? - newInst = generateRXInstruction(self(), newOpCode, node, targetReg, mr, inst->getPrev()); - targetReg->decTotalUseCount(); - // mem ref need to dec ref count too - if (mr->getBaseRegister()) - { - mr->getBaseRegister()->decTotalUseCount(); - } - if (mr->getIndexRegister()) - { - mr->getIndexRegister()->decTotalUseCount(); - } - break; - case TR::InstOpCode::SR: - if (srcUpgradable) - { - newOpCode = TR::InstOpCode::SHHHR; - } - else - { - newOpCode = TR::InstOpCode::SHHLR; - } - newInst = generateRRRInstruction(self(), newOpCode, node, targetReg, targetReg, srcReg, inst->getPrev()); - targetReg->decTotalUseCount(); - srcReg->decTotalUseCount(); - targetReg->incFutureUseCount(); - break; - case TR::InstOpCode::SLR: - if (srcUpgradable) - { - newOpCode = TR::InstOpCode::SLHHHR; - } - else - { - newOpCode = TR::InstOpCode::SLHHLR; - } - newInst = generateRRRInstruction(self(), newOpCode, node, targetReg, targetReg, srcReg, inst->getPrev()); - targetReg->decTotalUseCount(); - srcReg->decTotalUseCount(); - targetReg->incFutureUseCount(); - break; - case TR::InstOpCode::SLFI: - //ALSIH - newOpCode = TR::InstOpCode::ALSIH; - immValue = ((TR::S390RILInstruction*)inst)->getSourceImmediate(); - newInst = generateRILInstruction(self(), newOpCode, node, targetReg, -immValue, inst->getPrev()); - targetReg->decTotalUseCount(); - break; - } - } - else if (srcUpgradable) - { - switch (s390Inst->getOpCodeValue()) - { - case TR::InstOpCode::LR: - newOpCode = TR::InstOpCode::LLHFR; - newInst = generateExtendedHighWordInstruction(node, self(), newOpCode, targetReg, srcReg, 0, inst->getPrev()); - targetReg->decTotalUseCount(); - srcReg->decTotalUseCount(); - break; - case TR::InstOpCode::LLCR: - newOpCode = TR::InstOpCode::LLCLHR; - newInst = generateExtendedHighWordInstruction(node, self(), newOpCode, targetReg, srcReg, 0, inst->getPrev()); - targetReg->decTotalUseCount(); - srcReg->decTotalUseCount(); - break; - case TR::InstOpCode::LLHR: - newOpCode = TR::InstOpCode::LLHLHR; - newInst = generateExtendedHighWordInstruction(node, self(), newOpCode, targetReg, srcReg, 0, inst->getPrev()); - targetReg->decTotalUseCount(); - srcReg->decTotalUseCount(); - break; - /*---- these guys are cracked instructions, not worth it - case TR::InstOpCode::NR: - newOpCode = TR::InstOpCode::NLHR; - newInst = generateExtendedHighWordInstruction(node, self(), newOpCode, targetReg, srcReg, 0, inst->getPrev()); - targetReg->decTotalUseCount(); - srcReg->decTotalUseCount(); - break; - case TR::InstOpCode::OR: - newOpCode = TR::InstOpCode::OLHR; - newInst = generateExtendedHighWordInstruction(node, self(), newOpCode, targetReg, srcReg, 0, inst->getPrev()); - targetReg->decTotalUseCount(); - srcReg->decTotalUseCount(); - break; - case TR::InstOpCode::XR: - newOpCode = TR::InstOpCode::XLHR; - newInst = generateExtendedHighWordInstruction(node, self(), newOpCode, targetReg, srcReg, 0, inst->getPrev()); - targetReg->decTotalUseCount(); - srcReg->decTotalUseCount(); - break; - ----*/ - } - } - - if (newInst) - { - // make sure the registers will keep on getting upgraded for other instructions - if (targetUpgradable) - targetReg->setIsNotHighWordUpgradable(false); - if (srcUpgradable) - srcReg->setIsNotHighWordUpgradable(false); - - TR::Instruction * s390NewInst = newInst; - //traceMsg(comp(), "\n Old inst: %p, new inst : %p", inst, newInst); - s390NewInst->setBlockIndex(s390Inst->getBlockIndex()); - if (s390Inst->getDependencyConditions()) - s390NewInst->setDependencyConditionsNoBookKeeping(s390Inst->getDependencyConditions()); - if (s390Inst->throwsImplicitNullPointerException()) - s390NewInst->setThrowsImplicitNullPointerException(); - if (s390Inst->throwsImplicitException()) - s390NewInst->setThrowsImplicitException(); - if (s390Inst->isOutOfLineEX()) - s390NewInst->setOutOfLineEX(); - if (s390Inst->getIndex()) - s390NewInst->setIndex(s390Inst->getIndex()); - if (s390Inst->getGCMap()) - s390NewInst->setGCMap(s390Inst->getGCMap()); - if (s390Inst->needsGCMap()) - s390NewInst->setNeedsGCMap(s390Inst->getGCRegisterMask()); - - self()->replaceInst(inst, newInst); - - TR::DebugCounter::incStaticDebugCounter(self()->comp(), "hpr/upgrade"); - - if (srcUpgradable) - { - if (self()->machine()->findBestFreeRegister(inst, TR_GPR, srcReg) != NULL) - { - TR::DebugCounter::incStaticDebugCounter(self()->comp(), "hpr/upgrade-found-free-source-GPR"); - } - } - - if (targetUpgradable) - { - if (self()->machine()->findBestFreeRegister(inst, TR_GPR, targetReg) != NULL) - { - TR::DebugCounter::incStaticDebugCounter(self()->comp(), "hpr/upgrade-found-free-target-GPR"); - } - } - - if (self()->getDebug()) - self()->getDebug()->addInstructionComment(s390NewInst, "HPR Upgraded"); - - return newInst; - } - - return NULL; - } - static TR::Instruction *skipInternalControlFlow(TR::Instruction *insertInstr) { int32_t nestingDepth=1; @@ -2624,14 +2071,6 @@ OMR::Z::CodeGenerator::doRegisterAssignment(TR_RegisterKinds kindsToAssign) self()->tracePreRAInstruction(instructionCursor); - if (self()->supportsHighWordFacility() && !self()->comp()->getOption(TR_DisableHPRUpgrade)) - { - TR::Instruction * newInst = self()->upgradeToHPRInstruction(instructionCursor); - if (newInst) - { - instructionCursor = newInst; - } - } if (self()->supportsHighWordFacility()) self()->setAvailableHPRSpillMask(0xffff0000); diff --git a/compiler/z/codegen/OMRCodeGenerator.hpp b/compiler/z/codegen/OMRCodeGenerator.hpp index e8e4f6ca432..299074e0192 100644 --- a/compiler/z/codegen/OMRCodeGenerator.hpp +++ b/compiler/z/codegen/OMRCodeGenerator.hpp @@ -479,8 +479,6 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator // Query to codegen to know if regs are available or not bool isLitPoolFreeForAssignment(); - // zGryphon HPR - TR::Instruction * upgradeToHPRInstruction(TR::Instruction * inst); // REG ASSOCIATION // bool enableRegisterAssociations(); diff --git a/compiler/z/codegen/OMRInstruction.cpp b/compiler/z/codegen/OMRInstruction.cpp index 28cc3257b1a..0db0c953fd4 100644 --- a/compiler/z/codegen/OMRInstruction.cpp +++ b/compiler/z/codegen/OMRInstruction.cpp @@ -1011,22 +1011,6 @@ OMR::Z::Instruction::useSourceRegister(TR::Register * reg) } } - // mark used bit for HW/LW virtual regs - if (self()->cg()->supportsHighWordFacility()) - { - if (!self()->isHPRUpgradable(_targetRegSize+_sourceRegSize-1)) - { - reg->setIsNotHighWordUpgradable(true); - } - - if (reg->getRegisterPair()) - { - reg->setIsNotHighWordUpgradable(true); - reg->getLowOrder()->setIsNotHighWordUpgradable(true); - reg->getHighOrder()->setIsNotHighWordUpgradable(true); - } - } - return _sourceRegSize-1; // index into the source register array } @@ -1154,23 +1138,7 @@ OMR::Z::Instruction::useTargetRegister(TR::Register* reg) reg->getHighOrder()->setIs64BitReg(true); } } - - // mark used bit for HW/LW virtual regs - if (self()->cg()->supportsHighWordFacility()) - { - if (!self()->isHPRUpgradable(_targetRegSize+_sourceRegSize-1)) - { - reg->setIsNotHighWordUpgradable(true); - } - - if (reg->getRegisterPair()) - { - reg->setIsNotHighWordUpgradable(true); - reg->getLowOrder()->setIsNotHighWordUpgradable(true); - reg->getHighOrder()->setIsNotHighWordUpgradable(true); - } - } - + return _targetRegSize-1; // index into the target register array } diff --git a/compiler/z/codegen/OMRRegister.cpp b/compiler/z/codegen/OMRRegister.cpp index 3aadc29ec91..0005755dbb1 100644 --- a/compiler/z/codegen/OMRRegister.cpp +++ b/compiler/z/codegen/OMRRegister.cpp @@ -91,18 +91,6 @@ OMR::Z::Register::assignToGPR() return (!(self()->is64BitReg()) && !_flags.testAny(AssignToHPR)); } -bool -OMR::Z::Register::isHighWordUpgradable() - { - return (!_flags.testAny(IsNotHighWordUpgradable) && - !self()->isUsedInMemRef() && - !self()->containsCollectedReference() && - !self()->containsInternalPointer() && - !self()->getRegisterPair() && - (self()->getKind() == TR_GPR) && - !self()->is64BitReg()); - } - ncount_t OMR::Z::Register::decFutureUseCount(ncount_t fuc) { diff --git a/compiler/z/codegen/OMRRegister.hpp b/compiler/z/codegen/OMRRegister.hpp index 7c9647a615a..97fb67ce218 100644 --- a/compiler/z/codegen/OMRRegister.hpp +++ b/compiler/z/codegen/OMRRegister.hpp @@ -92,9 +92,6 @@ class OMR_EXTENSIBLE Register: public OMR::Register void setAssignToHPR(bool b = true) {_flags.set(AssignToHPR, b);} bool assignToGPR(); - bool isHighWordUpgradable(); - void setIsNotHighWordUpgradable(bool b = true){_flags.set(IsNotHighWordUpgradable, b);} - bool isSpilledToHPR() {return (_flags.testAny(SpilledToHPR));} void setSpilledToHPR(bool b = true) {_flags.set(SpilledToHPR, b);} @@ -140,7 +137,6 @@ class OMR_EXTENSIBLE Register: public OMR::Register IsUsedInMemRef = 0x0800, // 390 cannot associate GPR0 to regs used in memrefs Is64Bit = 0x0002, // 390 flag indicates that this Register contained a 64-bit value AssignToHPR = 0x0004, // 390 flag indicates that this virtual register needs to be assigned to an HPR - IsNotHighWordUpgradable = 0x2000, // 390 flag indicates that this Reg can be upgraded to use HPR SpilledToHPR = 0x4000, // 390 flag indicates that this virtual register is spilled to DependencySet = 0x0200, // 390 flag, post dependancy was assigned diff --git a/compiler/z/codegen/OMRRegisterDependency.cpp b/compiler/z/codegen/OMRRegisterDependency.cpp index 3393f69212f..99ec7450efb 100644 --- a/compiler/z/codegen/OMRRegisterDependency.cpp +++ b/compiler/z/codegen/OMRRegisterDependency.cpp @@ -681,9 +681,6 @@ TR_S390RegisterDependencyGroup::checkRegisterPairSufficiencyAndHPRAssignment(TR: if (realRegI == TR::RealRegister::EvenOddPair) numReqPairs++; - // Set HPR or 64-bit register assignment flags - virtRegI->setIsNotHighWordUpgradable(true); - if (virtRegI && virtRegI->getKind() != TR_FPR && virtRegI->getKind() != TR_VRF) diff --git a/compiler/z/codegen/OMRRegisterDependency.hpp b/compiler/z/codegen/OMRRegisterDependency.hpp index 1851e16a3ad..010e567efa8 100644 --- a/compiler/z/codegen/OMRRegisterDependency.hpp +++ b/compiler/z/codegen/OMRRegisterDependency.hpp @@ -118,8 +118,6 @@ class TR_S390RegisterDependencyGroup _dependencies[index].assignFlags(flag); _dependencies[index].setRealRegister(rr); if (vr) vr->setDependencySet(true); - if (vr != NULL) - vr->setIsNotHighWordUpgradable(true); } TR::Register *searchForRegister(TR::Register* vr, uint8_t flag, uint32_t numberOfRegisters, TR::CodeGenerator *cg) diff --git a/compiler/z/codegen/OMRRegisterPair.cpp b/compiler/z/codegen/OMRRegisterPair.cpp deleted file mode 100644 index 5dd9b2306cb..00000000000 --- a/compiler/z/codegen/OMRRegisterPair.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2016 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 - * distribution and is available at http://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] http://openjdk.java.net/legal/assembly-exception.html - * - * 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-exception - *******************************************************************************/ - -//On zOS XLC linker can't handle files with same name at link time -//This workaround with pragma is needed. What this does is essentially -//give a different name to the codesection (csect) for this file. So it -//doesn't conflict with another file with same name. -#pragma csect(CODE,"OMRZRegPairBase#C") -#pragma csect(STATIC,"OMRZRegPairBase#S") -#pragma csect(TEST,"OMRZRegPairBase#T") - -#include "z/codegen/OMRRegisterPair.hpp" - -#include "codegen/CodeGenerator.hpp" -#include "codegen/LiveRegister.hpp" -#include "codegen/Register.hpp" -#include "codegen/RegisterPair.hpp" -#include "il/AliasSetInterface.hpp" -#include "il/SymbolReference.hpp" -#include "optimizer/Structure.hpp" - -OMR::Z::RegisterPair::RegisterPair(TR::Register *lo, TR::Register *ho): - OMR::RegisterPair(lo, ho) - { - // highword RA HPR upgrade - if (lo) - lo->setIsNotHighWordUpgradable(true); - if (ho) - ho->setIsNotHighWordUpgradable(true); - } - - -TR::Register * -OMR::Z::RegisterPair::setLowOrder(TR::Register *lo, TR::CodeGenerator *codeGen) - { - // highword RA HPR upgrade - if (lo) lo->setIsNotHighWordUpgradable(true); - - // call base class implementation - return OMR::RegisterPair::setLowOrder(lo, codeGen); - } - - -TR::Register * -OMR::Z::RegisterPair::setHighOrder(TR::Register *ho, TR::CodeGenerator *codeGen) - { - // highword RA HPR upgrade - if (ho) ho->setIsNotHighWordUpgradable(true); - - // call base class implementation - return OMR::RegisterPair::setHighOrder(ho, codeGen); - } diff --git a/compiler/z/codegen/OMRRegisterPair.hpp b/compiler/z/codegen/OMRRegisterPair.hpp deleted file mode 100644 index 24c701a9dc2..00000000000 --- a/compiler/z/codegen/OMRRegisterPair.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2016 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 - * distribution and is available at http://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] http://openjdk.java.net/legal/assembly-exception.html - * - * 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-exception - *******************************************************************************/ - -#ifndef OMR_Z_REGISTER_PAIR_INCL -#define OMR_Z_REGISTER_PAIR_INCL - -/* - * The following #define and typedef must appear before any #includes in this file - */ -#ifndef OMR_REGISTER_PAIR_CONNECTOR -#define OMR_REGISTER_PAIR_CONNECTOR - namespace OMR { namespace Z { class RegisterPair; } } - namespace OMR { typedef OMR::Z::RegisterPair RegisterPairConnector; } -#else - #error OMR::Z::RegisterPair expected to be a primary connector, but a OMR connector is already defined -#endif - - -#include "compiler/codegen/OMRRegisterPair.hpp" - -namespace OMR -{ - -namespace Z -{ - -class OMR_EXTENSIBLE RegisterPair: public OMR::RegisterPair - { - protected: - - RegisterPair() {} - RegisterPair(TR_RegisterKinds rk): OMR::RegisterPair(rk) {} - RegisterPair(TR::Register *lo, TR::Register *ho); - - public: - - TR::Register * setLowOrder(TR::Register *lo, TR::CodeGenerator *codeGen); - TR::Register * setHighOrder(TR::Register *ho, TR::CodeGenerator *codeGen); - - - }; - -} - -} - -#endif diff --git a/fvtest/compilertest/build/IWYU_Mappings.imp b/fvtest/compilertest/build/IWYU_Mappings.imp index e12e714a59e..859e7d92a51 100644 --- a/fvtest/compilertest/build/IWYU_Mappings.imp +++ b/fvtest/compilertest/build/IWYU_Mappings.imp @@ -121,7 +121,6 @@ { include: [ "\"z/codegen/OMRRegisterIterator.hpp\"", private, "\"codegen/RegisterIterator.hpp\"", public ] }, { include: [ "\"codegen/OMRRegisterPair.hpp\"", private, "\"codegen/RegisterPair.hpp\"", public ] }, - { include: [ "\"z/codegen/OMRRegisterPair.hpp\"", private, "\"codegen/RegisterPair.hpp\"", public ] }, { include: [ "\"codegen/OMRSnippet.hpp\"", private, "\"codegen/Snippet.hpp\"", public ] }, { include: [ "\"arm/codegen/OMRSnippet.hpp\"", private, "\"codegen/Snippet.hpp\"", public ] }, diff --git a/fvtest/compilertest/build/files/target/z.mk b/fvtest/compilertest/build/files/target/z.mk index a242434d745..3c1d58ffcf0 100644 --- a/fvtest/compilertest/build/files/target/z.mk +++ b/fvtest/compilertest/build/files/target/z.mk @@ -50,7 +50,6 @@ JIT_PRODUCT_BACKEND_SOURCES+=\ $(JIT_OMR_DIRTY_DIR)/z/codegen/InstOpCode.cpp \ $(JIT_OMR_DIRTY_DIR)/z/codegen/OMRRegister.cpp \ $(JIT_OMR_DIRTY_DIR)/z/codegen/OMRRealRegister.cpp \ - $(JIT_OMR_DIRTY_DIR)/z/codegen/OMRRegisterPair.cpp \ $(JIT_OMR_DIRTY_DIR)/z/codegen/OMRCodeGenPhase.cpp \ $(JIT_OMR_DIRTY_DIR)/z/codegen/OMRCodeGenerator.cpp From 0cfbe8cf61907489723009508efd13d1e00393d8 Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Thu, 28 Feb 2019 09:45:44 -0500 Subject: [PATCH 03/23] Deprecate HPR spilling This also effectively deprecates all HPR support and opens up opportunity to clean up and fold a lot of code throughout the codebase. Signed-off-by: Filip Jeremic --- compiler/z/codegen/OMRMachine.cpp | 343 ++---------------------------- 1 file changed, 22 insertions(+), 321 deletions(-) diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index fc7f644be79..08bccd8b839 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -492,45 +492,6 @@ OMR::Z::Machine::registerExchange(TR::CodeGenerator* cg, return currentInstruction; } -/** - * Check if a given virtual register lives across any OOL - * @return true if this register interference with an OOL - */ -static bool -checkOOLInterference(TR::Instruction * currentInstruction, TR::Register * virtReg) - { - TR::Instruction * cursor = currentInstruction; - - if (cursor->cg()->isOutOfLineColdPath() || cursor->cg()->isOutOfLineHotPath()) - return true; - - // walk the live range of virtReg - while (cursor != virtReg->getStartOfRange()) - { - // look for OOL return label - if (cursor->isLabel() && - toS390LabelInstruction(cursor)->getLabelSymbol()->isEndOfColdInstructionStream()) - { - cursor->cg()->traceRegisterAssignment("Found %R used in OOL [0x%p]: will not spill to HPR", virtReg, cursor); - return true; - } - - // This shouldn't be necessary, however if for any reason startOfRange - // is not setup properly, we do not want to end up in an infinite loop - if (cursor->getNode() != NULL && - cursor->getNode()->getOpCodeValue() == TR::BBStart && - !cursor->getNode()->getBlock()->isExtensionOfPreviousBlock()) - { - // we reached a new BB, virtRegs do not live across BB - return false; - } - - cursor = cursor->getPrev(); - } - - return false; - } - static bool boundNext(TR::Instruction * currentInstruction, int32_t realNum, TR::Register * virtReg) { @@ -2131,9 +2092,6 @@ OMR::Z::Machine::freeBestRegisterPair(TR::RealRegister ** firstReg, TR::RealRegi TR_Debug * debugObj = self()->cg()->getDebug(); - bool enableHighWordRA = self()->cg()->supportsHighWordFacility() && - rk != TR_FPR && rk != TR_VRF; - // Look at all reg pairs (starting with an even reg) for (int32_t i = TR::RealRegister::FirstGPR; i <= TR::RealRegister::LastAssignableGPR; i += 2) { @@ -2271,18 +2229,6 @@ OMR::Z::Machine::freeBestRegisterPair(TR::RealRegister ** firstReg, TR::RealRegi } } } - else - { - // TODO: This is a little too conservative. This API needs to be taught whether the register pair requires 64-bit - // registers or not and if and only if we require 64-bit registers do we need to evict the highword register. - if (enableHighWordRA && bestCandidateLow->getHighWordRegister()->getAssignedRegister() != NULL) - { - // if the candidate is assigned on both GPR and HPR, need to spill HPR - self()->cg()->traceRegisterAssignment("spilling HPR %R for reg pair low", - bestCandidateLow->getHighWordRegister()->getAssignedRegister()); - currInst = self()->freeHighWordRegister(currInst, bestCandidateLow->getHighWordRegister()); - } - } if (bestVirtCandidateHigh != NULL) { @@ -2370,18 +2316,6 @@ OMR::Z::Machine::freeBestRegisterPair(TR::RealRegister ** firstReg, TR::RealRegi } } } - else - { - // TODO: This is a little too conservative. This API needs to be taught whether the register pair requires 64-bit - // registers or not and if and only if we require 64-bit registers do we need to evict the highword register. - if (enableHighWordRA && bestCandidateHigh->getHighWordRegister()->getAssignedRegister() != NULL) - { - // if the candidate is assigned on both GPR and HPR, need to spill HPR - self()->cg()->traceRegisterAssignment("spilling HPR %R for reg pair high", - bestCandidateHigh->getHighWordRegister()->getAssignedRegister()); - currInst = self()->freeHighWordRegister(currInst, bestCandidateHigh->getHighWordRegister()); - } - } // Mark associated real regs as free @@ -3166,9 +3100,6 @@ OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Regi TR::Machine *machine = self()->cg()->machine(); bool useGPR0 = (virtReg == NULL) ? false : (virtReg->isUsedInMemRef() == false); - bool enableHighWordRA = self()->cg()->supportsHighWordFacility() && - rk != TR_FPR && rk != TR_VRF; - switch (rk) { case TR_GPR: @@ -3415,18 +3346,7 @@ OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Regi cursor = cursor->getPrev(); } - TR::RealRegister * best = NULL; - - if (candidates[0]->getAssignedRegister()) - { - best = toRealRegister(candidates[0]->getAssignedRegister()); - } - else - { - TR_ASSERT_FATAL( enableHighWordRA, "freeBestRegister:a virtual reg is assigned to NULL?"); - // if the best candidate is a previously spilled HPR - best = toRealRegister(self()->findVirtRegInHighWordRegister(candidates[0])); - } + TR::RealRegister * best = toRealRegister(candidates[0]->getAssignedRegister()); // Shortcut the selection when a virtReg is specified, and it is already assigned a real, we spill // that real @@ -3592,43 +3512,8 @@ OMR::Z::Machine::spillRegister(TR::Instruction * currentInstruction, TR::Registe TR::Instruction * cursor = NULL; TR::RealRegister * best = NULL; TR_Debug * debugObj = self()->cg()->getDebug(); - - // Highword RA flags - // check: what if virtReg is actually a real Reg?? - bool enableHighWordRA = self()->cg()->supportsHighWordFacility() && - rk != TR_FPR && rk != TR_VRF; - TR::RealRegister * freeHighWordReg = NULL; - bool alreadySpilledToHPR = false; - bool alreadySpilledToHPRCollectible = false; - - // If virtReg was already spilled into an HPR, need to find which one it is - if (enableHighWordRA && virtReg->getAssignedRegister() == NULL) - { - best = self()->findVirtRegInHighWordRegister(virtReg); - // do not attempt HPR spill anymore - alreadySpilledToHPR = true; - if (virtReg->containsCollectedReference()) - { - // in this case, we must either find another free HPR for virtReg or - // decompress this virtReg and spill it onto the stack - alreadySpilledToHPRCollectible = true; - } - TR_ASSERT(best != NULL, "HW RA: spillRegister cannot find real target reg\n"); - } - else - { - best = toRealRegister(virtReg->getAssignedRegister()); - if (enableHighWordRA && best->isHighWordRegister()) - { - alreadySpilledToHPR = true; - if (virtReg->containsCollectedReference()) - { - // in this case, we must either find another free HPR for virtReg or - // decompress this virtReg and spill it onto the stack - alreadySpilledToHPRCollectible = true; - } - } - } + + best = toRealRegister(virtReg->getAssignedRegister()); if (virtReg->containsInternalPointer()) { @@ -3650,102 +3535,6 @@ OMR::Z::Machine::spillRegister(TR::Instruction * currentInstruction, TR::Registe self()->cg()->traceRegisterAssignment("%R contains collected", virtReg); } - static char * debugHPR= feGetEnv("TR_debugHPR"); - - bool canSpillPointerToHPR = false; - - if (virtReg->containsCollectedReference() && TR::Compiler->target.is64Bit() && - comp->useCompressedPointers() && TR::Compiler->vm.heapBaseAddress() == 0 && - TR::Compiler->om.compressedReferenceShift() == 0 && !checkOOLInterference(currentInstruction, virtReg)) - { - canSpillPointerToHPR = true; - } - - // try to spill to highword - if (enableHighWordRA && !comp->getOption(TR_DisableHPRSpill) && - ((!virtReg->is64BitReg() && !virtReg->containsCollectedReference()) || canSpillPointerToHPR) && - best->isLowWordRegister() && - !virtReg->containsInternalPointer() && - !self()->cg()->isOutOfLineColdPath()) - { - // try to find a free HW reg - availHighWordRegMap &= self()->cg()->getAvailableHPRSpillMask(); - freeHighWordReg = self()->findBestFreeRegister(currentInstruction, rk, virtReg, availHighWordRegMap, true); - - if (freeHighWordReg) - { - if (debugHPR) - { - printf ("\nHW RA: spilling into HPR "); fflush(stdout); - } - self()->cg()->traceRegisterAssignment("\nHW RA: HW spill: %R(%R) into %R\n", virtReg, best, freeHighWordReg); - - TR::DebugCounter::incStaticDebugCounter(comp, "hpr/spill/HPR/register"); - - // spill to HW - if (alreadySpilledToHPR) - { - cursor = generateExtendedHighWordInstruction(currentNode, self()->cg(), TR::InstOpCode::LHHR, best, freeHighWordReg, 0, currentInstruction); - } - else - { - if (virtReg->containsCollectedReference()) - { - if (debugHPR) - { - printf ("(collected) "); fflush(stdout); - } - uint32_t compressShift = TR::Compiler->om.compressedReferenceShift(); - // need to assert heapbase, offset = 0 - if (compressShift == 0) - { - cursor = generateExtendedHighWordInstruction(currentNode, self()->cg(), TR::InstOpCode::LLHFR, best, freeHighWordReg, 0, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - cursor = generateRILInstruction(self()->cg(), TR::InstOpCode::IIHF, currentNode, best, 0, cursor); - self()->cg()->traceRAInstruction(cursor); - } - else - { - cursor = generateRIEInstruction(self()->cg(), TR::InstOpCode::RISBLG, currentNode, best, freeHighWordReg, 0, 31+0x80-compressShift, 32+compressShift, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - cursor = generateRIEInstruction(self()->cg(), TR::InstOpCode::RISBHG, currentNode, best, freeHighWordReg, 32-compressShift, 31+0x80, 32+compressShift, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - } - } - else - { - cursor = generateExtendedHighWordInstruction(currentNode, self()->cg(), TR::InstOpCode::LLHFR, best, freeHighWordReg, 0, currentInstruction); - } - } - if (debugHPR) - { - printf ("in %s ,0x%x, %s", comp->signature(), availHighWordRegMap, comp->getHotnessName(comp->getMethodHotness()));fflush(stdout); - } - - if (debugObj) - { - debugObj->addInstructionComment(cursor, "Load Highword Spill"); - } - self()->cg()->traceRAInstruction(cursor); - - best->setAssignedRegister(NULL); - best->setState(TR::RealRegister::Free); - if (virtReg->containsCollectedReference() && TR::Compiler->target.is64Bit()) - { - best->getHighWordRegister()->setAssignedRegister(NULL); - best->getHighWordRegister()->setState(TR::RealRegister::Free); - } - - freeHighWordReg->setAssignedRegister(virtReg); - freeHighWordReg->setState(TR::RealRegister::Assigned); - - virtReg->setAssignedRegister(NULL); // NULL to force reverseSpillState - virtReg->setSpilledToHPR(true); - return; - } - } - - { location = virtReg->getBackingStorage(); switch (rk) { @@ -3779,31 +3568,6 @@ OMR::Z::Machine::spillRegister(TR::Instruction * currentInstruction, TR::Registe TR::InstOpCode::LG : TR::InstOpCode::L; - if (enableHighWordRA) - { - if (best->isHighWordRegister()) - { - TR::DebugCounter::incStaticDebugCounter(comp, "hpr/spill/HPR/memory"); - opCode = TR::InstOpCode::LFH; - } - else if (best->isLowWordRegister() && best->getHighWordRegister()->getAssignedRegister() != virtReg) - { - TR::DebugCounter::incStaticDebugCounter(comp, "hpr/spill/GPR"); - opCode = TR::InstOpCode::L; - } - else - { - TR::DebugCounter::incStaticDebugCounter(comp, "hpr/spill/GPR"); - } - //TR_ASSERTC( TR::Compiler->target.is64Bit(),comp, "\nallocateSpill has incorrect spill slot size"); - //this assume kicks in for SLLG, MGHI etc on 31bit - if (debugObj) - self()->cg()->traceRegisterAssignment(" HW RA: spilling %R:%R", virtReg, best); - } - else - { - TR::DebugCounter::incStaticDebugCounter(comp, "hpr/spill/GPR"); - } break; case TR_FPR: if (!comp->getOption(TR_DisableOOL) && @@ -3838,21 +3602,11 @@ OMR::Z::Machine::spillRegister(TR::Instruction * currentInstruction, TR::Registe TR::MemoryReference * tempMR = generateS390MemoryReference(currentNode, location->getSymbolReference(), self()->cg()); location->getSymbolReference()->getSymbol()->setSpillTempLoaded(); virtReg->setBackingStorage(location); - if (enableHighWordRA && alreadySpilledToHPRCollectible) - { - // load compressed refs low word into highword - TR::MemoryReference * mr = generateS390MemoryReference(*tempMR, 4, self()->cg()); - cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::LFH, currentNode, best, mr, currentInstruction); - virtReg->setSpilledToHPR(false); - } + + if (opCode == TR::InstOpCode::VL) + cursor = generateVRXInstruction(self()->cg(), opCode, currentNode, best, tempMR, 0, currentInstruction); else - { - if (opCode == TR::InstOpCode::VL) - cursor = generateVRXInstruction(self()->cg(), opCode, currentNode, best, tempMR, 0, currentInstruction); - else - cursor = generateRXInstruction(self()->cg(), opCode, currentNode, best, tempMR, currentInstruction); - } - } + cursor = generateRXInstruction(self()->cg(), opCode, currentNode, best, tempMR, currentInstruction); self()->cg()->traceRAInstruction(cursor); if (debugObj) @@ -3930,7 +3684,6 @@ OMR::Z::Machine::reverseSpillState(TR::Instruction *currentInstruction, TR::InstOpCode::Mnemonic opCode; int32_t dataSize; TR::Instruction * cursor = NULL; - TR::RealRegister * freeHighWordReg = NULL; TR_Debug * debugObj = self()->cg()->getDebug(); TR::Compilation *comp = self()->cg()->comp(); //This may not actually need to be reversed if @@ -3938,9 +3691,6 @@ OMR::Z::Machine::reverseSpillState(TR::Instruction *currentInstruction, self()->cg()->traceRegisterAssignment("REVERSE SPILL STATE FOR %R", spilledRegister); - bool enableHighWordRA = self()->cg()->supportsHighWordFacility() && - rk != TR_FPR && rk != TR_VRF; - if (spilledRegister->isPlaceholderReg()) { return NULL; @@ -3952,15 +3702,7 @@ OMR::Z::Machine::reverseSpillState(TR::Instruction *currentInstruction, self()->cg()->incTotalSpills(); } #endif - - if (enableHighWordRA) - { - //TR_ASSERTC( !location,self()->cg()->comp(), "\nHW RA: reg spilled to both HW and stack??\n"); - freeHighWordReg = self()->findVirtRegInHighWordRegister(spilledRegister); - if (freeHighWordReg) - self()->cg()->traceRegisterAssignment("reverseSpillState: found GPR spilled to %R", freeHighWordReg); - } - + // no real reg is assigned to targetRegister yet if (targetRegister == NULL) { @@ -3977,31 +3719,28 @@ OMR::Z::Machine::reverseSpillState(TR::Instruction *currentInstruction, // the future and total use count might not always reflect register spill state // for example a new register assignment in the hot path would cause FC != TC // in this case, assign a new register and return - if (!freeHighWordReg) + if (location == NULL) { - if (location == NULL) + if (debugObj) { - if (debugObj) - { - self()->cg()->traceRegisterAssignment("OOL: Not generating reverse spill for (%s)\n", debugObj->getName(spilledRegister)); - } - - targetRegister->setState(TR::RealRegister::Assigned); - targetRegister->setAssignedRegister(spilledRegister); - spilledRegister->setAssignedRegister(targetRegister); + self()->cg()->traceRegisterAssignment("OOL: Not generating reverse spill for (%s)\n", debugObj->getName(spilledRegister)); + } - if (spilledRegister->is64BitReg()) - { - targetRegister->getHighWordRegister()->setState(TR::RealRegister::Assigned); - targetRegister->getHighWordRegister()->setAssignedRegister(spilledRegister); - } + targetRegister->setState(TR::RealRegister::Assigned); + targetRegister->setAssignedRegister(spilledRegister); + spilledRegister->setAssignedRegister(targetRegister); - return targetRegister; + if (spilledRegister->is64BitReg()) + { + targetRegister->getHighWordRegister()->setState(TR::RealRegister::Assigned); + targetRegister->getHighWordRegister()->setAssignedRegister(spilledRegister); } + + return targetRegister; } } - if (location == NULL && freeHighWordReg == NULL) + if (location == NULL) { if (rk == TR_GPR) { @@ -4030,44 +3769,6 @@ OMR::Z::Machine::reverseSpillState(TR::Instruction *currentInstruction, targetRegister->getHighWordRegister()->setAssignedRegister(spilledRegister); } - // the register was spilled to a HW reg - if (freeHighWordReg) - { - if (targetRegister->isHighWordRegister()) - { - cursor = generateExtendedHighWordInstruction(currentNode, self()->cg(), TR::InstOpCode::LHHR, freeHighWordReg, targetRegister, 0, currentInstruction); - } - else - { - if (spilledRegister->containsCollectedReference()) - { - uint32_t compressShift = TR::Compiler->om.compressedReferenceShift(); - // need to assert heapbase, offset = 0 - if (compressShift == 0) - { - cursor = generateExtendedHighWordInstruction(currentNode, self()->cg(), TR::InstOpCode::LHLR, freeHighWordReg, targetRegister, 0, currentInstruction); - } - else - { - cursor = generateRIEInstruction(self()->cg(), TR::InstOpCode::RISBHG, currentNode, freeHighWordReg, targetRegister, 0, 31+0x80, 32-compressShift, currentInstruction); - } - } - else - { - cursor = generateExtendedHighWordInstruction(currentNode, self()->cg(), TR::InstOpCode::LHLR, freeHighWordReg, targetRegister, 0, currentInstruction); - } - } - if (debugObj) - { - debugObj->addInstructionComment(cursor, "Reverse spill Highword"); - } - self()->cg()->traceRAInstruction(cursor); - spilledRegister->setSpilledToHPR(false); - freeHighWordReg->setAssignedRegister(NULL); - freeHighWordReg->setState(TR::RealRegister::Free); - return targetRegister; - } - TR::MemoryReference * tempMR = generateS390MemoryReference(currentNode, location->getSymbolReference(), self()->cg()); bool needMVHI = false; From 253bf1e20290f8aff6de745ed09bfbceffa5b71c Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Tue, 5 Mar 2019 12:57:12 -0500 Subject: [PATCH 04/23] Fold assignToHPR as false Now that all three HPR related transformations have been deprecated we can start cleaning up all HPR related APIs. We start with the `assignToHPR` API which was the primary interface between global and local RA. This API determined whether a particular virtual register is to be assigned to an HPR the first time the register becomes alive, or whether when generating an instruction using such a register needs to be upgraded to an equivalent HPR instruction. We fold this API to always return false and all the code that follows. Signed-off-by: Filip Jeremic --- compiler/z/codegen/BinaryEvaluator.cpp | 33 +--- compiler/z/codegen/OMRInstruction.cpp | 20 --- compiler/z/codegen/OMRMachine.cpp | 66 +------- compiler/z/codegen/OMRRegister.cpp | 8 +- compiler/z/codegen/OMRRegister.hpp | 3 - compiler/z/codegen/OMRRegisterDependency.cpp | 3 - compiler/z/codegen/OMRTreeEvaluator.cpp | 17 -- .../z/codegen/S390GenerateInstructions.cpp | 154 ------------------ 8 files changed, 8 insertions(+), 296 deletions(-) diff --git a/compiler/z/codegen/BinaryEvaluator.cpp b/compiler/z/codegen/BinaryEvaluator.cpp index 2d943f3e83f..9f84933aad1 100644 --- a/compiler/z/codegen/BinaryEvaluator.cpp +++ b/compiler/z/codegen/BinaryEvaluator.cpp @@ -1387,29 +1387,7 @@ genericIntShift(TR::Node * node, TR::CodeGenerator * cg, TR::InstOpCode::Mnemoni { if (trgReg != srcReg && canUseAltShiftOp ) { - if (cg->supportsHighWordFacility() && srcReg->assignToHPR() && - (altShiftOp == TR::InstOpCode::SLLK || altShiftOp == TR::InstOpCode::SRLK )) - { - if (altShiftOp == TR::InstOpCode::SLLK) - { - if (trgReg->assignToHPR()) - altShiftOp = TR::InstOpCode::SLLHH; - else - altShiftOp = TR::InstOpCode::SLLLH; - } - else - { - if (trgReg->assignToHPR()) - altShiftOp = TR::InstOpCode::SRLHH; - else - altShiftOp = TR::InstOpCode::SRLLH; - } - generateExtendedHighWordInstruction(node, cg, altShiftOp, trgReg, srcReg, shiftAmount); - } - else - { - generateRSInstruction(cg, altShiftOp, node, trgReg, srcReg, shiftAmount); - } + generateRSInstruction(cg, altShiftOp, node, trgReg, srcReg, shiftAmount); } else { @@ -1714,15 +1692,6 @@ genericRotateAndInsertHelper(TR::Node * node, TR::CodeGenerator * cg) secondChild->getOpCode().isLoadConst() && firstChild->getSecondChild()->getOpCode().isLoadConst()) { - // if GRA had decided to assign HPR to these nodes, we cannot use RISBG because they are 64-bit - // instructions - if (cg->supportsHighWordFacility() && - firstChild->getFirstChild()->getRegister() && - firstChild->getFirstChild()->getRegister()->assignToHPR()) - { - return NULL; - } - uint64_t value = 0; // Mask diff --git a/compiler/z/codegen/OMRInstruction.cpp b/compiler/z/codegen/OMRInstruction.cpp index 0db0c953fd4..5ec0a7543af 100644 --- a/compiler/z/codegen/OMRInstruction.cpp +++ b/compiler/z/codegen/OMRInstruction.cpp @@ -1469,8 +1469,6 @@ OMR::Z::Instruction::assignOrderedRegisters(TR_RegisterKinds kindToBeAssigned) if (!_targetReg[i]->getRegisterPair()) continue; - if (self()->cg()->supportsHighWordFacility()) - _targetReg[i]->setAssignToHPR(false); TR::Register *virtReg=_targetReg[i]; _targetReg[i] = self()->assignRegisterNoDependencies(virtReg); _targetReg[i]->block(); @@ -1497,8 +1495,6 @@ OMR::Z::Instruction::assignOrderedRegisters(TR_RegisterKinds kindToBeAssigned) if (!_sourceReg[i]->getRegisterPair()) continue; - if (self()->cg()->supportsHighWordFacility()) - (_sourceReg[i])->setAssignToHPR(false); (_sourceReg[i]) = self()->assignRegisterNoDependencies(_sourceReg[i]); (_sourceReg[i])->block(); @@ -1517,22 +1513,6 @@ OMR::Z::Instruction::assignOrderedRegisters(TR_RegisterKinds kindToBeAssigned) registerOperandNum = (_targetReg < _sourceReg) ? i+1 : _sourceRegSize+i+1; - if (self()->cg()->supportsHighWordFacility()) - { - if ((self()->getOpCodeValue() == TR::InstOpCode::RISBLG || self()->getOpCodeValue() == TR::InstOpCode::RISBHG) && - ((TR::S390RIEInstruction *)self())->getExtendedHighWordOpCode().getOpCodeValue() != TR::InstOpCode::BAD) - { - if (((TR::S390RIEInstruction *)self())->getExtendedHighWordOpCode().isOperandHW(registerOperandNum)) - _targetReg[i]->setAssignToHPR(true); - else - _targetReg[i]->setAssignToHPR(false); - } - else if (_opcode.isOperandHW(registerOperandNum)) - _targetReg[i]->setAssignToHPR(true); - else - _targetReg[i]->setAssignToHPR(false); - } - if (_targetReg[i]->is64BitReg() && _targetReg[i]->getRealRegister() == NULL && _targetReg[i]->getKind() != TR_FPR && _targetReg[i]->getKind() != TR_VRF) { diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index 08bccd8b839..080fd75367b 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -1193,32 +1193,8 @@ OMR::Z::Machine::assignBestRegisterSingle(TR::Register *targetRegister, { appendInst = currInst->getPrev(); } - //for 32-bit Registers, we need to make sure that the register is in the correct low/high word - if (assignedRegister->isLowWordRegister() && targetRegister->assignToHPR()) - { - // need to find a free HPR and move assignedRegister there - TR::RealRegister * assignedHighWordRegister = NULL; - - if ((assignedHighWordRegister = self()->findBestFreeRegister(currInst, kindOfRegister, targetRegister, availRegMask)) == NULL) - { - //assignedRegister->block(); - assignedHighWordRegister = self()->freeBestRegister(currInst, targetRegister, kindOfRegister, availRegMask); - //assignedRegister->unblock(); - } - - TR::Instruction * cursor = generateExtendedHighWordInstruction(currInst->getNode(), self()->cg(), TR::InstOpCode::LLHFR, assignedRegister, assignedHighWordRegister, 0, appendInst); - - self()->addToUpgradedBlockedList(assignedRegister) ? - assignedRegister->setState(TR::RealRegister::Blocked) : - assignedRegister->setState(TR::RealRegister::Free); - targetRegister->setAssignedRegister(assignedHighWordRegister); - assignedHighWordRegister->setAssignedRegister(targetRegister); - assignedHighWordRegister->setState(TR::RealRegister::Assigned); - assignedRegister->setAssignedRegister(NULL); - assignedRegister = assignedHighWordRegister; - self()->cg()->traceRAInstruction(cursor); - } - else if (assignedRegister->isHighWordRegister() && targetRegister->assignToGPR()) + + if (assignedRegister->isHighWordRegister() && targetRegister->assignToGPR()) { // special case for RISBG, we can change the rotate amount to shuffle low word/ high word if (currInst->getOpCodeValue() == TR::InstOpCode::RISBG || currInst->getOpCodeValue() == TR::InstOpCode::RISBGN) @@ -2757,7 +2733,7 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, TR::RealRegister * candidate = NULL; if (preference != 0 && (prefRegMask & availRegMask) && _registerFile[preference] != NULL) { - if (virtualReg->assignToHPR() || needsHighWord) + if (needsHighWord) candidate = _registerFile[preference]->getHighWordRegister(); else candidate = _registerFile[preference]->getLowWordRegister(); @@ -2874,7 +2850,7 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, } else { - if (virtualReg->assignToHPR() || needsHighWord) + if (needsHighWord) { candidate = _registerFile[i]->getHighWordRegister(); tRegMask = candidate->getRealRegisterMask(); @@ -3183,33 +3159,7 @@ OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Regi { TR::RealRegister * realRegHW = realReg->getHighWordRegister(); - if (virtReg->assignToHPR()) - { - if (realRegHW->getState() == TR::RealRegister::Assigned) - { - TR::Register * associatedVirtual = realRegHW->getAssignedRegister(); - - if ((!iInterfere && i==preference && pref_favored) || (realReg->getState() == TR::RealRegister::Free)) - { - if (numCandidates == 0) - { - candidates[0] = associatedVirtual; - } - else - { - tempReg = candidates[0]; - candidates[0] = associatedVirtual; - candidates[numCandidates] = tempReg; - } - } - else - { - candidates[numCandidates] = associatedVirtual; - } - numCandidates++; - } - } - else if (virtReg->assignToGPR()) + if (virtReg->assignToGPR()) { if (realReg->getState() == TR::RealRegister::Assigned) { @@ -3372,10 +3322,6 @@ OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Regi self()->cg()->traceRegisterAssignment("HW RA: freeBestReg Spill %R for fullsize reg: %R ", best->getHighWordRegister(), virtReg); self()->spillRegister(currentInstruction, best->getHighWordRegister()->getAssignedRegister()); } - else if (virtReg->assignToHPR()) - { - best = best->getHighWordRegister(); - } else if ((rk != TR_FPR && rk != TR_VRF) && (virtReg->is64BitReg() || virtReg->assignToGPR())) { best = best->getLowWordRegister(); @@ -3779,7 +3725,7 @@ OMR::Z::Machine::reverseSpillState(TR::Instruction *currentInstruction, dataSize = TR::Compiler->om.sizeofReferenceAddress(); opCode = TR::InstOpCode::getStoreOpCode(); - if (spilledRegister->assignToHPR() || targetRegister->isHighWordRegister()) + if (targetRegister->isHighWordRegister()) { //dataSize = 4; opCode = TR::InstOpCode::STFH; diff --git a/compiler/z/codegen/OMRRegister.cpp b/compiler/z/codegen/OMRRegister.cpp index 0005755dbb1..40643f9747d 100644 --- a/compiler/z/codegen/OMRRegister.cpp +++ b/compiler/z/codegen/OMRRegister.cpp @@ -79,16 +79,10 @@ OMR::Z::Register::setPlaceholderReg() OMR::Register::setPlaceholderReg(); } -bool -OMR::Z::Register::assignToHPR() - { - return (!(self()->is64BitReg()) && _flags.testAny(AssignToHPR)); - } - bool OMR::Z::Register::assignToGPR() { - return (!(self()->is64BitReg()) && !_flags.testAny(AssignToHPR)); + return !(self()->is64BitReg()); } ncount_t diff --git a/compiler/z/codegen/OMRRegister.hpp b/compiler/z/codegen/OMRRegister.hpp index 97fb67ce218..87d65856c3b 100644 --- a/compiler/z/codegen/OMRRegister.hpp +++ b/compiler/z/codegen/OMRRegister.hpp @@ -88,8 +88,6 @@ class OMR_EXTENSIBLE Register: public OMR::Register bool is64BitReg(); void setIs64BitReg(bool b = true); - bool assignToHPR(); - void setAssignToHPR(bool b = true) {_flags.set(AssignToHPR, b);} bool assignToGPR(); bool isSpilledToHPR() {return (_flags.testAny(SpilledToHPR));} @@ -136,7 +134,6 @@ class OMR_EXTENSIBLE Register: public OMR::Register { IsUsedInMemRef = 0x0800, // 390 cannot associate GPR0 to regs used in memrefs Is64Bit = 0x0002, // 390 flag indicates that this Register contained a 64-bit value - AssignToHPR = 0x0004, // 390 flag indicates that this virtual register needs to be assigned to an HPR SpilledToHPR = 0x4000, // 390 flag indicates that this virtual register is spilled to DependencySet = 0x0200, // 390 flag, post dependancy was assigned diff --git a/compiler/z/codegen/OMRRegisterDependency.cpp b/compiler/z/codegen/OMRRegisterDependency.cpp index 99ec7450efb..0115c0f871d 100644 --- a/compiler/z/codegen/OMRRegisterDependency.cpp +++ b/compiler/z/codegen/OMRRegisterDependency.cpp @@ -695,10 +695,8 @@ TR_S390RegisterDependencyGroup::checkRegisterPairSufficiencyAndHPRAssignment(TR: virtRegI->setIs64BitReg(true); } - virtRegI->setAssignToHPR(false); if (TR::RealRegister::isHPR(realRegI)) { - virtRegI->setAssignToHPR(true); cg->maskAvailableHPRSpillMask(~(machine->getRealRegister(realRegI)->getRealRegisterMask())); } else if (TR::RealRegister::isGPR(realRegI) && virtRegI->is64BitReg()) @@ -1509,7 +1507,6 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru if(virtReg->isUsedInMemRef()) { - virtReg->setAssignToHPR(false); uint32_t availRegMask =~TR::RealRegister::GPR0Mask; // No bookkeeping on assignment call as we do bookkeeping at end of this method diff --git a/compiler/z/codegen/OMRTreeEvaluator.cpp b/compiler/z/codegen/OMRTreeEvaluator.cpp index 01da9956ccc..aeb9ecbf38a 100644 --- a/compiler/z/codegen/OMRTreeEvaluator.cpp +++ b/compiler/z/codegen/OMRTreeEvaluator.cpp @@ -787,11 +787,6 @@ generateS390ImmOp(TR::CodeGenerator * cg, TR::InstOpCode::Mnemonic memOp, TR::N // LL: If Golden Eagle - can use Add Immediate with max 32-bit value. ei_immOp = TR::InstOpCode::AFI; } - if (targetRegister != NULL && targetRegister->assignToHPR()) - { - immOp = TR::InstOpCode::BAD; - ei_immOp = TR::InstOpCode::AIH; - } break; case TR::InstOpCode::AG: if (value == 0) return cursor; @@ -854,11 +849,6 @@ generateS390ImmOp(TR::CodeGenerator * cg, TR::InstOpCode::Mnemonic memOp, TR::N // LL: If Golden Eagle - can use Compare Immediate with max 32-bit value. ei_immOp = TR::InstOpCode::CFI; } - if (targetRegister != NULL && targetRegister->assignToHPR()) - { - immOp = TR::InstOpCode::BAD; - ei_immOp = TR::InstOpCode::CIH; - } break; case TR::InstOpCode::CL: @@ -880,11 +870,6 @@ generateS390ImmOp(TR::CodeGenerator * cg, TR::InstOpCode::Mnemonic memOp, TR::N return cursor; } } - if (targetRegister != NULL && targetRegister->assignToHPR()) - { - immOp = TR::InstOpCode::BAD; - ei_immOp = TR::InstOpCode::CIH; - } else { if (cg->canUseGoldenEagleImmediateInstruction(value)) @@ -11999,8 +11984,6 @@ OMR::Z::TreeEvaluator::iRegLoadEvaluator(TR::Node * node, TR::CodeGenerator * cg } node->setRegister(globalReg); - - globalReg->setAssignToHPR(false); } return globalReg; diff --git a/compiler/z/codegen/S390GenerateInstructions.cpp b/compiler/z/codegen/S390GenerateInstructions.cpp index ec3e157d1fb..2b398212bf9 100644 --- a/compiler/z/codegen/S390GenerateInstructions.cpp +++ b/compiler/z/codegen/S390GenerateInstructions.cpp @@ -151,11 +151,6 @@ TR::Instruction * generateS390BranchInstruction(TR::CodeGenerator * cg, TR::InstOpCode::Mnemonic op, TR::Node * n, TR::Register * targetReg, TR::LabelSymbol * sym, TR::Instruction * preced) { - if (op == TR::InstOpCode::BRCT && targetReg->assignToHPR()) - { - // upgrade to Highword branch on count - op = TR::InstOpCode::BRCTH; - } if (preced) { return new (INSN_HEAP) TR::S390BranchOnCountInstruction(op, n, targetReg, sym, preced, cg); @@ -167,11 +162,6 @@ TR::Instruction * generateS390BranchInstruction(TR::CodeGenerator * cg, TR::InstOpCode::Mnemonic op, TR::Node * n, TR::Register * targetReg, TR::RegisterDependencyConditions *cond, TR::LabelSymbol * sym, TR::Instruction * preced) { - if (op == TR::InstOpCode::BRCT && targetReg->assignToHPR()) - { - // upgrade to Highword branch on count - op = TR::InstOpCode::BRCTH; - } if (preced) { return new (INSN_HEAP) TR::S390BranchOnCountInstruction(op, n, targetReg, cond, sym, preced, cg); @@ -475,81 +465,6 @@ generateRRInstruction(TR::CodeGenerator * cg, TR::InstOpCode::Mnemonic op, TR::N { switch(op) { - case TR::InstOpCode::AR: - if (treg->assignToHPR()) - { - if (sreg->assignToHPR()) - { - return generateRRRInstruction(cg, TR::InstOpCode::AHHHR, n, treg, treg, sreg, preced); - } - //cracked insn - //return generateRRRInstruction(cg, TR::InstOpCode::AHHLR, n, treg, treg, sreg, preced); - } - break; - case TR::InstOpCode::ALR: - if (treg->assignToHPR()) - { - if (sreg->assignToHPR()) - { - return generateRRRInstruction(cg, TR::InstOpCode::ALHHHR, n, treg, treg, sreg, preced); - } - //return generateRRRInstruction(cg, TR::InstOpCode::ALHHLR, n, treg, treg, sreg, preced); - } - break; - case TR::InstOpCode::CR: - if (treg->assignToHPR()) - { - op = TR::InstOpCode::CHLR; - if (sreg->assignToHPR()) - { - op = TR::InstOpCode::CHHR; - } - } - break; - case TR::InstOpCode::CLR: - if (treg->assignToHPR()) - { - op = TR::InstOpCode::CLHLR; - if (sreg->assignToHPR()) - { - op = TR::InstOpCode::CLHHR; - } - } - break; - case TR::InstOpCode::LR: - if (treg->assignToHPR()) - { - if (sreg->assignToHPR()) - { - return generateExtendedHighWordInstruction(n, cg, TR::InstOpCode::LHHR, treg, sreg, 0, preced); - } - return generateExtendedHighWordInstruction(n, cg, TR::InstOpCode::LHLR, treg, sreg, 0, preced); - } - if (sreg->assignToHPR()) - { - return generateExtendedHighWordInstruction(n, cg, TR::InstOpCode::LLHFR, treg, sreg, 0, preced); - } - break; - case TR::InstOpCode::SR: - if (treg->assignToHPR()) - { - if (sreg->assignToHPR()) - { - return generateRRRInstruction(cg, TR::InstOpCode::SHHHR, n, treg, treg, sreg, preced); - } - //return generateRRRInstruction(cg, TR::InstOpCode::SHHLR, n, treg, treg, sreg, preced); - } - break; - case TR::InstOpCode::SLR: - if (treg->assignToHPR()) - { - if (sreg->assignToHPR()) - { - return generateRRRInstruction(cg, TR::InstOpCode::SLHHHR, n, treg, treg, sreg, preced); - } - //return generateRRRInstruction(cg, TR::InstOpCode::SLHHLR, n, treg, treg, sreg, preced); - } - break; case TR::InstOpCode::LHHR: return generateExtendedHighWordInstruction(n, cg, TR::InstOpCode::LHHR, treg, sreg, 0, preced); break; @@ -747,60 +662,6 @@ generateRXInstruction(TR::CodeGenerator * cg, TR::InstOpCode::Mnemonic op, TR::N TR_ASSERT(treg->getRealRegister()!=NULL || // Not in RA op != TR::InstOpCode::L || !n->isExtendedTo64BitAtSource(), "Generating an TR::InstOpCode::L, when LLGF|LGF should be used"); - if (treg->assignToHPR()) - { - switch(op) - { - case TR::InstOpCode::C: - op = TR::InstOpCode::CHF; - break; - case TR::InstOpCode::CL: - op = TR::InstOpCode::CLHF; - break; - case TR::InstOpCode::L: - op = TR::InstOpCode::LFH; - break; - case TR::InstOpCode::LB: - op = TR::InstOpCode::LBH; - break; - case TR::InstOpCode::LH: - op = TR::InstOpCode::LHH; - break; - case TR::InstOpCode::LHY: - op = TR::InstOpCode::LHH; - break; - case TR::InstOpCode::LLC: - op = TR::InstOpCode::LLCH; - break; - case TR::InstOpCode::LLH: - op = TR::InstOpCode::LLHH; - break; - case TR::InstOpCode::LY: - op = TR::InstOpCode::LFH; - break; - case TR::InstOpCode::ST: - op = TR::InstOpCode::STFH; - break; - case TR::InstOpCode::STC: - op = TR::InstOpCode::STCH; - break; - case TR::InstOpCode::STCY: - op = TR::InstOpCode::STCH; - break; - case TR::InstOpCode::STH: - op = TR::InstOpCode::STHH; - break; - case TR::InstOpCode::STHY: - op = TR::InstOpCode::STHH; - break; - case TR::InstOpCode::STY: - op = TR::InstOpCode::STFH; - break; - default: - break; - } - } - // Handle long displacement if necessary op = getReplacementLongDisplacementOpCode(cg, op, mf); @@ -911,21 +772,6 @@ generateRIInstruction(TR::CodeGenerator * cg, TR::InstOpCode::Mnemonic op, TR::N TR::Instruction * generateRIInstruction(TR::CodeGenerator * cg, TR::InstOpCode::Mnemonic op, TR::Node * n, TR::Register * treg, int32_t imm, TR::Instruction * preced) { - TR::Compilation *comp = cg->comp(); - if (treg->assignToHPR()) - { - switch(op) - { - case TR::InstOpCode::LHI: - return generateRILInstruction(cg, TR::InstOpCode::IIHF, n, treg, imm, preced); - break; - case TR::InstOpCode::AHI: - return generateRILInstruction(cg, TR::InstOpCode::AIH, n, treg, imm, preced); - break; - default: - break; - } - } if (preced) { return new (INSN_HEAP) TR::S390RIInstruction(op, n, treg, imm, preced, cg); From a898a06b6acbeac1ce0c109d38aa4a00f8b05382 Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Tue, 5 Mar 2019 13:03:31 -0500 Subject: [PATCH 05/23] Fold SpilledToHPR In addition fold: - setSpilledToHPR - isSpilledToHPR HPRs can no longer be spilled to (since they do not exist) so these APIs can be folded away as well as the corresponding flag. Signed-off-by: Filip Jeremic --- compiler/z/codegen/OMRMachine.cpp | 26 +------------------- compiler/z/codegen/OMRRegister.hpp | 4 --- compiler/z/codegen/OMRRegisterDependency.cpp | 2 -- 3 files changed, 1 insertion(+), 31 deletions(-) diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index 080fd75367b..e3b312f238b 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -3212,19 +3212,7 @@ OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Regi } bool doNotSpillHPR = realRegHW->getAssignedRegister() == virtReg && realReg->getAssignedRegister() != virtReg; - - /* - // do not to spill an HPR that contains a compressed ref when shift !=0. - // We have to first decompress the pointer, which means we need an extra 64-bit register or at least the low word register. - // for shift = 0 case, we can load LFH from stack directly - if (realRegHW->getAssignedRegister() && - realRegHW->getAssignedRegister()->isSpilledToHPR() && - realRegHW->getAssignedRegister()->containsCollectedReference()) - { - //doNotSpillHPR = true; - } - */ - + if ((realReg->getState() == TR::RealRegister::Assigned || realReg->getState() == TR::RealRegister::Free) && (realRegHW->getState() == TR::RealRegister::Assigned || realRegHW->getState() == TR::RealRegister::Free) && !doNotSpillHPR) @@ -3846,7 +3834,6 @@ OMR::Z::Machine::reverseSpillState(TR::Instruction *currentInstruction, self()->cg()->traceRAInstruction(cursor); cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::STFH, currentNode, targetRegister, generateS390MemoryReference(*tempMR, 4, self()->cg()), cursor); self()->cg()->traceRAInstruction(cursor); - spilledRegister->setSpilledToHPR(true); } else { @@ -4028,7 +4015,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction // don't need to worry about protecting backing storage because we are leaving cold path OOL now self()->cg()->freeSpill(virtualRegister->getBackingStorage(), 8, 0); virtualRegister->setBackingStorage(NULL); - virtualRegister->setSpilledToHPR(true); } else { @@ -4054,7 +4040,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction } // fix up the states virtualRegister->setAssignedRegister(NULL); - virtualRegister->setSpilledToHPR(true); targetRegister->setAssignedRegister(virtualRegister); return cursor; } @@ -4435,7 +4420,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction // don't need to worry about protecting backing storage because we are leaving cold path OOL now self()->cg()->freeSpill(virtualRegister->getBackingStorage(), 8, 0); virtualRegister->setBackingStorage(NULL); - virtualRegister->setSpilledToHPR(true); } else { @@ -4461,7 +4445,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction } // fix up the states virtualRegister->setAssignedRegister(NULL); - virtualRegister->setSpilledToHPR(true); targetRegister->setAssignedRegister(virtualRegister); } else @@ -4481,7 +4464,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction //fix up states currentHighWordReg->setState(TR::RealRegister::Free); currentHighWordReg->setAssignedRegister(NULL); - virtualRegister->setSpilledToHPR(false); } else if (virtualRegister->getTotalUseCount() != virtualRegister->getFutureUseCount()) { @@ -4500,7 +4482,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction // don't need to worry about protecting backing storage because we are leaving cold path OOL now self()->cg()->freeSpill(virtualRegister->getBackingStorage(), 8, 0); virtualRegister->setBackingStorage(NULL); - virtualRegister->setSpilledToHPR(true); } // and do nothing in case virtual reg is a placeholder } @@ -5812,11 +5793,6 @@ OMR::Z::Machine::restoreRegisterStateFromSnapShot() } } - if (_containsHPRSpillSnapShot[i]) - { - _registerFile[i]->getAssignedRegister()->setSpilledToHPR(true); - } - // If a register is only created and used in multiple OOL hot paths (created in one OOL hot path // the dead in a later OOL hot path) and has never been used in any OOL cold path or main line, then we need // to make sure to not include this register in the snapshot once the register is dead, otherwise diff --git a/compiler/z/codegen/OMRRegister.hpp b/compiler/z/codegen/OMRRegister.hpp index 87d65856c3b..79bc30125e4 100644 --- a/compiler/z/codegen/OMRRegister.hpp +++ b/compiler/z/codegen/OMRRegister.hpp @@ -90,9 +90,6 @@ class OMR_EXTENSIBLE Register: public OMR::Register bool assignToGPR(); - bool isSpilledToHPR() {return (_flags.testAny(SpilledToHPR));} - void setSpilledToHPR(bool b = true) {_flags.set(SpilledToHPR, b);} - bool isDependencySet() {return _flags.testAny(DependencySet);} void setDependencySet(bool v) {if (v) _flags.set(DependencySet);} @@ -134,7 +131,6 @@ class OMR_EXTENSIBLE Register: public OMR::Register { IsUsedInMemRef = 0x0800, // 390 cannot associate GPR0 to regs used in memrefs Is64Bit = 0x0002, // 390 flag indicates that this Register contained a 64-bit value - SpilledToHPR = 0x4000, // 390 flag indicates that this virtual register is spilled to DependencySet = 0x0200, // 390 flag, post dependancy was assigned AlreadySignExtended = 0x1000, // determine whether i2l should be nops diff --git a/compiler/z/codegen/OMRRegisterDependency.cpp b/compiler/z/codegen/OMRRegisterDependency.cpp index 0115c0f871d..166aa8662dd 100644 --- a/compiler/z/codegen/OMRRegisterDependency.cpp +++ b/compiler/z/codegen/OMRRegisterDependency.cpp @@ -937,7 +937,6 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru "virtReg is assigned to HPR but is not a spilled compress pointer"); // we need to decompress pointer tempMR = generateS390MemoryReference(*tempMR, 4, cg); - virtReg->setSpilledToHPR(false); } } } @@ -1684,7 +1683,6 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru TR_ASSERT(virtReg, "\nOOL HPR spill: spilled HPR should have a virt Reg assigned!"); TR_ASSERT(highWordReg->isHighWordRegister(), "\nOOL HPR spill: spilled HPR should be a real HPR!"); virtReg->setAssignedRegister(NULL); - virtReg->setSpilledToHPR(true); } } } From 29e1373dcff44d3f5fca37d9e0a5c421440e67da Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Tue, 5 Mar 2019 13:07:56 -0500 Subject: [PATCH 06/23] Fold findVirtRegInHighWordRegister This API was used to do a linear walk through the HPR register table and find the real (HPR) register which is assigned to a particular virtual register. This API is in hindsight pretty expensive given the number of places it is called in. We fold it away here and all the code that relies on it. Signed-off-by: Filip Jeremic --- compiler/z/codegen/OMRMachine.cpp | 219 +++++++------------ compiler/z/codegen/OMRRegisterDependency.cpp | 15 +- 2 files changed, 79 insertions(+), 155 deletions(-) diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index e3b312f238b..369d63892eb 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -2973,33 +2973,6 @@ OMR::Z::Machine::findRegNotUsedInInstruction(TR::Instruction *currentInstructio return spill; } - -/** - * Look for the virtual reg in the highword register table. - * @return the real reg if found, NULL if not found - */ -TR::RealRegister * -OMR::Z::Machine::findVirtRegInHighWordRegister(TR::Register *virtReg) - { - int32_t first = TR::RealRegister::FirstHPR; - int32_t last = TR::RealRegister::LastHPR; - TR::Machine *machine = self()->cg()->machine(); - - for (int32_t i = first; i <= last; i++) - { - TR::RealRegister * realReg = - machine->getRealRegister((TR::RealRegister::RegNum) i); - - if (realReg->getAssignedRegister() && virtReg == realReg->getAssignedRegister() ) - { - return realReg; - } - } - - return NULL; - } - - void OMR::Z::Machine::allocateUpgradedBlockedList(TR_Stack *mem) { @@ -3978,66 +3951,52 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction // this could happen for OOL, when the reg deps on the top of slow path dictates that a collectible register must be // spilled to a specific HPR TR_ASSERT( virtualRegister->containsCollectedReference(), " OOL HPR spill: spilling a 64 bit scalar into HPR"); - - TR::RealRegister * currentHighWordReg = self()->findVirtRegInHighWordRegister(virtualRegister); - - if (virtualRegister->getAssignedRegister() == NULL && currentHighWordReg) - { - // already spilled to HPR, so simply move - cursor = generateExtendedHighWordInstruction(currentNode, self()->cg(), TR::InstOpCode::LHHR, currentHighWordReg, targetRegister, 0, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - - //fix up states - currentHighWordReg->setAssignedRegister(NULL); - currentHighWordReg->setState(TR::RealRegister::Free); - } - else + + if (currentAssignedRegister == NULL) { - if (currentAssignedRegister == NULL) + if (virtualRegister->getTotalUseCount() != virtualRegister->getFutureUseCount() && + virtualRegister->getBackingStorage() != NULL) { - if (virtualRegister->getTotalUseCount() != virtualRegister->getFutureUseCount() && - virtualRegister->getBackingStorage() != NULL) - { - // the virtual register is currently spilled to stack, now we need to spill it onto HPR - // load it back from the stack into HPR with STFH - // since we are working with compressed refs shift = 0, simply load 32-bit value into HPR. - TR::MemoryReference * tempMR = generateS390MemoryReference(currentNode, virtualRegister->getBackingStorage()->getSymbolReference(), self()->cg()); - - // is the offset correct? +4 big endian? - TR::MemoryReference * mr = generateS390MemoryReference(*tempMR, 4, self()->cg()); - - cursor = generateSILInstruction(self()->cg(), TR::InstOpCode::MVHI, currentNode, tempMR, 0, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::STFH, currentNode, targetRegister, mr, cursor); - self()->cg()->traceRAInstruction(cursor); - - // fix up states - // don't need to worry about protecting backing storage because we are leaving cold path OOL now - self()->cg()->freeSpill(virtualRegister->getBackingStorage(), 8, 0); - virtualRegister->setBackingStorage(NULL); - } - else - { - TR_ASSERT(comp, " OOL HPR spill: currentAssignedRegister is NULL but virtual reg is not spilled?"); - } - } - else - { - // the virtual register is currently assigned to a 64 bit real reg - // simply spill it to HPR and decompress - TR_ASSERT(currentAssignedRegister->isLowWordRegister(), " OOL HPR spill: 64-bit reg assigned to HPR and is not spilled to HPR"); - cursor = generateExtendedHighWordInstruction(currentNode, self()->cg(), TR::InstOpCode::LLHFR, currentAssignedRegister, targetRegister, 0, currentInstruction); + // the virtual register is currently spilled to stack, now we need to spill it onto HPR + // load it back from the stack into HPR with STFH + // since we are working with compressed refs shift = 0, simply load 32-bit value into HPR. + TR::MemoryReference * tempMR = generateS390MemoryReference(currentNode, virtualRegister->getBackingStorage()->getSymbolReference(), self()->cg()); + + // is the offset correct? +4 big endian? + TR::MemoryReference * mr = generateS390MemoryReference(*tempMR, 4, self()->cg()); + + cursor = generateSILInstruction(self()->cg(), TR::InstOpCode::MVHI, currentNode, tempMR, 0, currentInstruction); self()->cg()->traceRAInstruction(cursor); - cursor = generateRILInstruction(self()->cg(), TR::InstOpCode::IIHF, currentNode, currentAssignedRegister, 0, cursor); + cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::STFH, currentNode, targetRegister, mr, cursor); self()->cg()->traceRAInstruction(cursor); // fix up states - currentAssignedRegister->setAssignedRegister(NULL); - currentAssignedRegister->setState(TR::RealRegister::Free); - currentAssignedRegisterHW->setAssignedRegister(NULL); - currentAssignedRegisterHW->setState(TR::RealRegister::Free); + // don't need to worry about protecting backing storage because we are leaving cold path OOL now + self()->cg()->freeSpill(virtualRegister->getBackingStorage(), 8, 0); + virtualRegister->setBackingStorage(NULL); + } + else + { + TR_ASSERT(comp, " OOL HPR spill: currentAssignedRegister is NULL but virtual reg is not spilled?"); } } + else + { + // the virtual register is currently assigned to a 64 bit real reg + // simply spill it to HPR and decompress + TR_ASSERT(currentAssignedRegister->isLowWordRegister(), " OOL HPR spill: 64-bit reg assigned to HPR and is not spilled to HPR"); + cursor = generateExtendedHighWordInstruction(currentNode, self()->cg(), TR::InstOpCode::LLHFR, currentAssignedRegister, targetRegister, 0, currentInstruction); + self()->cg()->traceRAInstruction(cursor); + cursor = generateRILInstruction(self()->cg(), TR::InstOpCode::IIHF, currentNode, currentAssignedRegister, 0, cursor); + self()->cg()->traceRAInstruction(cursor); + + // fix up states + currentAssignedRegister->setAssignedRegister(NULL); + currentAssignedRegister->setState(TR::RealRegister::Free); + currentAssignedRegisterHW->setAssignedRegister(NULL); + currentAssignedRegisterHW->setState(TR::RealRegister::Free); + } + // fix up the states virtualRegister->setAssignedRegister(NULL); targetRegister->setAssignedRegister(virtualRegister); @@ -4384,65 +4343,51 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction // spilled to a specific HPR TR_ASSERT( virtualRegister->containsCollectedReference(), " OOL HPR spill: spilling a 64 bit scalar into HPR"); - TR::RealRegister * currentHighWordReg = self()->findVirtRegInHighWordRegister(virtualRegister); - - if (virtualRegister->getAssignedRegister() == NULL && currentHighWordReg) - { - // already spilled to HPR, so simply move - cursor = generateExtendedHighWordInstruction(currentNode, self()->cg(), TR::InstOpCode::LHHR, currentHighWordReg, targetRegister, 0, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - - //fix up states - currentHighWordReg->setAssignedRegister(NULL); - currentHighWordReg->setState(TR::RealRegister::Free); - } - else + if (currentAssignedRegister == NULL) { - if (currentAssignedRegister == NULL) + if (virtualRegister->getTotalUseCount() != virtualRegister->getFutureUseCount() && + virtualRegister->getBackingStorage() != NULL) { - if (virtualRegister->getTotalUseCount() != virtualRegister->getFutureUseCount() && - virtualRegister->getBackingStorage() != NULL) - { - // the virtual register is currently spilled to stack, now we need to spill it onto HPR - // load it back from the stack into HPR with STFH - // since we are working with compressed refs shift = 0, simply load 32-bit value into HPR. - TR::MemoryReference * tempMR = generateS390MemoryReference(currentNode, virtualRegister->getBackingStorage()->getSymbolReference(), self()->cg()); - - // is the offset correct? +4 big endian? - TR::MemoryReference * mr = generateS390MemoryReference(*tempMR, 4, self()->cg()); - - cursor = generateSILInstruction(self()->cg(), TR::InstOpCode::MVHI, currentNode, tempMR, 0, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::STFH, currentNode, targetRegister, mr, cursor); - self()->cg()->traceRAInstruction(cursor); - - // fix up states - // don't need to worry about protecting backing storage because we are leaving cold path OOL now - self()->cg()->freeSpill(virtualRegister->getBackingStorage(), 8, 0); - virtualRegister->setBackingStorage(NULL); - } - else - { - TR_ASSERT(comp, " OOL HPR spill: currentAssignedRegister is NULL but virtual reg is not spilled?"); - } - } - else - { - // the virtual register is currently assigned to a 64 bit real reg - // simply spill it to HPR and decompress - TR_ASSERT(currentAssignedRegister->isLowWordRegister(), " OOL HPR spill: 64-bit reg assigned to HPR and is not spilled to HPR"); - cursor = generateExtendedHighWordInstruction(currentNode, self()->cg(), TR::InstOpCode::LLHFR, currentAssignedRegister, targetRegister, 0, currentInstruction); + // the virtual register is currently spilled to stack, now we need to spill it onto HPR + // load it back from the stack into HPR with STFH + // since we are working with compressed refs shift = 0, simply load 32-bit value into HPR. + TR::MemoryReference * tempMR = generateS390MemoryReference(currentNode, virtualRegister->getBackingStorage()->getSymbolReference(), self()->cg()); + + // is the offset correct? +4 big endian? + TR::MemoryReference * mr = generateS390MemoryReference(*tempMR, 4, self()->cg()); + + cursor = generateSILInstruction(self()->cg(), TR::InstOpCode::MVHI, currentNode, tempMR, 0, currentInstruction); self()->cg()->traceRAInstruction(cursor); - cursor = generateRILInstruction(self()->cg(), TR::InstOpCode::IIHF, currentNode, currentAssignedRegister, 0, cursor); + cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::STFH, currentNode, targetRegister, mr, cursor); self()->cg()->traceRAInstruction(cursor); // fix up states - currentAssignedRegister->setAssignedRegister(NULL); - currentAssignedRegister->setState(TR::RealRegister::Free); - currentAssignedRegisterHW->setAssignedRegister(NULL); - currentAssignedRegisterHW->setState(TR::RealRegister::Free); + // don't need to worry about protecting backing storage because we are leaving cold path OOL now + self()->cg()->freeSpill(virtualRegister->getBackingStorage(), 8, 0); + virtualRegister->setBackingStorage(NULL); + } + else + { + TR_ASSERT(comp, " OOL HPR spill: currentAssignedRegister is NULL but virtual reg is not spilled?"); } } + else + { + // the virtual register is currently assigned to a 64 bit real reg + // simply spill it to HPR and decompress + TR_ASSERT(currentAssignedRegister->isLowWordRegister(), " OOL HPR spill: 64-bit reg assigned to HPR and is not spilled to HPR"); + cursor = generateExtendedHighWordInstruction(currentNode, self()->cg(), TR::InstOpCode::LLHFR, currentAssignedRegister, targetRegister, 0, currentInstruction); + self()->cg()->traceRAInstruction(cursor); + cursor = generateRILInstruction(self()->cg(), TR::InstOpCode::IIHF, currentNode, currentAssignedRegister, 0, cursor); + self()->cg()->traceRAInstruction(cursor); + + // fix up states + currentAssignedRegister->setAssignedRegister(NULL); + currentAssignedRegister->setState(TR::RealRegister::Free); + currentAssignedRegisterHW->setAssignedRegister(NULL); + currentAssignedRegisterHW->setState(TR::RealRegister::Free); + } + // fix up the states virtualRegister->setAssignedRegister(NULL); targetRegister->setAssignedRegister(virtualRegister); @@ -4453,19 +4398,7 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction // the target HPR is now free if (currentAssignedRegister == NULL) { - // the 32-bit virtual register is spilled - TR::RealRegister * currentHighWordReg = self()->findVirtRegInHighWordRegister(virtualRegister); - if (currentHighWordReg) - { - // if it is spilled to HPR, simply move it - cursor = generateExtendedHighWordInstruction(currentNode, self()->cg(), TR::InstOpCode::LHHR, currentHighWordReg, targetRegister, 0, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - - //fix up states - currentHighWordReg->setState(TR::RealRegister::Free); - currentHighWordReg->setAssignedRegister(NULL); - } - else if (virtualRegister->getTotalUseCount() != virtualRegister->getFutureUseCount()) + if (virtualRegister->getTotalUseCount() != virtualRegister->getFutureUseCount()) { // if it is spilled to stack, load it back into HPR TR_ASSERT(virtualRegister->getBackingStorage(), " OOL HPR spill: virtual reg is not spilled to stack nor HPR"); diff --git a/compiler/z/codegen/OMRRegisterDependency.cpp b/compiler/z/codegen/OMRRegisterDependency.cpp index 166aa8662dd..093de857534 100644 --- a/compiler/z/codegen/OMRRegisterDependency.cpp +++ b/compiler/z/codegen/OMRRegisterDependency.cpp @@ -881,23 +881,14 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru if (dependentRegNum == TR::RealRegister::SpilledReg && !_dependencies[i].getRegister()->getRealRegister()) { TR_ASSERT_FATAL(virtReg->getBackingStorage() != NULL, "Spilled virtual register on dependency list does not have backing storage"); - TR::RealRegister * spilledHPR = NULL; - if (virtReg->getKind() != TR_FPR && virtReg->getKind() != TR_VRF && virtReg->getAssignedRealRegister() == NULL) - { - spilledHPR = cg->machine()->findVirtRegInHighWordRegister(virtReg); - cg->traceRegisterAssignment (" \nOOL: found %R spilled to %R", virtReg, spilledHPR); - } - if (virtReg->getAssignedRealRegister() || spilledHPR) + + if (virtReg->getAssignedRealRegister()) { // this happens when the register was first spilled in main line path then was reverse spilled // and assigned to a real register in OOL path. We protected the backing store when doing // the reverse spill so we could re-spill to the same slot now TR::Node *currentNode = currentInstruction->getNode(); - TR::RealRegister *assignedReg; - if (spilledHPR) - assignedReg = spilledHPR; - else - assignedReg = toRealRegister(virtReg->getAssignedRegister()); + TR::RealRegister *assignedReg = toRealRegister(virtReg->getAssignedRegister()); cg->traceRegisterAssignment ("\nOOL: Found %R spilled in main line and reused inside OOL", virtReg); TR::MemoryReference * tempMR = generateS390MemoryReference(currentNode, virtReg->getBackingStorage()->getSymbolReference(), cg); TR::InstOpCode::Mnemonic opCode; From 5c28feaa33c7431554dbe9da0da85d446f178b00 Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Tue, 5 Mar 2019 13:19:39 -0500 Subject: [PATCH 07/23] Fold freeHighWordRegister Signed-off-by: Filip Jeremic --- compiler/z/codegen/OMRMachine.cpp | 300 +----------------------------- compiler/z/codegen/OMRMachine.hpp | 1 - 2 files changed, 6 insertions(+), 295 deletions(-) diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index 369d63892eb..8c490b353fa 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -1146,23 +1146,6 @@ OMR::Z::Machine::assignBestRegisterSingle(TR::Register *targetRegister, assignedRegister->setState(TR::RealRegister::Free); assignedRegister = newAssignedRegister; } - else if (assignedRegister->isLowWordRegister() && - assignedRegister->getHighWordRegister()->getAssignedRegister() != targetRegister) - { - self()->cg()->traceRegisterAssignment("%R is 64bit but HPR is assigned to a different vreg, freeing up HPR", targetRegister); - if (assignedRegister->getHighWordRegister()->getState() == TR::RealRegister::Assigned) - { - assignedRegister->block(); - TR::Instruction * cursor = self()->freeHighWordRegister(currInst, assignedRegister->getHighWordRegister()); - assignedRegister->unblock(); - self()->cg()->traceRAInstruction(cursor); - } - else if (assignedRegister->getHighWordRegister()->getState() == TR::RealRegister::Blocked || - assignedRegister->getHighWordRegister()->getState() == TR::RealRegister::Locked) - { - TR_ASSERT(0, "\n HPR RA: shouldn't get here, not supported yet!"); - } - } else if (assignedRegister->isHighWordRegister()) { self()->cg()->traceRegisterAssignment("%R is 64bit but currently assigned to HPR, shuffling", targetRegister); @@ -3320,84 +3303,6 @@ void OMR::Z::Machine::freeRealRegister(TR::Instruction *currentInstruction, TR:: } } -TR::Instruction* -OMR::Z::Machine::freeHighWordRegister(TR::Instruction *currentInstruction, TR::RealRegister * targetRegisterHW) - { - TR::Register * virtRegHW = targetRegisterHW->getAssignedRegister(); - TR::RealRegister * spareReg = NULL; - TR_RegisterKinds rk = virtRegHW->getKind(); - TR::Instruction * cursor = currentInstruction; - - self()->cg()->traceRegisterAssignment(" freeHighWordRegister: %R:%R ", virtRegHW, targetRegisterHW); - - TR_ASSERT(targetRegisterHW != NULL, "freeHighWordRegister called but targetReg HW is null?"); - TR_ASSERT(targetRegisterHW->isHighWordRegister(), "freeHighWordRegister called for non HPR?"); - - // if we are trying to free up the HPR that was used for a 32-bit GPR spill - if (virtRegHW->getAssignedRegister() == NULL && targetRegisterHW->getState() == TR::RealRegister::Assigned) - { - self()->cg()->traceRegisterAssignment(" HW RA %R was spilled to %R, now need to spill again", virtRegHW, targetRegisterHW); - - // try to find another free HPR - spareReg = self()->findBestFreeRegister(currentInstruction, rk, virtRegHW, self()->cg()->getAvailableHPRSpillMask(), true); - - if (spareReg) - { - cursor = self()->registerCopy(self()->cg(), TR_HPR, targetRegisterHW, spareReg, currentInstruction); - targetRegisterHW->setState(TR::RealRegister::Unlatched); - targetRegisterHW->setAssignedRegister(NULL); - spareReg->setState(TR::RealRegister::Assigned); - spareReg->setAssignedRegister(virtRegHW); - } - else - { - // if no more free regs, spill this one to stack, do not try to HPR spill again - self()->spillRegister(currentInstruction, virtRegHW, 0); - } - - return cursor; - } - - spareReg = self()->findBestFreeRegister(currentInstruction, rk, virtRegHW, self()->cg()->getAvailableHPRSpillMask(), true); - - if (targetRegisterHW->getState() == TR::RealRegister::Blocked) - { - if (spareReg == NULL) - { - virtRegHW->block(); - spareReg = self()->freeBestRegister(currentInstruction, virtRegHW, rk, self()->cg()->getAvailableHPRSpillMask()); - virtRegHW->unblock(); - } - TR_ASSERT(spareReg != NULL, "freeHighWordRegister: blocked, must find a spareReg"); - - cursor = self()->registerCopy(self()->cg(), TR_HPR, targetRegisterHW, spareReg, currentInstruction); - //TR_ASSERTC( spareReg->isHighWordRegister(),self()->cg()->comp(), "\nfreeHighWordRegister: spareReg is not an HPR?\n"); - spareReg->setAssignedRegister(virtRegHW); - spareReg->setState(TR::RealRegister::Assigned); - virtRegHW->setAssignedRegister(spareReg); - } - else - { - if (spareReg) - { - cursor = self()->registerCopy(self()->cg(), TR_HPR, targetRegisterHW, spareReg, currentInstruction); - //TR_ASSERTC( spareReg->isHighWordRegister(),self()->cg()->comp(), "\nfreeHighWordRegister: spareReg is not an HPR?\n"); - spareReg->setAssignedRegister(virtRegHW); - spareReg->setState(TR::RealRegister::Assigned); - virtRegHW->setAssignedRegister(spareReg); - } - else - { - self()->spillRegister(currentInstruction, virtRegHW); - } - } - - targetRegisterHW->setAssignedRegister(NULL); - targetRegisterHW->setState(TR::RealRegister::Free); - return cursor; - } - - /** * Spill in a virt register, which frees up the assigned real reg, as we do * assignment in reverse-order of execution. @@ -4002,16 +3907,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction targetRegister->setAssignedRegister(virtualRegister); return cursor; } - - if (targetRegisterHW->getState() != TR::RealRegister::Free && targetRegisterHW->getState() != TR::RealRegister::Unlatched) - { - virtualRegister->block(); - targetRegister->setState(TR::RealRegister::Blocked); - // free up this highword register by either spilling it or moving it - cursor = self()->freeHighWordRegister(currentInstruction, targetRegisterHW); - virtualRegister->unblock(); - targetRegister->setState(TR::RealRegister::Free); - } } // the virtual register haven't be assigned to any real register yet if (currentAssignedRegister == NULL) @@ -4093,32 +3988,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction currentTargetVirtual->unblock(); } - // if currentTargetVirtual is low word only, spare Reg will be low word - // but virtual Reg could require full size, in this case, need to free the HW of target Reg - if (virtualRegister->is64BitReg()) - { - - // There is an extra check at the end to avoid the scenario in which virtualRegister is assigned to - // HPRx and we are attempting to coerce it to GPRx. In this case we do not need to spill HPRx, rather just copy it - if (targetRegisterHW->getState() != TR::RealRegister::Free && - targetRegisterHW->getState() != TR::RealRegister::Unlatched && - targetRegisterHW->getAssignedRegister() != virtualRegister) - { - if (targetRegisterHW->getAssignedRegister() && - targetRegisterHW->getAssignedRegister() != targetRegister->getAssignedRegister()) - { - //TR_ASSERTC( currentTargetVirtual->isLowWordOnly(),self()->cg()->comp(), "currentTargetVirtual is not LWOnly but HW is clobbered by another vreg?"); - virtualRegister->block(); - currentTargetVirtual->block(); - spareReg->block(); //to do: is this necessary? only need to block HPR? - // free up this highword register by either spilling it or moving it - cursor = self()->freeHighWordRegister(currentInstruction, targetRegisterHW); - spareReg->unblock(); - currentTargetVirtual->unblock(); - virtualRegister->unblock(); - } - } - } // find a free register if the virtual register hasn't been assigned to any real register // or it is a FPR for later use // virtual register is currently assigned to a different register, @@ -4326,123 +4195,13 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction } } - // If the target HPR was a spill slot - if (rk != TR_FPR && rk != TR_VRF && - currentTargetVirtual->getAssignedRegister() == NULL && - targetRegister->isHighWordRegister()) - { - self()->cg()->traceRegisterAssignment(" HW RA %R was spilled to %R, now need to spill again", currentTargetVirtual, targetRegister); - - // free this spill slot up first - // block virtual reg? - cursor = self()->freeHighWordRegister(currentInstruction, targetRegister); - - if (virtualRegister->is64BitReg() && !virtualRegister->isPlaceholderReg()) - { - // this could happen for OOL, when the reg deps on the top of slow path dictates that a collectible register must be - // spilled to a specific HPR - TR_ASSERT( virtualRegister->containsCollectedReference(), " OOL HPR spill: spilling a 64 bit scalar into HPR"); - - if (currentAssignedRegister == NULL) - { - if (virtualRegister->getTotalUseCount() != virtualRegister->getFutureUseCount() && - virtualRegister->getBackingStorage() != NULL) - { - // the virtual register is currently spilled to stack, now we need to spill it onto HPR - // load it back from the stack into HPR with STFH - // since we are working with compressed refs shift = 0, simply load 32-bit value into HPR. - TR::MemoryReference * tempMR = generateS390MemoryReference(currentNode, virtualRegister->getBackingStorage()->getSymbolReference(), self()->cg()); - - // is the offset correct? +4 big endian? - TR::MemoryReference * mr = generateS390MemoryReference(*tempMR, 4, self()->cg()); - - cursor = generateSILInstruction(self()->cg(), TR::InstOpCode::MVHI, currentNode, tempMR, 0, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::STFH, currentNode, targetRegister, mr, cursor); - self()->cg()->traceRAInstruction(cursor); - - // fix up states - // don't need to worry about protecting backing storage because we are leaving cold path OOL now - self()->cg()->freeSpill(virtualRegister->getBackingStorage(), 8, 0); - virtualRegister->setBackingStorage(NULL); - } - else - { - TR_ASSERT(comp, " OOL HPR spill: currentAssignedRegister is NULL but virtual reg is not spilled?"); - } - } - else - { - // the virtual register is currently assigned to a 64 bit real reg - // simply spill it to HPR and decompress - TR_ASSERT(currentAssignedRegister->isLowWordRegister(), " OOL HPR spill: 64-bit reg assigned to HPR and is not spilled to HPR"); - cursor = generateExtendedHighWordInstruction(currentNode, self()->cg(), TR::InstOpCode::LLHFR, currentAssignedRegister, targetRegister, 0, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - cursor = generateRILInstruction(self()->cg(), TR::InstOpCode::IIHF, currentNode, currentAssignedRegister, 0, cursor); - self()->cg()->traceRAInstruction(cursor); - - // fix up states - currentAssignedRegister->setAssignedRegister(NULL); - currentAssignedRegister->setState(TR::RealRegister::Free); - currentAssignedRegisterHW->setAssignedRegister(NULL); - currentAssignedRegisterHW->setState(TR::RealRegister::Free); - } - - // fix up the states - virtualRegister->setAssignedRegister(NULL); - targetRegister->setAssignedRegister(virtualRegister); - } - else - { - // we need to either assign or spill a 32-bit virtual register into a HPR - // the target HPR is now free - if (currentAssignedRegister == NULL) - { - if (virtualRegister->getTotalUseCount() != virtualRegister->getFutureUseCount()) - { - // if it is spilled to stack, load it back into HPR - TR_ASSERT(virtualRegister->getBackingStorage(), " OOL HPR spill: virtual reg is not spilled to stack nor HPR"); - TR::MemoryReference * tempMR = generateS390MemoryReference(currentNode, virtualRegister->getBackingStorage()->getSymbolReference(), self()->cg()); - - TR::MemoryReference * mr = generateS390MemoryReference(*tempMR, 4, self()->cg()); - - cursor = generateSILInstruction(self()->cg(), TR::InstOpCode::MVHI, currentNode, tempMR, 0, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::STFH, currentNode, targetRegister, mr, cursor); - self()->cg()->traceRAInstruction(cursor); - - // fix up states - // don't need to worry about protecting backing storage because we are leaving cold path OOL now - self()->cg()->freeSpill(virtualRegister->getBackingStorage(), 8, 0); - virtualRegister->setBackingStorage(NULL); - } - // and do nothing in case virtual reg is a placeholder - } - else - { - // the 32-bit virtual register is currently assigned to a real register - // do register copy - cursor = self()->registerCopy(self()->cg(), currentAssignedRegisterRK, currentAssignedRegister, targetRegister, currentInstruction); - currentAssignedRegister->setState(TR::RealRegister::Free); - currentAssignedRegister->setAssignedRegister(NULL); - } - - // fix up states - virtualRegister->setAssignedRegister(targetRegister); - targetRegister->setState(TR::RealRegister::Assigned); - targetRegister->setAssignedRegister(virtualRegister); - } - return cursor; - } + // in this case we cannot use the HPR of target reg as spareReg + if (virtualRegister->is64BitReg()) + spareReg = self()->findBestFreeRegister(currentInstruction, rk, currentTargetVirtual, availHighWordRegMap); else - { - // in this case we cannot use the HPR of target reg as spareReg - if (virtualRegister->is64BitReg()) - spareReg = self()->findBestFreeRegister(currentInstruction, rk, currentTargetVirtual, availHighWordRegMap); - else - // Look for a free reg in case we need a spare. - spareReg = self()->findBestFreeRegister(currentInstruction, rk, currentTargetVirtual); - } + // Look for a free reg in case we need a spare. + spareReg = self()->findBestFreeRegister(currentInstruction, rk, currentTargetVirtual); + self()->cg()->setRegisterAssignmentFlag(TR_IndirectCoercion); // If the source register is already assigned a realReg, we will try and @@ -4498,30 +4257,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction virtualRegister->unblock(); } - // if currentTargetVirtual is low word only, spare Reg will be low word - // but virtual Reg could require full size, in this case, need to free the HW of target Reg - if (virtualRegister->is64BitReg()) - { - if (targetRegisterHW->getState() != TR::RealRegister::Free && - targetRegisterHW->getState() != TR::RealRegister::Unlatched) - { - // if the targetReg and targetRegHW are assigned to two different virtual regs - if (targetRegisterHW->getAssignedRegister() && - targetRegisterHW->getAssignedRegister() != targetRegister->getAssignedRegister()) - { - //TR_ASSERTC( currentTargetVirtual->isLowWordOnly(),self()->cg()->comp(), "currentTargetVirtual is not LWOnly but HW is clobbered by another vreg?"); - virtualRegister->block(); - currentTargetVirtual->block(); - spareReg->block(); //to do: is this necessary? only need to block HPR? - // free up this highword register by either spilling it or moving it - cursor = self()->freeHighWordRegister(currentInstruction, targetRegisterHW); - spareReg->unblock(); - currentTargetVirtual->unblock(); - virtualRegister->unblock(); - } - } - } - // Spill policy decided the best reg to spill was not the targetReg, so move target // to the spareReg, and move the source reg to the target. if (targetRegister->getRegisterNumber() != spareReg->getRegisterNumber() && !doNotRegCopy) @@ -4692,29 +4427,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction virtualRegister->unblock(); } - // if currentTargetVirtual is low word only, spare Reg will be low word - // but virtual Reg could require full size, in this case, need to free the HW of target Reg - if (virtualRegister->is64BitReg()) - { - if (targetRegisterHW->getState() != TR::RealRegister::Free && - targetRegisterHW->getState() != TR::RealRegister::Unlatched) - { - if (targetRegisterHW->getAssignedRegister() && - targetRegisterHW->getAssignedRegister() != targetRegister->getAssignedRegister()) - { - //TR_ASSERTC( currentTargetVirtual->isLowWordOnly(),self()->cg()->comp(), "currentTargetVirtual is not LWOnly but HW is clobbered by another vreg?"); - virtualRegister->block(); - currentTargetVirtual->block(); - spareReg->block(); //to do: is this necessary? only need to block HPR? - // free up this highword register by either spilling it or moving it - cursor = self()->freeHighWordRegister(currentInstruction, targetRegisterHW); - spareReg->unblock(); - currentTargetVirtual->unblock(); - virtualRegister->unblock(); - } - } - } - // If we chose to spill a reg that wasn't the target, we use the new space // to free up the target. if (targetRegister->getRegisterNumber() != spareReg->getRegisterNumber() && !doNotRegCopy) diff --git a/compiler/z/codegen/OMRMachine.hpp b/compiler/z/codegen/OMRMachine.hpp index b04aef5357f..65a86f6c819 100644 --- a/compiler/z/codegen/OMRMachine.hpp +++ b/compiler/z/codegen/OMRMachine.hpp @@ -343,7 +343,6 @@ class OMR_EXTENSIBLE Machine : public OMR::Machine TR::RealRegister *targetReal, bool is64BitReg); - TR::Instruction * freeHighWordRegister(TR::Instruction *currentInstruction, TR::RealRegister *targetRegisterHW); void spillRegister(TR::Instruction *currentInstruction, TR::Register *virtReg, uint32_t availHighWordRegMap = -1); TR::RealRegister *reverseSpillState(TR::Instruction *currentInstruction, From ac48efab9b9e0b3c6156e46c8a9520bd7825aed2 Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Tue, 5 Mar 2019 13:23:20 -0500 Subject: [PATCH 08/23] Fold UpgradedBlockedList This list was used to keep track of blocked registers (HPR/GPR) that upgrades/spills etc. should not use. Signed-off-by: Filip Jeremic --- compiler/z/codegen/OMRCodeGenerator.cpp | 3 --- compiler/z/codegen/OMRInstruction.cpp | 7 ------ compiler/z/codegen/OMRMachine.cpp | 33 +------------------------ compiler/z/codegen/OMRMachine.hpp | 15 ++--------- 4 files changed, 3 insertions(+), 55 deletions(-) diff --git a/compiler/z/codegen/OMRCodeGenerator.cpp b/compiler/z/codegen/OMRCodeGenerator.cpp index 058b924996a..a0f52d6abeb 100644 --- a/compiler/z/codegen/OMRCodeGenerator.cpp +++ b/compiler/z/codegen/OMRCodeGenerator.cpp @@ -2014,9 +2014,6 @@ OMR::Z::CodeGenerator::doRegisterAssignment(TR_RegisterKinds kindsToAssign) currBlock->setHasBeenVisited(false); } - // Be stingy with allocating the blocked list (for HPR upgrades). Space requirement is small, but it adds up - self()->machine()->allocateUpgradedBlockedList(new (self()->comp()->trStackMemory()) TR_Stack(self()->comp()->trMemory(), 16, true, stackAlloc)); - while (instructionCursor) { TR::Node *treeNode=instructionCursor->getNode(); diff --git a/compiler/z/codegen/OMRInstruction.cpp b/compiler/z/codegen/OMRInstruction.cpp index 5ec0a7543af..9f3e7cc3424 100644 --- a/compiler/z/codegen/OMRInstruction.cpp +++ b/compiler/z/codegen/OMRInstruction.cpp @@ -1629,13 +1629,6 @@ OMR::Z::Instruction::assignOrderedRegisters(TR_RegisterKinds kindToBeAssigned) } // Unblock everything, as we are done assigning for this instr self()->unblock(_sourceReg, _sourceRegSize, _targetReg, _targetRegSize, _sourceMem, _targetMem); - /* Unblock registers that were Assigned and then Blocked in deeper stack frames of RA (src/target is HPR/GPR). */ - TR::RealRegister * reg = NULL; - while(reg = self()->cg()->machine()->getNextRegFromUpgradedBlockedList()) - { - self()->cg()->traceRegisterAssignment("Restoring blocked register %R (0x%p) to previous state", reg, reg); - reg->unblock(); - } } void diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index 8c490b353fa..54d9769f9bf 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -1198,9 +1198,7 @@ OMR::Z::Machine::assignBestRegisterSingle(TR::Register *targetRegister, TR::Instruction * cursor = generateExtendedHighWordInstruction(currInst->getNode(), self()->cg(), TR::InstOpCode::LHLR, assignedRegister, assignedLowWordRegister, 0, appendInst); - self()->addToUpgradedBlockedList(assignedRegister) ? - assignedRegister->setState(TR::RealRegister::Blocked): - assignedRegister->setState(TR::RealRegister::Free); + assignedRegister->setState(TR::RealRegister::Blocked); targetRegister->setAssignedRegister(assignedLowWordRegister); assignedLowWordRegister->setAssignedRegister(targetRegister); @@ -2956,35 +2954,6 @@ OMR::Z::Machine::findRegNotUsedInInstruction(TR::Instruction *currentInstructio return spill; } -void -OMR::Z::Machine::allocateUpgradedBlockedList(TR_Stack *mem) - { - _blockedUpgradedRegList = mem; - } - -bool -OMR::Z::Machine::addToUpgradedBlockedList(TR::RealRegister * reg) - { - if (reg == NULL) - return false; - self()->cg()->traceRegisterAssignment("Adding %s (0x%p) to blocked reg list", getRegisterName(reg,self()->cg()), reg); - _blockedUpgradedRegList->push(reg); - return true; - } - -TR::RealRegister * -OMR::Z::Machine::getNextRegFromUpgradedBlockedList() - { - if (_blockedUpgradedRegList->isEmpty()) - return NULL; - TR::RealRegister * reg = _blockedUpgradedRegList->pop(); - TR_ASSERT(reg->getAssignedRegister() == NULL, - "Register %s (0x%p) from Blocked-list has assigned reg %p", getRegisterName(reg,self()->cg()), reg, reg->getAssignedRegister()); - TR_ASSERT(reg->getState() == TR::RealRegister::Blocked, - "Register %s (0x%p) from Blocked-list is not in Blocked state", getRegisterName(reg,self()->cg()), reg); - return reg; - } - /** * Spill all high regs on calls */ diff --git a/compiler/z/codegen/OMRMachine.hpp b/compiler/z/codegen/OMRMachine.hpp index 65a86f6c819..e5c2eb6612b 100644 --- a/compiler/z/codegen/OMRMachine.hpp +++ b/compiler/z/codegen/OMRMachine.hpp @@ -192,10 +192,7 @@ class OMR_EXTENSIBLE Machine : public OMR::Machine TR::Register *_assignedRegisterSnapShot[TR::RealRegister::NumRegisters]; uint32_t _globalRegisterNumberToRealRegisterMapSnapShot[TR::RealRegister::NumRegisters]; bool _containsHPRSpillSnapShot[TR::RealRegister::NumRegisters]; - - /** Used to keep track of blocked registers (HPR/GPR) that upgrades/spill's etc should not use. Typical stores ~0-3 registers. */ - TR_Stack *_blockedUpgradedRegList; - + TR_GlobalRegisterNumber _firstGlobalGPRRegisterNumber; TR_GlobalRegisterNumber _lastGlobalGPRRegisterNumber; TR_GlobalRegisterNumber _last8BitGlobalGPRRegisterNumber; @@ -296,15 +293,7 @@ class OMR_EXTENSIBLE Machine : public OMR::Machine TR::Instruction* currInst, uint64_t availRegMask=0x0000ffff); void freeBestFPRegisterPair(TR::RealRegister** firstReg, TR::RealRegister** lastReg, TR::Instruction* currInst, uint64_t availRegMask=0x0000ffff); - - // Access Register managed - TR::RealRegister* findVirtRegInHighWordRegister(TR::Register *virtReg); - - // Used to keep track of blocked GPR's during HPR upgrades/spills/copies to prevent clobbering - bool addToUpgradedBlockedList(TR::RealRegister * reg); - void allocateUpgradedBlockedList(TR_Stack * mem); - TR::RealRegister * getNextRegFromUpgradedBlockedList(); - + // High Register managed void spillAllVolatileHighRegisters(TR::Instruction *currentInstruction); From 433e171700fdd70b43e2cda6109644c4803c52b1 Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Tue, 5 Mar 2019 16:07:57 -0500 Subject: [PATCH 09/23] Fold needsHighWord as false The `findBestFreeRegister` API was aware of HPRs and no longer needs to be, so we remove the `needsHighWord` parameter as false and simplify the API. Signed-off-by: Filip Jeremic --- compiler/z/codegen/OMRMachine.cpp | 43 ++++++++++--------------------- compiler/z/codegen/OMRMachine.hpp | 3 +-- 2 files changed, 14 insertions(+), 32 deletions(-) diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index 54d9769f9bf..2b6af1bbf2a 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -2302,8 +2302,7 @@ TR::RealRegister * OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, TR_RegisterKinds rk, TR::Register *virtualReg, - uint64_t availRegMask, - bool needsHighWord) + uint64_t availRegMask) { uint32_t interference = 0; int32_t first, maskI, last; @@ -2349,11 +2348,6 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, } } - if (needsHighWord && preference !=0 && !TR::RealRegister::isHPR((TR::RealRegister::RegNum)preference)) - { - preference = 0; - } - uint64_t prefRegMask = TR::RealRegister::isRealReg((TR::RealRegister::RegNum)preference) ? _registerFile[preference]->getRealRegisterMask() : 0; if (liveRegOn && virtualReg != NULL) @@ -2417,7 +2411,7 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, /****************************************************************************************************************/ // Register Associations are best effort. If you really need to map a virtual to a real, use register pre/post dependency conditions. - if (self()->cg()->enableRegisterPairAssociation() && preference == TR::RealRegister::LegalEvenOfPair && !needsHighWord) + if (self()->cg()->enableRegisterPairAssociation() && preference == TR::RealRegister::LegalEvenOfPair) { // Check to see if there is a sibling already assigned if ((virtualReg->getSiblingRegister()) && @@ -2447,12 +2441,12 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, * If the desired register is indeed free use it. * If not, default to standard search which is broken into 4 categories: * If register pair associations are enabled: - * Preference needsHighWord? - * 1. TR::RealRegister::LegalEvenOfPair No - * 2. TR::RealRegister::LegalOddOfPair No - * 3. TR::RealRegister::LegalFirstOfFPPair N/A - * 4. TR::RealRegister::LegalSecondOfFPPair N/A - * 5. None of the above + * Preference + * 1. TR::RealRegister::LegalEvenOfPair + * 2. TR::RealRegister::LegalOddOfPair + * 3. TR::RealRegister::LegalFirstOfFPPair + * 4. TR::RealRegister::LegalSecondOfFPPair + * 5. None of the above */ if (virtualReg->is64BitReg()) { @@ -2490,7 +2484,7 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, } } } - else if (self()->cg()->enableRegisterPairAssociation() && preference == TR::RealRegister::LegalOddOfPair && !needsHighWord) + else if (self()->cg()->enableRegisterPairAssociation() && preference == TR::RealRegister::LegalOddOfPair) { // Check to see if there is a sibling already assigned if ((virtualReg->getSiblingRegister()) && @@ -2665,7 +2659,7 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, } else { - if (virtualReg->is64BitReg() && !needsHighWord) + if (virtualReg->is64BitReg()) { bool candidateLWFree = true; bool candidateHWFree = true; @@ -2714,10 +2708,7 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, TR::RealRegister * candidate = NULL; if (preference != 0 && (prefRegMask & availRegMask) && _registerFile[preference] != NULL) { - if (needsHighWord) - candidate = _registerFile[preference]->getHighWordRegister(); - else - candidate = _registerFile[preference]->getLowWordRegister(); + candidate = _registerFile[preference]->getLowWordRegister(); } if (candidate != NULL && (prefRegMask & availRegMask) && @@ -2792,7 +2783,7 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, } } - if (virtualReg->is64BitReg() && !needsHighWord) + if (virtualReg->is64BitReg()) { bool candidateLWFree = (candidate->getState() == TR::RealRegister::Free) || @@ -2831,15 +2822,7 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, } else { - if (needsHighWord) - { - candidate = _registerFile[i]->getHighWordRegister(); - tRegMask = candidate->getRealRegisterMask(); - } - else - { - candidate = _registerFile[i]->getLowWordRegister(); - } + candidate = _registerFile[i]->getLowWordRegister(); //self()->cg()->traceRegWeight(candidate, candidate->getWeight()); // Don't consider registers that can't be assigned. diff --git a/compiler/z/codegen/OMRMachine.hpp b/compiler/z/codegen/OMRMachine.hpp index e5c2eb6612b..8e1f5168f48 100644 --- a/compiler/z/codegen/OMRMachine.hpp +++ b/compiler/z/codegen/OMRMachine.hpp @@ -309,8 +309,7 @@ class OMR_EXTENSIBLE Machine : public OMR::Machine TR::RealRegister *findBestFreeRegister(TR::Instruction *currentInstruction, TR_RegisterKinds rk, TR::Register *virtualReg = NULL, - uint64_t availRegMask = 0xffffffff, - bool needsHighWord = false); + uint64_t availRegMask = 0xffffffff); TR::RealRegister *freeBestRegister(TR::Instruction *currentInstruction, TR::Register *virtReg, From 1aed13b878a3bee9a9d280dbf8e12f89c176af2c Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Tue, 5 Mar 2019 16:11:52 -0500 Subject: [PATCH 10/23] Fold availHighWordRegMap Similarly to `needsHighWord` the `availHighWordRegMap` parameter used in several APIs is no longer needed as there are no HPRs available for assignment. Signed-off-by: Filip Jeremic --- compiler/z/codegen/OMRMachine.cpp | 41 ++++++------------------------- compiler/z/codegen/OMRMachine.hpp | 2 +- 2 files changed, 9 insertions(+), 34 deletions(-) diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index 2b6af1bbf2a..f3edafe4b12 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -3223,16 +3223,8 @@ OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Regi best = best->getLowWordRegister(); } - // If we spill into highword, make sure to not to spill it into the one that will clobber fullsize reg - if (virtReg->is64BitReg() || doNotSpillToSiblingHPR) - { - uint32_t availHighWordRegMap = ~(toRealRegister(best->getHighWordRegister())->getRealRegisterMask()) & availRegMask & 0xffff0000; - self()->spillRegister(currentInstruction, candidates[0], availHighWordRegMap); - } - else - { - self()->spillRegister(currentInstruction, candidates[0]); - } + self()->spillRegister(currentInstruction, candidates[0]); + return best; } @@ -3244,15 +3236,7 @@ void OMR::Z::Machine::freeRealRegister(TR::Instruction *currentInstruction, TR:: TR::Compilation *comp = self()->cg()->comp(); TR::Register *virtReg=targetReal->getAssignedRegister(); - if (is64BitReg) - { - uint32_t availHighWordRegMap = ~(toRealRegister(targetReal->getHighWordRegister())->getRealRegisterMask()) & 0xffff0000; - self()->spillRegister(currentInstruction, virtReg, availHighWordRegMap); - } - else - { - self()->spillRegister(currentInstruction, virtReg); - } + self()->spillRegister(currentInstruction, virtReg); } /** @@ -3264,7 +3248,7 @@ void OMR::Z::Machine::freeRealRegister(TR::Instruction *currentInstruction, TR:: * A GPRX, .... // use GPRX */ void -OMR::Z::Machine::spillRegister(TR::Instruction * currentInstruction, TR::Register* virtReg, uint32_t availHighWordRegMap) +OMR::Z::Machine::spillRegister(TR::Instruction * currentInstruction, TR::Register* virtReg) { TR::Compilation *comp = self()->cg()->comp(); TR::InstOpCode::Mnemonic opCode; @@ -4311,24 +4295,15 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction spillTargetHWReg = true; } } - // In zLinux, GPR6 may be used for param passing, in this case, we can't spill to it - if (TR::Compiler->target.isLinux()) - { - // HPR7-12 are available - self()->spillRegister(currentInstruction, currentTargetVirtual, availHWRegs & 0x1F800000); - } - else - { - // can only spill to preserved registers (HPR6-HPR12) - self()->spillRegister(currentInstruction, currentTargetVirtual, availHWRegs & 0x1FC00000); - //spillRegister(currentInstruction, currentTargetVirtual, 0x1FC00000); - } + + self()->spillRegister(currentInstruction, currentTargetVirtual); + targetRegister->setState(TR::RealRegister::Unlatched); targetRegister->setAssignedRegister(NULL); if (spillTargetHWReg) { - self()->spillRegister(currentInstruction, targetRegisterHW->getAssignedRegister(), 0); + self()->spillRegister(currentInstruction, targetRegisterHW->getAssignedRegister()); } if (currentTargetVirtual->is64BitReg()) diff --git a/compiler/z/codegen/OMRMachine.hpp b/compiler/z/codegen/OMRMachine.hpp index 8e1f5168f48..b5e83838fb9 100644 --- a/compiler/z/codegen/OMRMachine.hpp +++ b/compiler/z/codegen/OMRMachine.hpp @@ -331,7 +331,7 @@ class OMR_EXTENSIBLE Machine : public OMR::Machine TR::RealRegister *targetReal, bool is64BitReg); - void spillRegister(TR::Instruction *currentInstruction, TR::Register *virtReg, uint32_t availHighWordRegMap = -1); + void spillRegister(TR::Instruction *currentInstruction, TR::Register *virtReg); TR::RealRegister *reverseSpillState(TR::Instruction *currentInstruction, TR::Register *spilledRegister, From 703855e5dd93735b82da1cd51b5f32edb125c69f Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Tue, 5 Mar 2019 16:18:01 -0500 Subject: [PATCH 11/23] Fix up freeBestRegister parameters With the removal of `availHighWordRegMap` several of the default parameters of the `freeBestRegister` API are now "misplaced", or better put, not in the best order. In this commit we fix up the parameters to something more intuitive. Signed-off-by: Filip Jeremic --- compiler/z/codegen/OMRMachine.cpp | 31 ++++++++++--------------------- compiler/z/codegen/OMRMachine.hpp | 4 +--- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index f3edafe4b12..98c935c4fb8 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -1059,7 +1059,7 @@ OMR::Z::Machine::findBestRegisterForShuffle(TR::Instruction *currentInstruction, // find a free register if ((newRegister = self()->findBestFreeRegister(currentInstruction, kindOfRegister, currentAssignedRegister, availRegMask)) == NULL) { - newRegister = self()->freeBestRegister(currentInstruction, currentAssignedRegister, kindOfRegister, availRegMask); + newRegister = self()->freeBestRegister(currentInstruction, currentAssignedRegister, kindOfRegister); } // unblock if we blocked target reg of the instruction if (blockingRegister) @@ -1192,7 +1192,7 @@ OMR::Z::Machine::assignBestRegisterSingle(TR::Register *targetRegister, if ((assignedLowWordRegister = self()->findBestFreeRegister(currInst, kindOfRegister, targetRegister, availRegMask)) == NULL) { //assignedRegister->block(); - assignedLowWordRegister = self()->freeBestRegister(currInst, targetRegister, kindOfRegister, availRegMask); + assignedLowWordRegister = self()->freeBestRegister(currInst, targetRegister, kindOfRegister); //assignedRegister->unblock(); } @@ -1262,17 +1262,7 @@ OMR::Z::Machine::assignBestRegisterSingle(TR::Register *targetRegister, // If no free reg available, free one up if ((assignedRegister = self()->findBestFreeRegister(currInst, kindOfRegister, targetRegister, availRegMask)) == NULL) { - if (targetRegister->is64BitReg()) - { - // do not highword spill to itself for 64bit reg - //traceMsg(comp,"\nDo not spill to its own HPR!"); - assignedRegister = self()->freeBestRegister(currInst, targetRegister, kindOfRegister, availRegMask, false, true); - } - else - { - //traceMsg(comp,"\nCan spill to its own HPR!"); - assignedRegister = self()->freeBestRegister(currInst, targetRegister, kindOfRegister, availRegMask); - } + assignedRegister = self()->freeBestRegister(currInst, targetRegister, kindOfRegister); } } @@ -2971,8 +2961,7 @@ OMR::Z::Machine::spillAllVolatileHighRegisters(TR::Instruction *currentInstructi //////////////////////////////////////////////////// TR::RealRegister * -OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Register * virtReg, TR_RegisterKinds rk, - uint64_t availRegMask, bool allowNullReturn, bool doNotSpillToSiblingHPR) +OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Register * virtReg, TR_RegisterKinds rk, bool allowNullReturn) { self()->cg()->traceRegisterAssignment("FREE BEST REGISTER FOR %R", virtReg); TR::Compilation *comp = self()->cg()->comp(); @@ -3911,14 +3900,14 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction { // if we end up spilling currentTargetVirtual to HPR, make sure to not pick the HPR of targetRegister since it will not // free up the full 64 bit register - spareReg = self()->freeBestRegister(currentInstruction, currentTargetVirtual, currentTargetVirtual->getKind(), availHighWordRegMap, true, true); + spareReg = self()->freeBestRegister(currentInstruction, currentTargetVirtual, currentTargetVirtual->getKind(), true); } else { // we can allow freeBestRegister() to return NULL here, as long as we can perform register exchange later via memory // and take a bad OSC penalty // todo: fix HW RA to enable register exchange later - spareReg = self()->freeBestRegister(currentInstruction, currentTargetVirtual, currentTargetVirtual->getKind(), 0xffff, true); + spareReg = self()->freeBestRegister(currentInstruction, currentTargetVirtual, currentTargetVirtual->getKind(), true); } virtualRegister->unblock(); currentTargetVirtual->unblock(); @@ -4166,11 +4155,11 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction { // if we end up spilling currentTargetVirtual to HPR, make sure to not pick the HPR of targetRegister since it will not // free up the full 64 bit register - spareReg = self()->freeBestRegister(currentInstruction, currentTargetVirtual, currentTargetVirtual->getKind(), availHighWordRegMap, false, true); + spareReg = self()->freeBestRegister(currentInstruction, currentTargetVirtual, currentTargetVirtual->getKind()); } else { - spareReg = self()->freeBestRegister(currentInstruction, currentTargetVirtual, currentTargetVirtual->getKind(), availHighWordRegMap, true); + spareReg = self()->freeBestRegister(currentInstruction, currentTargetVirtual, currentTargetVirtual->getKind(), true); } // For some reason (blocked/locked regs etc), we couldn't find a spare reg so spill the virtual in the target and use it for coercion @@ -4327,11 +4316,11 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction { // if we end up spilling currentTargetVirtual to HPR, make sure to not pick the HPR of targetRegister since it will not // free up the full 64 bit register - spareReg = self()->freeBestRegister(currentInstruction, currentTargetVirtual, currentTargetVirtual->getKind(), availHighWordRegMap, false, true); + spareReg = self()->freeBestRegister(currentInstruction, currentTargetVirtual, currentTargetVirtual->getKind()); } else { - spareReg = self()->freeBestRegister(currentInstruction, currentTargetVirtual, currentTargetVirtual->getKind(), availHighWordRegMap, true); + spareReg = self()->freeBestRegister(currentInstruction, currentTargetVirtual, currentTargetVirtual->getKind(), true); } // For some reason (blocked/locked regs etc), we couldn't find a spare reg so spill the virtual in the target and use it for coercion diff --git a/compiler/z/codegen/OMRMachine.hpp b/compiler/z/codegen/OMRMachine.hpp index b5e83838fb9..556426bb63c 100644 --- a/compiler/z/codegen/OMRMachine.hpp +++ b/compiler/z/codegen/OMRMachine.hpp @@ -314,9 +314,7 @@ class OMR_EXTENSIBLE Machine : public OMR::Machine TR::RealRegister *freeBestRegister(TR::Instruction *currentInstruction, TR::Register *virtReg, TR_RegisterKinds rk, - uint64_t availRegMask = 0xffffffff, - bool allowNullReturn = false, - bool doNotSpillToSiblingHPR = false); + bool allowNullReturn = false); TR::RealRegister *findBestRegisterForShuffle(TR::Instruction *currentInstruction, TR::Register *currentAssignedRegister, From 5ae2f87f69c185be1dccacabe088b36d977701ee Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Tue, 5 Mar 2019 17:05:17 -0500 Subject: [PATCH 12/23] Do not generate HPR register dependencies With HPRs almost gone out of the picture we can stop generating HPR register dependencies since nothing can be assigned to them. Note that the only piece we really need to keep is the KillVolHighRegs register dependency which is used to evict volatile HPRs on 32-bit linkage points. This commit will greatly improve the compile time of methods as we no longer have to traverse as many dependencies in quite a few local RA locations. Signed-off-by: Filip Jeremic --- compiler/codegen/OMRCodeGenerator.hpp | 1 - compiler/ras/Debug.cpp | 10 - compiler/z/codegen/BinaryAnalyser.hpp | 5 +- compiler/z/codegen/OMRCodeGenerator.cpp | 36 ---- compiler/z/codegen/OMRCodeGenerator.hpp | 9 +- compiler/z/codegen/OMRInstruction.cpp | 112 +---------- compiler/z/codegen/OMRLinkage.cpp | 36 +--- compiler/z/codegen/OMRMachine.cpp | 198 +++---------------- compiler/z/codegen/OMRRegisterDependency.cpp | 58 +----- compiler/z/codegen/OMRTreeEvaluator.cpp | 7 - compiler/z/codegen/S390Debug.cpp | 35 ---- 11 files changed, 33 insertions(+), 474 deletions(-) diff --git a/compiler/codegen/OMRCodeGenerator.hpp b/compiler/codegen/OMRCodeGenerator.hpp index 3b2cc85a091..e57ffd77c76 100644 --- a/compiler/codegen/OMRCodeGenerator.hpp +++ b/compiler/codegen/OMRCodeGenerator.hpp @@ -1339,7 +1339,6 @@ class OMR_EXTENSIBLE CodeGenerator bool isLiteralPoolOnDemandOn () { return false; } bool supportsOnDemandLiteralPool() { return false; } bool supportsDirectIntegralLoadStoresFromLiteralPool() { return false; } - bool supportsHighWordFacility() { return false; } bool inlineDirectCall(TR::Node *node, TR::Register *&resultReg) { return false; } diff --git a/compiler/ras/Debug.cpp b/compiler/ras/Debug.cpp index 6c500ed8ff4..cdb333ff920 100644 --- a/compiler/ras/Debug.cpp +++ b/compiler/ras/Debug.cpp @@ -4725,16 +4725,6 @@ TR_Debug::traceRegisterAssignment(TR::Instruction *instr, bool insertedByRA, boo trfprintf(_file, "\n"); } #if defined(TR_TARGET_S390) - if (_registerKindsToAssign & TR_HPR_Mask) - { - trfprintf(_file, "\n"); - TR::RegisterIterator *iter = _cg->getHPRegisterIterator(); - for (TR::Register *hpr = iter->getFirst(); hpr; hpr = iter->getNext()) - { - printFullRegInfo(_file, hpr); - } - trfprintf(_file, "\n"); - } if (_registerKindsToAssign & TR_VRF_Mask && _cg->getSupportsVectorRegisters()) { trfprintf(_file, "\n"); diff --git a/compiler/z/codegen/BinaryAnalyser.hpp b/compiler/z/codegen/BinaryAnalyser.hpp index 876c9a700f1..c34fe8a76d2 100644 --- a/compiler/z/codegen/BinaryAnalyser.hpp +++ b/compiler/z/codegen/BinaryAnalyser.hpp @@ -65,10 +65,7 @@ class TR_S390BinaryAnalyser : public TR_Analyser { TR::InstOpCode::Mnemonic loadOp = TR::InstOpCode::getLoadRegOpCode(); - if (cg()->supportsHighWordFacility()) - { - loadOp = TR::InstOpCode::LR; - } + genericAnalyser(root,regToRegOpCode,memToRegOpCode,loadOp); } diff --git a/compiler/z/codegen/OMRCodeGenerator.cpp b/compiler/z/codegen/OMRCodeGenerator.cpp index a0f52d6abeb..c497068acfe 100644 --- a/compiler/z/codegen/OMRCodeGenerator.cpp +++ b/compiler/z/codegen/OMRCodeGenerator.cpp @@ -651,11 +651,6 @@ OMR::Z::CodeGenerator::CodeGenerator() _callsForPreloadList = new (self()->trHeapMemory()) TR::list(getTypedAllocator(comp->allocator())); } - if (TR::Compiler->target.cpu.getS390SupportsHPRDebug() && !comp->getOption(TR_DisableHighWordRA) && !comp->getOption(TR_MimicInterpreterFrameShape)) - { - self()->setSupportsHighWordFacility(true); - } - self()->setOnDemandLiteralPoolRun(true); self()->setGlobalStaticBaseRegisterOn(false); @@ -812,7 +807,6 @@ OMR::Z::CodeGenerator::CodeGenerator() { self()->setGPRegisterIterator(new (self()->trHeapMemory()) TR::RegisterIterator(self()->machine(), TR::RealRegister::FirstGPR, TR::RealRegister::LastAssignableGPR)); self()->setFPRegisterIterator(new (self()->trHeapMemory()) TR::RegisterIterator(self()->machine(), TR::RealRegister::FirstFPR, TR::RealRegister::LastFPR)); - self()->setHPRegisterIterator(new (self()->trHeapMemory()) TR::RegisterIterator(self()->machine(), TR::RealRegister::FirstHPR, TR::RealRegister::LastHPR)); self()->setVRFRegisterIterator(new (self()->trHeapMemory()) TR::RegisterIterator(self()->machine(), TR::RealRegister::FirstVRF, TR::RealRegister::LastVRF)); } @@ -1924,7 +1918,6 @@ OMR::Z::CodeGenerator::prepareRegistersForAssignment() } int32_t lockedGPRs = 0; - int32_t lockedHPRs = 0; int32_t lockedFPRs = 0; int32_t lockedVRFs = 0; @@ -1936,13 +1929,6 @@ OMR::Z::CodeGenerator::prepareRegistersForAssignment() ++lockedGPRs; } - for (int32_t i = TR::RealRegister::FirstHPR; i <= TR::RealRegister::LastHPR; ++i) - { - TR::RealRegister* realReg = machine->getRealRegister((TR::RealRegister::RegNum)i); - if (realReg->getState() == TR::RealRegister::Locked) - ++lockedHPRs; - } - for (int32_t i = TR::RealRegister::FirstFPR; i <= TR::RealRegister::LastFPR; ++i) { TR::RealRegister* realReg = machine->getRealRegister((TR::RealRegister::RegNum)i); @@ -1958,7 +1944,6 @@ OMR::Z::CodeGenerator::prepareRegistersForAssignment() } machine->setNumberOfLockedRegisters(TR_GPR, lockedGPRs); - machine->setNumberOfLockedRegisters(TR_HPR, lockedHPRs); machine->setNumberOfLockedRegisters(TR_FPR, lockedFPRs); machine->setNumberOfLockedRegisters(TR_VRF, lockedVRFs); @@ -2068,9 +2053,6 @@ OMR::Z::CodeGenerator::doRegisterAssignment(TR_RegisterKinds kindsToAssign) self()->tracePreRAInstruction(instructionCursor); - if (self()->supportsHighWordFacility()) - self()->setAvailableHPRSpillMask(0xffff0000); - prevInstruction = instructionCursor->getPrev(); if (instructionCursor->getNode()->getOpCodeValue() == TR::BBEnd) @@ -4425,24 +4407,6 @@ OMR::Z::CodeGenerator::buildRegisterMapForInstruction(TR_GCStackMap * map) TR_InternalPointerMap * internalPtrMap = NULL; TR::GCStackAtlas * atlas = self()->getStackAtlas(); - - if (self()->supportsHighWordFacility()) - { - for (int32_t i = TR::RealRegister::FirstHPR; i <= TR::RealRegister::LastHPR; i++) - { - TR::RealRegister * realReg = self()->machine()->getRealRegister((TR::RealRegister::RegNum) i); - if (realReg->getHasBeenAssignedInMethod()) - { - TR::Register * virtReg = realReg->getAssignedRegister(); - if (virtReg && virtReg->containsCollectedReference() && virtReg->getAssignedRegister() == NULL) - { - // 2 bits per register, '10' means HPR has collectible, '11' means both HPR and GPR have collectibles - map->setHighWordRegisterBits(1 << ((i - TR::RealRegister::FirstHPR)*2 +1) ); - //traceMsg(comp(), "\nsetting HPR regmap 0x%x\n", 1 << ((i - TR::RealRegister::FirstHPR)*2 + 1)); - } - } - } - } for (int32_t i = TR::RealRegister::FirstGPR; i <= TR::RealRegister::LastAssignableGPR; i++) { TR::RealRegister * realReg = self()->machine()->getRealRegister((TR::RealRegister::RegNum) i); diff --git a/compiler/z/codegen/OMRCodeGenerator.hpp b/compiler/z/codegen/OMRCodeGenerator.hpp index 299074e0192..1ddae09de21 100644 --- a/compiler/z/codegen/OMRCodeGenerator.hpp +++ b/compiler/z/codegen/OMRCodeGenerator.hpp @@ -290,9 +290,6 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator bool shouldYankCompressedRefs() { return true; } - TR::RegisterIterator *getHPRegisterIterator() {return _hpRegisterIterator; } - TR::RegisterIterator *setHPRegisterIterator(TR::RegisterIterator *iter) {return _hpRegisterIterator = iter; } - bool supportsJITFreeSystemStackPointer() { return false; } TR::RegisterIterator *getVRFRegisterIterator() {return _vrfRegisterIterator; } TR::RegisterIterator *setVRFRegisterIterator(TR::RegisterIterator *iter) {return _vrfRegisterIterator = iter;} @@ -713,9 +710,6 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator bool supportsDirectIntegralLoadStoresFromLiteralPool(); - void setSupportsHighWordFacility(bool val) { _cgFlags.set(S390CG_supportsHighWordFacility, val); } - bool supportsHighWordFacility() { return _cgFlags.testAny(S390CG_supportsHighWordFacility); } - void setCanExceptByTrap(bool val) { _cgFlags.set(S390CG_canExceptByTrap, val); } virtual bool canExceptByTrap() { return _cgFlags.testAny(S390CG_canExceptByTrap); } @@ -849,7 +843,6 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator TR_HashTab * _interfaceSnippetToPICsListHashTab; - TR::RegisterIterator *_hpRegisterIterator; TR::RegisterIterator *_vrfRegisterIterator; TR_Array _transientLongRegisters; @@ -906,7 +899,7 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator S390CG_condCodeShouldBePreserved = 0x00004000, S390CG_enableBranchPreload = 0x00008000, S390CG_globalStaticBaseRegisterOn = 0x00010000, - S390CG_supportsHighWordFacility = 0x00020000, + // Available = 0x00020000, S390CG_canExceptByTrap = 0x00040000, S390CG_enableTLHPrefetching = 0x00080000, S390CG_enableBranchPreloadForCalls = 0x00100000, diff --git a/compiler/z/codegen/OMRInstruction.cpp b/compiler/z/codegen/OMRInstruction.cpp index 9f3e7cc3424..2807f707ba9 100644 --- a/compiler/z/codegen/OMRInstruction.cpp +++ b/compiler/z/codegen/OMRInstruction.cpp @@ -340,33 +340,8 @@ OMR::Z::Instruction::matchesAnyRegister(TR::Register * reg, TR::Register * instR TR::RealRegister * realInstReg1 = NULL; TR::RealRegister * realInstReg2 = NULL; - bool enableHighWordRA = - self()->cg()->supportsHighWordFacility() && - (reg->getKind()!=TR_FPR) && - (instReg->getKind()!=TR_FPR) && - (reg->getKind()!=TR_VRF) && - (instReg->getKind()!=TR_VRF); - - if (enableHighWordRA && reg->getRealRegister()) - { - realReg = (TR::RealRegister *)reg; - if (realReg->isHighWordRegister()) - { - // Highword aliasing low word regs - realReg = realReg->getLowWordRegister(); - } - } - if (regPair) { - // if we are matching real regs - if (enableHighWordRA && regPair->getHighOrder()->getRealRegister()) - { - // reg pairs do not use HPRs - realInstReg1 = (TR::RealRegister *)(regPair->getHighOrder()); - realInstReg2 = toRealRegister(regPair->getLowOrder()); - return realReg == realInstReg1 || realReg == realInstReg2; - } // if we are matching virt regs if ((reg == regPair->getHighOrder()) || reg == regPair->getLowOrder()) { @@ -375,12 +350,6 @@ OMR::Z::Instruction::matchesAnyRegister(TR::Register * reg, TR::Register * instR } else { - // if we are matching real regs - if (enableHighWordRA && instReg->getRealRegister()) - { - realInstReg1 = (TR::RealRegister *)instReg; - return realReg == realInstReg1; - } // if we are matching virt regs if (reg == instReg) { @@ -764,17 +733,6 @@ OMR::Z::Instruction::assignRegisters(TR_RegisterKinds kindToBeAssigned) } } - if (self()->cg()->supportsHighWordFacility()) - { - for (int32_t i = TR::RealRegister::FirstHPR; i <= TR::RealRegister::LastHPR; i++) - { - TR::Register * virtReg = machine->getVirtualAssociatedWithReal((TR::RealRegister::RegNum) (i)); - if (virtReg) - { - virtReg->setAssociation(TR::RealRegister::NoReg); - } - } - } // Step 2 : loop through and set up the new associations (both on the machine and by associating the virtual // registers with their real dependencies) TR_S390RegisterDependencyGroup * depGroup = self()->getDependencyConditions()->getPostConditions(); @@ -784,14 +742,6 @@ OMR::Z::Instruction::assignRegisters(TR_RegisterKinds kindToBeAssigned) machine->setVirtualAssociatedWithReal((TR::RealRegister::RegNum) (j + 1), virtReg); } - if(self()->cg()->supportsHighWordFacility()) - { - for (int32_t j = 0; j < TR::RealRegister::LastHPR-TR::RealRegister::FirstHPR; ++j) - { - TR::Register * virtReg = depGroup->getRegisterDependency(j+last)->getRegister(); - machine->setVirtualAssociatedWithReal((TR::RealRegister::RegNum) (j + TR::RealRegister::FirstHPR), virtReg); - } - } machine->setRegisterWeightsFromAssociations(); } } @@ -1474,21 +1424,6 @@ OMR::Z::Instruction::assignOrderedRegisters(TR_RegisterKinds kindToBeAssigned) _targetReg[i]->block(); tgtAssigned[i] = 2; - - if (self()->cg()->supportsHighWordFacility()) - { - // don't need to block HPR here beacuse no Highword instruction uses register pair - // but make sure we do not spill to the targetReg's HPR (even if it became free) while assigning sourceReg - if (_targetReg[i]->getRegisterPair() && - _targetReg[i]->getRegisterPair()->getHighOrder()->getKind() != TR_FPR && - _targetReg[i]->getRegisterPair()->getHighOrder()->getKind() != TR_VRF) - { - uint32_t availHPRMask = self()->cg()->getAvailableHPRSpillMask(); - availHPRMask &= ~(toRealRegister(_targetReg[i]->getRegisterPair()->getHighOrder())->getHighWordRegister()->getRealRegisterMask()); - availHPRMask &= ~(toRealRegister(_targetReg[i]->getRegisterPair()->getLowOrder())->getHighWordRegister()->getRealRegisterMask()); - self()->cg()->setAvailableHPRSpillMask(availHPRMask); - } - } } for (i = 0; i < _sourceRegSize; ++i) { @@ -1519,23 +1454,7 @@ OMR::Z::Instruction::assignOrderedRegisters(TR_RegisterKinds kindToBeAssigned) targetRegIs64Bit = true; } _targetReg[i] = self()->assignRegisterNoDependencies(_targetReg[i]); - - if (self()->cg()->supportsHighWordFacility() && - _targetReg[i]->getKind() != TR_FPR && _targetReg[i]->getKind() != TR_VRF) - { - if (toRealRegister(_targetReg[i])->getState() == TR::RealRegister::Free && targetRegIs64Bit) - { - blockTargetHighword = true; - toRealRegister(_targetReg[i])->getHighWordRegister()->setState(TR::RealRegister::Blocked); - TR_ASSERT(i==0, "more than 1 HPR target regs need to be blocked?"); - } - - // make sure we do not spill to the targetReg's HPR later (even if it's free) - uint32_t availHPRMask = self()->cg()->getAvailableHPRSpillMask(); - availHPRMask &= ~(toRealRegister(_targetReg[i])->getHighWordRegister()->getRealRegisterMask()); - self()->cg()->setAvailableHPRSpillMask(availHPRMask); - } - + if (_targetReg[i]->getAssignedRegister()) { _targetReg[i]->getAssignedRegister()->block(); @@ -2207,35 +2126,6 @@ OMR::Z::Instruction::setUseDefRegisters(bool updateDependencies) } } } - - // set all HPRs to alias GPRs - if (self()->cg()->supportsHighWordFacility()) - { - if (_useRegs) - { - for (i=0;i<_useRegs->size();i++) - { - if (((*_useRegs)[i])->getRealRegister()) - { - TR::RealRegister * realReg = toRealRegister((*_useRegs)[i]); - if (realReg && realReg->isHighWordRegister()) - (*_useRegs)[i] = realReg->getLowWordRegister(); - } - } - } - if (_defRegs) - { - for (i=0;i<_defRegs->size();i++) - { - if (((*_defRegs)[i])->getRealRegister()) - { - TR::RealRegister * realReg = toRealRegister((*_defRegs)[i]); - if (realReg && realReg->isHighWordRegister()) - (*_defRegs)[i] = realReg->getLowWordRegister(); - } - } - } - } } // Return i'th source reg or NULL diff --git a/compiler/z/codegen/OMRLinkage.cpp b/compiler/z/codegen/OMRLinkage.cpp index 754952b9cdb..a344ed1cbc6 100644 --- a/compiler/z/codegen/OMRLinkage.cpp +++ b/compiler/z/codegen/OMRLinkage.cpp @@ -2450,38 +2450,6 @@ OMR::Z::Linkage::buildArgs(TR::Node * callNode, TR::RegisterDependencyConditions } } - dummyReg = NULL; - self()->killAndAssignRegister(killMask, dependencies, &dummyReg, REGNUM(TR::RealRegister::HPR0), self()->cg(), true, true ); - self()->killAndAssignRegister(killMask, dependencies, &dummyReg, REGNUM(TR::RealRegister::HPR1), self()->cg(), true, true ); - self()->killAndAssignRegister(killMask, dependencies, &dummyReg, REGNUM(TR::RealRegister::HPR2), self()->cg(), true, true ); - self()->killAndAssignRegister(killMask, dependencies, &dummyReg, REGNUM(TR::RealRegister::HPR3), self()->cg(), true, true ); - self()->killAndAssignRegister(killMask, dependencies, &dummyReg, REGNUM(TR::RealRegister::HPR14), self()->cg(), true, true ); - - // consider all HPR volatile on 31-bit - if (TR::Compiler->target.is32Bit()) - { - self()->killAndAssignRegister(killMask, dependencies, &dummyReg, REGNUM(TR::RealRegister::HPR6), self()->cg(), true, true ); - self()->killAndAssignRegister(killMask, dependencies, &dummyReg, REGNUM(TR::RealRegister::HPR7), self()->cg(), true, true ); - self()->killAndAssignRegister(killMask, dependencies, &dummyReg, REGNUM(TR::RealRegister::HPR8), self()->cg(), true, true ); - self()->killAndAssignRegister(killMask, dependencies, &dummyReg, REGNUM(TR::RealRegister::HPR9), self()->cg(), true, true ); - self()->killAndAssignRegister(killMask, dependencies, &dummyReg, REGNUM(TR::RealRegister::HPR10), self()->cg(), true, true ); - self()->killAndAssignRegister(killMask, dependencies, &dummyReg, REGNUM(TR::RealRegister::HPR11), self()->cg(), true, true ); - self()->killAndAssignRegister(killMask, dependencies, &dummyReg, REGNUM(TR::RealRegister::HPR12), self()->cg(), true, true ); - } - - if (TR::Compiler->target.isZOS()) - { - self()->killAndAssignRegister(killMask, dependencies, &dummyReg, REGNUM(TR::RealRegister::HPR15), self()->cg(), true, true ); - if (self()->cg()->supportsJITFreeSystemStackPointer()) - { - self()->killAndAssignRegister(killMask, dependencies, &dummyReg, REGNUM(TR::RealRegister::HPR4),self()->cg(), true, true ); - } - } - else - { - self()->killAndAssignRegister(killMask, dependencies, &dummyReg, REGNUM(TR::RealRegister::HPR4), self()->cg(), true, true ); - } - // spill all overlapped vector registers if vector linkage is enabled if (enableVectorLinkage) { @@ -2588,9 +2556,7 @@ OMR::Z::Linkage::killAndAssignRegister(int64_t killMask, TR::RegisterDependencyC { if (isAllocate) { - if (regNum >= TR::RealRegister::FirstHPR && regNum <= TR::RealRegister::LastHPR) - *virtualRegPtr = self()->cg()->allocateRegister(); - else if (regNum <= TR::RealRegister::LastGPR) + if (regNum <= TR::RealRegister::LastGPR) *virtualRegPtr = self()->cg()->allocateRegister(); else if (regNum <= TR::RealRegister::LastFPR) *virtualRegPtr = self()->cg()->allocateRegister(TR_FPR); diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index 98c935c4fb8..84bf0cbb6c6 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -213,8 +213,6 @@ OMR::Z::Machine::registerExchange(TR::CodeGenerator* cg, char * REG_EXCHANGE = "LR=Reg_exchg"; char * REG_PAIR = "LR=Reg_pair"; TR_Debug * debugObj = cg->getDebug(); - bool enableHighWordRA = cg->supportsHighWordFacility() && - rk != TR_FPR && rk != TR_VRF; TR::Machine *machine = cg->machine(); // exchange floating point registers @@ -315,27 +313,6 @@ OMR::Z::Machine::registerExchange(TR::CodeGenerator* cg, bool srcRegIsHPR = sourceReg->isHighWordRegister(); bool tgtRegIsHPR = targetReg->isHighWordRegister(); - if (enableHighWordRA) - { - if (srcRegIsHPR) - { - opLoad = TR::InstOpCode::LFH; - } - if (tgtRegIsHPR) - { - opStore = TR::InstOpCode::STFH; - } - - if (srcRegIsHPR != tgtRegIsHPR) - { - opLoadReg = tgtRegIsHPR? TR::InstOpCode::LHLR:InstOpCode::LLHFR; - } - else - { - opLoadReg = tgtRegIsHPR? TR::InstOpCode::LHHR:opLoadReg; - } - } - // exchange general purpose registers // if (middleReg == NULL) @@ -382,98 +359,36 @@ OMR::Z::Machine::registerExchange(TR::CodeGenerator* cg, bool middleRegIsHPR = middleReg->isHighWordRegister(); - if (enableHighWordRA) + if (srcRegIsHPR || tgtRegIsHPR) { - if (srcRegIsHPR || tgtRegIsHPR) - { - TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/HPR"); - } - else - { - TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/GPR"); - } - if (srcRegIsHPR != middleRegIsHPR) - { - currentInstruction = - generateRRInstruction(cg, srcRegIsHPR? TR::InstOpCode::LHLR:InstOpCode::LLHFR, currentNode, sourceReg, middleReg, precedingInstruction); - } - else - { - currentInstruction = - generateRRInstruction(cg, srcRegIsHPR? TR::InstOpCode::LHHR:opLoadReg, currentNode, sourceReg, middleReg, precedingInstruction); - } - cg->traceRAInstruction(currentInstruction); - if (debugObj) - { - debugObj->addInstructionComment(toS390RRInstruction(currentInstruction), REG_EXCHANGE); - } - - if (srcRegIsHPR != tgtRegIsHPR) - { - currentInstruction = - generateRRInstruction(cg, tgtRegIsHPR? TR::InstOpCode::LHLR:InstOpCode::LLHFR, currentNode, targetReg, sourceReg, precedingInstruction); - } - else - { - currentInstruction = - generateRRInstruction(cg, tgtRegIsHPR? TR::InstOpCode::LHHR:opLoadReg, currentNode, targetReg, sourceReg, precedingInstruction); - } - cg->traceRAInstruction(currentInstruction); - if (debugObj) - { - debugObj->addInstructionComment(toS390RRInstruction(currentInstruction), REG_EXCHANGE); - } - - if (middleRegIsHPR != tgtRegIsHPR) - { - currentInstruction = - generateRRInstruction(cg, middleRegIsHPR? TR::InstOpCode::LHLR:InstOpCode::LLHFR, currentNode, middleReg, targetReg, precedingInstruction); - } - else - { - currentInstruction = - generateRRInstruction(cg, middleRegIsHPR? TR::InstOpCode::LHHR:opLoadReg, currentNode, middleReg, targetReg, precedingInstruction); - } - - cg->traceRAInstruction(currentInstruction); - if (debugObj) - { - debugObj->addInstructionComment(toS390RRInstruction(currentInstruction), REG_EXCHANGE); - } + TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/HPR"); } else { - if (srcRegIsHPR || tgtRegIsHPR) - { - TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/HPR"); - } - else - { - TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/GPR"); - } - currentInstruction = - generateRRInstruction(cg, opLoadReg, currentNode, sourceReg, middleReg, precedingInstruction); - cg->traceRAInstruction(currentInstruction); - if (debugObj) - { - debugObj->addInstructionComment(toS390RRInstruction(currentInstruction), REG_EXCHANGE); - } + TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/GPR"); + } + currentInstruction = + generateRRInstruction(cg, opLoadReg, currentNode, sourceReg, middleReg, precedingInstruction); + cg->traceRAInstruction(currentInstruction); + if (debugObj) + { + debugObj->addInstructionComment(toS390RRInstruction(currentInstruction), REG_EXCHANGE); + } - currentInstruction = - generateRRInstruction(cg, opLoadReg, currentNode, targetReg, sourceReg, precedingInstruction); - cg->traceRAInstruction(currentInstruction); - if (debugObj) - { - debugObj->addInstructionComment(toS390RRInstruction(currentInstruction), REG_EXCHANGE); - } + currentInstruction = + generateRRInstruction(cg, opLoadReg, currentNode, targetReg, sourceReg, precedingInstruction); + cg->traceRAInstruction(currentInstruction); + if (debugObj) + { + debugObj->addInstructionComment(toS390RRInstruction(currentInstruction), REG_EXCHANGE); + } - currentInstruction = - generateRRInstruction(cg, opLoadReg, currentNode, middleReg, targetReg, precedingInstruction); - cg->traceRAInstruction(currentInstruction); - if (debugObj) - { - debugObj->addInstructionComment(toS390RRInstruction(currentInstruction), REG_EXCHANGE); - } + currentInstruction = + generateRRInstruction(cg, opLoadReg, currentNode, middleReg, targetReg, precedingInstruction); + cg->traceRAInstruction(currentInstruction); + if (debugObj) + { + debugObj->addInstructionComment(toS390RRInstruction(currentInstruction), REG_EXCHANGE); } } @@ -2309,11 +2224,8 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, if (comp->getOption(TR_Randomize)) { randomPreference = preference; - if (TR::RealRegister::isHPR((TR::RealRegister::RegNum)preference)) - { - randomPreference = self()->cg()->randomizer.randomInt(TR::RealRegister::FirstHPR,TR::RealRegister::LastHPR); - } - else if (TR::RealRegister::isFPR((TR::RealRegister::RegNum)preference)) + + if (TR::RealRegister::isFPR((TR::RealRegister::RegNum)preference)) { randomPreference = self()->cg()->randomizer.randomInt(TR::RealRegister::FirstFPR,TR::RealRegister::LastFPR); } @@ -5170,8 +5082,6 @@ OMR::Z::Machine::setRegisterWeightsFromAssociations() int32_t first = TR::RealRegister::FirstGPR; TR::Compilation *comp = self()->cg()->comp(); int32_t last = TR::RealRegister::LastAssignableVRF; - if (self()->cg()->supportsHighWordFacility()) - last = TR::RealRegister::LastHPR; for (int32_t i = first; i <= last; ++i) { @@ -5215,17 +5125,8 @@ OMR::Z::Machine::createRegisterAssociationDirective(TR::Instruction * cursor) { TR::Compilation *comp = self()->cg()->comp(); int32_t last = TR::RealRegister::LastAssignableVRF; - TR::RegisterDependencyConditions * associations; + TR::RegisterDependencyConditions * associations = new (self()->cg()->trHeapMemory(), TR_MemoryBase::RegisterDependencyConditions) TR::RegisterDependencyConditions(0, last, self()->cg()); - if (self()->cg()->supportsHighWordFacility()) - { - int32_t lastHPR = last + TR::RealRegister::LastHPR - TR::RealRegister::FirstHPR; - associations = new (self()->cg()->trHeapMemory(), TR_MemoryBase::RegisterDependencyConditions) TR::RegisterDependencyConditions(0, lastHPR, self()->cg()); - } - else - { - associations = new (self()->cg()->trHeapMemory(), TR_MemoryBase::RegisterDependencyConditions) TR::RegisterDependencyConditions(0, last, self()->cg()); - } // Go through the current associations held in the machine and put a copy of // that state out into the stream after the cursor // so that when the register assigner goes backwards through this point @@ -5237,16 +5138,6 @@ OMR::Z::Machine::createRegisterAssociationDirective(TR::Instruction * cursor) associations->addPostCondition(self()->getVirtualAssociatedWithReal(regNum), regNum); } - if (self()->cg()->supportsHighWordFacility()) - { - for (int32_t i = TR::RealRegister::FirstHPR; i < TR::RealRegister::LastHPR+1; i++) - { - TR::RealRegister::RegNum regNum = (TR::RealRegister::RegNum) (i); - associations->addPostCondition(self()->getVirtualAssociatedWithReal(regNum), regNum); - } - } - - TR::Instruction *cursor1 = new (self()->cg()->trHeapMemory(), TR_MemoryBase::S390Instruction) TR::Instruction(cursor, TR::InstOpCode::ASSOCREGS, associations, self()->cg()); if (cursor == self()->cg()->getAppendInstruction()) @@ -5391,21 +5282,6 @@ TR::RegisterDependencyConditions * OMR::Z::Machine::createDepCondForLiveGPRs(TR: c += spilledRegisterList ? spilledRegisterList->size() : 0; - if (self()->cg()->supportsHighWordFacility()) - { - for (i = TR::RealRegister::FirstHPR; i <= TR::RealRegister::LastHPR; i++) - { - if (self()->getRealRegister(i)->getState() == TR::RealRegister::Assigned && self()->getRealRegister(i)->getAssignedRegister()) - { - if (self()->getRealRegister(i)->getAssignedRegister() != self()->getRealRegister(i)->getLowWordRegister()->getAssignedRegister()) - c++; - // if a HPR is assigned to a virtReg but a virtReg is not assigned to HPR, we must have spilled the virtReg to HPR - if (!self()->getRealRegister(i)->getAssignedRegister()->getAssignedRegister()) - c++; - } - } - } - TR::RegisterDependencyConditions *deps = NULL; if (c) @@ -5428,26 +5304,6 @@ TR::RegisterDependencyConditions * OMR::Z::Machine::createDepCondForLiveGPRs(TR: virtReg->incFutureUseCount(); } } - if (self()->cg()->supportsHighWordFacility()) - { - for (i = TR::RealRegister::FirstHPR; i <= TR::RealRegister::LastHPR; i++) - { - if (self()->getRealRegister(i)->getState() == TR::RealRegister::Assigned && self()->getRealRegister(i)->getAssignedRegister()) - { - if(self()->getRealRegister(i)->getAssignedRegister() != self()->getRealRegister(i)->getLowWordRegister()->getAssignedRegister()) - { - deps->addPostCondition(self()->getRealRegister(i)->getAssignedRegister(),self()->getRealRegister(i)->getRegisterNumber()); - self()->getRealRegister(i)->getAssignedRegister()->incFutureUseCount(); - } - // if a HPR is assigned to a virtReg but a virtReg is not assigned to HPR, we must have spilled the virtReg to HPR - if(!self()->getRealRegister(i)->getAssignedRegister()->getAssignedRegister()) - { - // this is not a conflicting dependency rather a directive to tell RA to mark the virt reg as a HPR spill - deps->addPostCondition(self()->getRealRegister(i), TR::RealRegister::SpilledReg); - } - } - } - } } if (spilledRegisterList) diff --git a/compiler/z/codegen/OMRRegisterDependency.cpp b/compiler/z/codegen/OMRRegisterDependency.cpp index 093de857534..72eb77507d2 100644 --- a/compiler/z/codegen/OMRRegisterDependency.cpp +++ b/compiler/z/codegen/OMRRegisterDependency.cpp @@ -791,26 +791,6 @@ TR_S390RegisterDependencyGroup::checkRegisterDependencyDuplicates(TR::CodeGenera { TR_ASSERT(false, "Real register duplicate found in a register dependency\n"); } - - if (realRegI == realRegJ + (TR::RealRegister::FirstHPR - TR::RealRegister::FirstGPR) && - virtRegI->isPlaceholderReg() && - virtRegJ->is64BitReg() && - virtRegJ->getKind() != TR_FPR && - virtRegJ->getKind() != TR_VRF) - { - traceMsg(comp, "Remove duplicate GPR (%s) / HPR (%s) register dependency\n", virtRegJ->getRegisterName(comp), virtRegI->getRegisterName(comp)); - _dependencies[i].setRealRegister(TR::RealRegister::NoReg); - } - - if (realRegJ == realRegI + (TR::RealRegister::FirstHPR - TR::RealRegister::FirstGPR) && - virtRegJ->isPlaceholderReg() && - virtRegI->is64BitReg() && - virtRegI->getKind() != TR_FPR && - virtRegI->getKind() != TR_VRF) - { - traceMsg(comp, "Remove duplicate GPR (%s) / HPR (%s) register dependency\n", virtRegI->getRegisterName(comp), virtRegJ->getRegisterName(comp)); - _dependencies[j].setRealRegister(TR::RealRegister::NoReg); - } } } } @@ -870,7 +850,6 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru int32_t i, j; bool changed; uint32_t availRegMask = checkDependencyGroup(cg, currentInstruction, numOfDependencies); - bool highRegSpill = false; if (!comp->getOption(TR_DisableOOL)) { @@ -999,24 +978,7 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru switch (virtReg->getKind()) { case TR_GPR: - // TODO (Issue #2739): Currently HPRs are not propperly tagged with TR_HPR register kind and are instead - // labeled as TR_GPR. This produces incorrect counts for the number of GPR vs. HPR dependencies that we - // have. We use a workaround here to circumvent the issue but a larger change is needed to properly tag - // the register kinds and eliminate this ugly code. - if ((dependentRegNum >= TR::RealRegister::FirstHPR && dependentRegNum <= TR::RealRegister::LastHPR) || - - // This case is used to handle removed GPR / HPR dependencies in checkRegisterDependencyDuplicates - // in which we don't actually remove the HPR dependency but simply set the target real register to - // be TR::RealRegister::NoReg. This is also a hack that needs to be cleaned up, i.e. we shouldn't - // be creating the duplicate register dependency in the first place. - (virtReg->isPlaceholderReg() && dependentRegNum == TR::RealRegister::NoReg)) - { - ++numHPRs; - } - else - { - ++numGPRs; - } + ++numGPRs; break; case TR_HPR: ++numHPRs; @@ -1035,7 +997,6 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru #ifdef DEBUG int32_t lockedGPRs = 0; - int32_t lockedHPRs = 0; int32_t lockedFPRs = 0; int32_t lockedVRFs = 0; @@ -1047,13 +1008,6 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru ++lockedGPRs; } - for (int32_t i = TR::RealRegister::FirstHPR; i <= TR::RealRegister::LastHPR; ++i) - { - TR::RealRegister* realReg = machine->getRealRegister((TR::RealRegister::RegNum)i); - if (realReg->getState() == TR::RealRegister::Locked) - ++lockedHPRs; - } - for (int32_t i = TR::RealRegister::FirstFPR; i <= TR::RealRegister::LastFPR; ++i) { TR::RealRegister* realReg = machine->getRealRegister((TR::RealRegister::RegNum)i); @@ -1069,7 +1023,6 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru } TR_ASSERT(lockedGPRs == machine->getNumberOfLockedRegisters(TR_GPR), "Inconsistent number of locked GPRs"); - TR_ASSERT(lockedHPRs == machine->getNumberOfLockedRegisters(TR_HPR), "Inconsistent number of locked HPRs"); TR_ASSERT(lockedFPRs == machine->getNumberOfLockedRegisters(TR_FPR), "Inconsistent number of locked FPRs"); TR_ASSERT(lockedVRFs == machine->getNumberOfLockedRegisters(TR_VRF), "Inconsistent number of locked VRFs"); #endif @@ -1080,19 +1033,15 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru // being blocked. bool haveSpareGPRs = true; - bool haveSpareHPRs = true; bool haveSpareFPRs = true; bool haveSpareVRFs = true; TR_ASSERT(numGPRs <= (TR::RealRegister::LastGPR - TR::RealRegister::FirstGPR + 1 - machine->getNumberOfLockedRegisters(TR_GPR)), "Too many GPR dependencies, unable to assign"); - TR_ASSERT(numHPRs <= (TR::RealRegister::LastHPR - TR::RealRegister::FirstHPR + 1 - machine->getNumberOfLockedRegisters(TR_HPR)), "Too many HPR dependencies, unable to assign"); TR_ASSERT(numFPRs <= (TR::RealRegister::LastFPR - TR::RealRegister::FirstFPR + 1 - machine->getNumberOfLockedRegisters(TR_FPR)), "Too many FPR dependencies, unable to assign"); TR_ASSERT(numVRFs <= (TR::RealRegister::LastVRF - TR::RealRegister::FirstVRF + 1 - machine->getNumberOfLockedRegisters(TR_VRF)), "Too many VRF dependencies, unable to assign"); if (numGPRs == (TR::RealRegister::LastGPR - TR::RealRegister::FirstGPR + 1 - machine->getNumberOfLockedRegisters(TR_GPR))) haveSpareGPRs = false; - if (numHPRs == (TR::RealRegister::LastHPR - TR::RealRegister::FirstHPR + 1 - machine->getNumberOfLockedRegisters(TR_HPR))) - haveSpareHPRs = false; if (numFPRs == (TR::RealRegister::LastFPR - TR::RealRegister::FirstFPR + 1 - machine->getNumberOfLockedRegisters(TR_FPR))) haveSpareFPRs = false; if (numVRFs == (TR::RealRegister::LastVRF - TR::RealRegister::FirstVRF + 1 - machine->getNumberOfLockedRegisters(TR_VRF))) @@ -1118,7 +1067,6 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru if (_dependencies[i].getRealRegister() == assignedRegNum || (map.getDependencyWithTarget(assignedRegNum) && ((virtReg->getKind() != TR_GPR || haveSpareGPRs) && - (virtReg->getKind() != TR_HPR || haveSpareHPRs) && (virtReg->getKind() != TR_FPR || haveSpareFPRs) && (virtReg->getKind() != TR_VRF || haveSpareVRFs)))) { @@ -1128,13 +1076,11 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru } // Check for directive to spill high registers. Used on callouts - if ( _dependencies[i].getRealRegister() == TR::RealRegister::KillVolHighRegs && TR::Compiler->target.is32Bit()) + if ( _dependencies[i].getRealRegister() == TR::RealRegister::KillVolHighRegs) { machine->spillAllVolatileHighRegisters(currentInstruction); _dependencies[i].setRealRegister(TR::RealRegister::NoReg); // ignore from now on - highRegSpill = true; } - } ///// REGISTER PAIRS diff --git a/compiler/z/codegen/OMRTreeEvaluator.cpp b/compiler/z/codegen/OMRTreeEvaluator.cpp index aeb9ecbf38a..dda4366241a 100644 --- a/compiler/z/codegen/OMRTreeEvaluator.cpp +++ b/compiler/z/codegen/OMRTreeEvaluator.cpp @@ -4630,13 +4630,6 @@ OMR::Z::TreeEvaluator::extendCastEvaluator(TR::Node * node, TR::CodeGenerator * bool canClobberSrc = cg->canClobberNodesRegister(firstChild); - // We have to be careful when we have HPRs and we're casting to a 64-bit - // value. If the result of the cast is then stored into an HPR, - // we need a new virtual register. We cannot use a clobber evaluate by - // reusing the source 64bit GPR, as this would trigger an assume in RA. - if (cg->supportsHighWordFacility() && (numberOfExtendBits==64)) - canClobberSrc = false; - /** * A load (for proper type conversion) is required if the node is unsigned, not sign extended and * not marked as unneeded conversion. diff --git a/compiler/z/codegen/S390Debug.cpp b/compiler/z/codegen/S390Debug.cpp index f7cc596d0e3..ef5c7b501c8 100644 --- a/compiler/z/codegen/S390Debug.cpp +++ b/compiler/z/codegen/S390Debug.cpp @@ -486,21 +486,6 @@ TR_Debug::printAssocRegDirective(TR::FILE *pOutFile, TR::Instruction * instr) } } - if (0 && !_comp->getOption(TR_DisableHighWordRA)) - { - // 16 HPRs - for (int j = 0; j <= TR::RealRegister::LastHPR - TR::RealRegister::FirstHPR; ++j) - { - TR::RegisterDependency * dependency = depGroup->getRegisterDependency(j+last); - if ((intptr_t) dependency->getRegister() > 0) - { - TR::Register * virtReg = dependency->getRegister(); - printS390RegisterDependency(pOutFile, virtReg, j+TR::RealRegister::FirstHPR, dependency->getRefsRegister(), dependency->getDefsRegister()); - } - } - } - // trfprintf(pOutFile,"\n"); - trfflush(pOutFile); } @@ -2202,26 +2187,6 @@ TR_Debug::printS390GCRegisterMap(TR::FILE *pOutFile, TR::GCRegisterMap * map) } } trfprintf(pOutFile, "}\n"); - - if (0 != map->getHPRMap()) - { - trfprintf(pOutFile, " compressed ptr in registers: {"); - for (int32_t i = TR::RealRegister::FirstHPR; i <= TR::RealRegister::LastHPR; i++) - { - // 2 bits per register, '10' means HPR has collectible, '11' means both HPR and GPR have collectibles - if (map->getHPRMap() & (1 << (i - TR::RealRegister::FirstHPR)*2 + 1)) - { - trfprintf(pOutFile, "%s ", getName(machine->getRealRegister((TR::RealRegister::RegNum) i))); - } - // Compressed collectible in lower GPR. - if (map->getHPRMap() & (1 << (i - TR::RealRegister::FirstHPR)*2)) - { - trfprintf(pOutFile, "%s ", getName(machine->getRealRegister((TR::RealRegister::RegNum) (i - TR::RealRegister::FirstHPR + TR::RealRegister::FirstGPR)))); - } - } - trfprintf(pOutFile, "}\n"); - } - trfprintf(pOutFile, "}\n"); } From d50d37b8063844ff453ac3f79d98098067bebf36 Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Tue, 5 Mar 2019 17:39:19 -0500 Subject: [PATCH 13/23] Fold getHighWordRegister Signed-off-by: Filip Jeremic --- compiler/z/codegen/OMRCodeGenerator.cpp | 2 +- compiler/z/codegen/OMRInstruction.cpp | 63 +-- compiler/z/codegen/OMRLinkage.cpp | 23 +- compiler/z/codegen/OMRMachine.cpp | 458 ++----------------- compiler/z/codegen/OMRMemoryReference.cpp | 6 - compiler/z/codegen/OMRRealRegister.cpp | 20 +- compiler/z/codegen/OMRRealRegister.hpp | 1 - compiler/z/codegen/OMRRegisterDependency.cpp | 29 -- compiler/z/codegen/S390Peephole.cpp | 17 - compiler/z/codegen/SystemLinkage.cpp | 5 - 10 files changed, 40 insertions(+), 584 deletions(-) diff --git a/compiler/z/codegen/OMRCodeGenerator.cpp b/compiler/z/codegen/OMRCodeGenerator.cpp index c497068acfe..c372211a2bd 100644 --- a/compiler/z/codegen/OMRCodeGenerator.cpp +++ b/compiler/z/codegen/OMRCodeGenerator.cpp @@ -2040,7 +2040,7 @@ OMR::Z::CodeGenerator::doRegisterAssignment(TR_RegisterKinds kindsToAssign) { realReg = self()->machine()->realRegister(static_cast(i)); - if ( realReg->getState() == TR::RealRegister::Free && realReg->getHighWordRegister()->getState() == TR::RealRegister::Free) + if ( realReg->getState() == TR::RealRegister::Free) { dcbInstr->setAssignableReg(realReg); realReg->setHasBeenAssignedInMethod(true); diff --git a/compiler/z/codegen/OMRInstruction.cpp b/compiler/z/codegen/OMRInstruction.cpp index 2807f707ba9..b526dc0a4b3 100644 --- a/compiler/z/codegen/OMRInstruction.cpp +++ b/compiler/z/codegen/OMRInstruction.cpp @@ -1178,12 +1178,7 @@ OMR::Z::Instruction::assignRegisterNoDependencies(TR::Register * reg) virtReg->setAssignedRegister(NULL); realReg->setAssignedRegister(NULL); realReg->setState(TR::RealRegister::Free); - if (virtReg->getKind() != TR_FPR && virtReg->is64BitReg() && virtReg->getKind() != TR_VRF) - { - toRealRegister(realReg)->getHighWordRegister()->setAssignedRegister(NULL); - toRealRegister(realReg)->getHighWordRegister()->setState(TR::RealRegister::Free); - self()->cg()->traceRegFreed(virtReg, toRealRegister(realReg)->getHighWordRegister()); - } + self()->cg()->traceRegFreed(virtReg, realReg); } @@ -1205,12 +1200,7 @@ OMR::Z::Instruction::assignRegisterNoDependencies(TR::Register * reg) virtRegHigh->setAssignedRegister(NULL); realRegHigh->setAssignedRegister(NULL); realRegHigh->setState(TR::RealRegister::Free); - if (virtRegHigh->getKind() != TR_FPR && virtRegHigh->is64BitReg() && virtRegHigh->getKind() != TR_VRF) - { - toRealRegister(realRegHigh)->getHighWordRegister()->setAssignedRegister(NULL); - toRealRegister(realRegHigh)->getHighWordRegister()->setState(TR::RealRegister::Free); - self()->cg()->traceRegFreed(virtRegHigh, toRealRegister(realRegHigh)->getHighWordRegister()); - } + self()->cg()->traceRegFreed(virtRegHigh, realRegHigh); } @@ -1220,12 +1210,7 @@ OMR::Z::Instruction::assignRegisterNoDependencies(TR::Register * reg) virtRegLow->setAssignedRegister(NULL); realRegLow->setAssignedRegister(NULL); realRegLow->setState(TR::RealRegister::Free); - if (virtRegLow->getKind() != TR_FPR && virtRegLow->is64BitReg() && virtRegLow->getKind() != TR_VRF) - { - toRealRegister(realRegLow)->getHighWordRegister()->setAssignedRegister(NULL); - toRealRegister(realRegLow)->getHighWordRegister()->setState(TR::RealRegister::Free); - self()->cg()->traceRegFreed(virtRegLow, toRealRegister(realRegLow)->getHighWordRegister()); - } + self()->cg()->traceRegFreed(virtRegLow, realRegLow); } @@ -1435,7 +1420,6 @@ OMR::Z::Instruction::assignOrderedRegisters(TR_RegisterKinds kindToBeAssigned) srcAssigned[i] = 2; } - bool blockTargetHighword = false; bool targetRegIs64Bit = false; // Assign all registers, blocking assignments as you go // @@ -1541,11 +1525,6 @@ OMR::Z::Instruction::assignOrderedRegisters(TR_RegisterKinds kindToBeAssigned) } } - - if (blockTargetHighword) - { - toRealRegister(_targetReg[0])->getHighWordRegister()->setState(TR::RealRegister::Free); - } // Unblock everything, as we are done assigning for this instr self()->unblock(_sourceReg, _sourceRegSize, _targetReg, _targetRegSize, _sourceMem, _targetMem); } @@ -1701,45 +1680,13 @@ OMR::Z::Instruction::renameRegister(TR::Register *from, TR::Register *to) void OMR::Z::Instruction::blockHPR(TR::Register * reg) { - TR::Compilation *comp = self()->cg()->comp(); - - if (reg->getKind() != TR_FPR && reg->getKind() != TR_VRF) - { - if (reg->is64BitReg() && reg->getAssignedRegister() != NULL) - { - TR::RealRegister *assignedReg = reg->getAssignedRegister()->getRealRegister(); - - if (assignedReg != NULL) - { - if (toRealRegister(assignedReg)->getHighWordRegister()->getState() == TR::RealRegister::Assigned) - { - toRealRegister(assignedReg)->getHighWordRegister()->setState(TR::RealRegister::Blocked); - } - } - } - } + } void OMR::Z::Instruction::unblockHPR(TR::Register * reg) { - TR::Compilation *comp = self()->cg()->comp(); - - if (reg->getKind() != TR_FPR && reg->getKind() != TR_VRF) - { - if (reg->is64BitReg() && reg->getAssignedRegister() != NULL) - { - TR::RealRegister *assignedReg = reg->getAssignedRegister()->getRealRegister(); - - if (assignedReg != NULL) - { - if (toRealRegister(assignedReg)->getHighWordRegister()->getState() == TR::RealRegister::Blocked) - { - toRealRegister(assignedReg)->getHighWordRegister()->setState(TR::RealRegister::Assigned, reg->isPlaceholderReg()); - } - } - } - } + } void diff --git a/compiler/z/codegen/OMRLinkage.cpp b/compiler/z/codegen/OMRLinkage.cpp index a344ed1cbc6..95019be288d 100644 --- a/compiler/z/codegen/OMRLinkage.cpp +++ b/compiler/z/codegen/OMRLinkage.cpp @@ -2820,11 +2820,6 @@ OMR::Z::Linkage::lockRegister(TR::RealRegister * lpReal) lpReal->setState(TR::RealRegister::Locked); lpReal->setAssignedRegister(lpReal); lpReal->setHasBeenAssignedInMethod(true); - - TR::RealRegister * lpRealHigh = toRealRegister(lpReal)->getHighWordRegister(); - lpRealHigh->setState(TR::RealRegister::Locked); - lpRealHigh->setAssignedRegister(lpRealHigh); - lpRealHigh->setHasBeenAssignedInMethod(true); } void @@ -2834,11 +2829,6 @@ OMR::Z::Linkage::unlockRegister(TR::RealRegister * lpReal) lpReal->resetState(TR::RealRegister::Free); lpReal->setAssignedRegister(NULL); lpReal->setHasBeenAssignedInMethod(false); - - TR::RealRegister * lpRealHigh = toRealRegister(lpReal)->getHighWordRegister(); - lpRealHigh->resetState(TR::RealRegister::Free); - lpRealHigh->setAssignedRegister(NULL); - lpRealHigh->setHasBeenAssignedInMethod(false); } bool OMR::Z::Linkage::needsAlignment(TR::DataType dt, TR::CodeGenerator * cg) @@ -2872,13 +2862,9 @@ OMR::Z::Linkage::getFirstSavedRegister(int32_t fromreg, int32_t toreg) { TR::RealRegister::RegNum firstUsedReg = TR::RealRegister::NoReg; - // if the first saved reg is an HPR, we will return the corresponding GPR - bool checkHPR = ((self()->getRealRegister(REGNUM(fromreg)))->isLowWordRegister() && - (self()->getRealRegister(REGNUM(toreg)))->isLowWordRegister()); for (int32_t i = fromreg; i <= toreg; ++i) { - if ((self()->getRealRegister(REGNUM(i)))->getHasBeenAssignedInMethod() || - (checkHPR && (self()->getRealRegister(REGNUM(i)))->getHighWordRegister()->getHasBeenAssignedInMethod())) + if ((self()->getRealRegister(REGNUM(i)))->getHasBeenAssignedInMethod()) { firstUsedReg = REGNUM(i); return firstUsedReg; @@ -2896,14 +2882,9 @@ OMR::Z::Linkage::getLastSavedRegister(int32_t fromreg, int32_t toreg) { TR::RealRegister::RegNum lastUsedReg = TR::RealRegister::NoReg; - // if the last saved reg is an HPR, we will return the corresponding GPR - bool checkHPR = ((self()->getRealRegister(REGNUM(fromreg)))->isLowWordRegister() && - (self()->getRealRegister(REGNUM(toreg)))->isLowWordRegister()); - for (int32_t i = fromreg; i <= toreg; ++i) { - if ((self()->getRealRegister(REGNUM(i)))->getHasBeenAssignedInMethod() || - (checkHPR && (self()->getRealRegister(REGNUM(i)))->getHighWordRegister()->getHasBeenAssignedInMethod())) + if ((self()->getRealRegister(REGNUM(i)))->getHasBeenAssignedInMethod()) { lastUsedReg = REGNUM(i); } diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index 84bf0cbb6c6..0c06cdb8188 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -1077,9 +1077,7 @@ OMR::Z::Machine::assignBestRegisterSingle(TR::Register *targetRegister, // todo: in regdepds make sure to do the other half: if the register comes in as 64-bit but requires an HPR, need to do shuffling } targetRegister->setAssignedRegister(assignedRegister); - assignedRegister->getHighWordRegister()->setAssignedRegister(targetRegister); assignedRegister->getLowWordRegister()->setAssignedRegister(targetRegister); - assignedRegister->getHighWordRegister()->setState(TR::RealRegister::Assigned); assignedRegister->getLowWordRegister()->setState(TR::RealRegister::Assigned); } else @@ -1188,15 +1186,6 @@ OMR::Z::Machine::assignBestRegisterSingle(TR::Register *targetRegister, assignedRegister->setAssignedRegister(targetRegister); assignedRegister->setState(TR::RealRegister::Assigned); - // in addition, for 64bit assignment, assign HPR to targetRegister also - // reverseSpill state already take cares of this itself - if (targetRegister->is64BitReg() && !reverseSpilled) - { - //TR_ASSERTC(comp, toRealRegister(assignedRegister)->getHighWordRegister()->getState() == TR::RealRegister::Free, - // "\nHW RA: assigning a 64bit virtual reg but HPR is not free!"); - assignedRegister->getHighWordRegister()->setAssignedRegister(targetRegister); - assignedRegister->getHighWordRegister()->setState(TR::RealRegister::Assigned); - } self()->cg()->traceRegAssigned(targetRegister, assignedRegister); self()->cg()->clearRegisterAssignmentFlags(); } @@ -1237,12 +1226,7 @@ OMR::Z::Machine::assignBestRegisterSingle(TR::Register *targetRegister, { self()->cg()->traceRegFreed(targetRegister, assignedRegister); targetRegister->resetIsLive(); - if (targetRegister->is64BitReg()) - { - assignedRegister->getHighWordRegister()->setAssignedRegister(NULL); - assignedRegister->getHighWordRegister()->setState(TR::RealRegister::Free); - self()->cg()->traceRegFreed(targetRegister, toRealRegister(assignedRegister)->getHighWordRegister()); - } + if (assignedRegister->getState() == TR::RealRegister::Locked ) { assignedRegister->setAssignedRegister(NULL); @@ -1409,17 +1393,6 @@ OMR::Z::Machine::assignBestRegisterPair(TR::Register *regPair, firstReg->setAssignedRegister(freeRegisterHigh); lastReg->setAssignedRegister(freeRegisterLow); - if (firstReg->is64BitReg()) - { - toRealRegister(freeRegisterHigh)->getHighWordRegister()->setState(TR::RealRegister::Assigned); - toRealRegister(freeRegisterHigh)->getHighWordRegister()->setAssignedRegister(firstReg); - } - - if (lastReg->is64BitReg()) - { - toRealRegister(freeRegisterLow)->getHighWordRegister()->setState(TR::RealRegister::Assigned); - toRealRegister(freeRegisterLow)->getHighWordRegister()->setAssignedRegister(lastReg); - } freeRegisterHigh->setAssignedRegister(firstReg); freeRegisterLow->setAssignedRegister(lastReg); @@ -1595,11 +1568,7 @@ OMR::Z::Machine::assignBestRegisterPair(TR::Register *regPair, { firstReg->resetIsLive(); firstReg->setAssignedRegister(NULL); - if (firstReg->is64BitReg()) - { - toRealRegister(freeRegisterHigh)->getHighWordRegister()->setAssignedRegister(NULL); - toRealRegister(freeRegisterHigh)->getHighWordRegister()->setState(TR::RealRegister::Free); - } + freeRegisterHigh->setAssignedRegister(NULL); if (freeRegisterHigh->getState() != TR::RealRegister::Locked) freeRegisterHigh->setState(TR::RealRegister::Free); @@ -1611,11 +1580,7 @@ OMR::Z::Machine::assignBestRegisterPair(TR::Register *regPair, { lastReg->resetIsLive(); lastReg->setAssignedRegister(NULL); - if (lastReg->is64BitReg()) - { - toRealRegister(freeRegisterLow)->getHighWordRegister()->setAssignedRegister(NULL); - toRealRegister(freeRegisterLow)->getHighWordRegister()->setState(TR::RealRegister::Free); - } + freeRegisterLow->setAssignedRegister(NULL); if (freeRegisterLow->getState() != TR::RealRegister::Locked) freeRegisterLow->setState(TR::RealRegister::Free); @@ -1654,18 +1619,8 @@ OMR::Z::Machine::findBestFreeRegisterPair(TR::RealRegister ** firstRegister, TR: continue; } - // TODO: This is a little too conservative. This API needs to be taught whether the register pair requires - // 64-bit registers or not and if and only if we require 64-bit registers do we need to check the highword. - bool highWordPairIsFree = false; - if ((_registerFile[i + 0]->getHighWordRegister()->getState() == TR::RealRegister::Free || _registerFile[i + 0]->getHighWordRegister()->getState() == TR::RealRegister::Unlatched) && - (_registerFile[i + 1]->getHighWordRegister()->getState() == TR::RealRegister::Free || _registerFile[i + 1]->getHighWordRegister()->getState() == TR::RealRegister::Unlatched)) - { - highWordPairIsFree = true; - } - // See if this pair is available, and better than the prev - if (highWordPairIsFree && - (_registerFile[i + 0]->getState() == TR::RealRegister::Free || _registerFile[i + 0]->getState() == TR::RealRegister::Unlatched) && + if ((_registerFile[i + 0]->getState() == TR::RealRegister::Free || _registerFile[i + 0]->getState() == TR::RealRegister::Unlatched) && (_registerFile[i + 1]->getState() == TR::RealRegister::Free || _registerFile[i + 1]->getState() == TR::RealRegister::Unlatched) && (_registerFile[i + 0]->getWeight() + _registerFile[i + 1]->getWeight()) < bestWeightSoFar) { @@ -1718,20 +1673,6 @@ OMR::Z::Machine::findBestFreeRegisterPair(TR::RealRegister ** firstRegister, TR: freeRegisterLow->setState(TR::RealRegister::Free); } - // If unlatched, set it free - if (freeRegisterHigh != NULL && freeRegisterHigh->getHighWordRegister()->getState() == TR::RealRegister::Unlatched) - { - freeRegisterHigh->getHighWordRegister()->setAssignedRegister(NULL); - freeRegisterHigh->getHighWordRegister()->setState(TR::RealRegister::Free); - } - - // If unlatched, set it free - if (freeRegisterLow != NULL && freeRegisterLow->getHighWordRegister()->getState() == TR::RealRegister::Unlatched) - { - freeRegisterLow->getHighWordRegister()->setAssignedRegister(NULL); - freeRegisterLow->getHighWordRegister()->setState(TR::RealRegister::Free); - } - // Did we find a pair, then update the register set structure. if (freeRegisterLow != NULL && freeRegisterHigh != NULL) { @@ -2032,9 +1973,6 @@ OMR::Z::Machine::freeBestRegisterPair(TR::RealRegister ** firstReg, TR::RealRegi if (bestVirtCandidateLow->is64BitReg()) { cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::LG, currentNode, bestCandidateLow, tempMRLow, currInst); - - bestCandidateLow->getHighWordRegister()->setState(TR::RealRegister::Free); - bestCandidateLow->getHighWordRegister()->setAssignedRegister(NULL); } else { @@ -2119,9 +2057,6 @@ OMR::Z::Machine::freeBestRegisterPair(TR::RealRegister ** firstReg, TR::RealRegi if (bestVirtCandidateHigh->is64BitReg()) { cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::LG, currentNode, bestCandidateHigh, tempMRHigh, currInst); - - bestCandidateHigh->getHighWordRegister()->setState(TR::RealRegister::Free); - bestCandidateHigh->getHighWordRegister()->setAssignedRegister(NULL); } else { @@ -2186,11 +2121,6 @@ OMR::Z::Machine::freeBestRegisterPair(TR::RealRegister ** firstReg, TR::RealRegi bestCandidateHigh->setAssignedRegister(NULL); bestCandidateLow->setAssignedRegister(NULL); - bestCandidateHigh->getHighWordRegister()->setState(TR::RealRegister::Free); - bestCandidateLow->getHighWordRegister()->setState(TR::RealRegister::Free); - bestCandidateHigh->getHighWordRegister()->setAssignedRegister(NULL); - bestCandidateLow->getHighWordRegister()->setAssignedRegister(NULL); - // Return free registers *firstReg = bestCandidateHigh; *lastReg = bestCandidateLow; @@ -2354,20 +2284,14 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, { if (bestRegister != NULL && (bestRegister->getState() == TR::RealRegister::Free || - bestRegister->getState() == TR::RealRegister::Unlatched) && - (bestRegister->getHighWordRegister()->getState() == TR::RealRegister::Free || - bestRegister->getHighWordRegister()->getState() == TR::RealRegister::Unlatched)) + bestRegister->getState() == TR::RealRegister::Unlatched)) { if (bestRegister->getState() == TR::RealRegister::Unlatched) { bestRegister->setAssignedRegister(NULL); bestRegister->setState(TR::RealRegister::Free); } - if (bestRegister->getHighWordRegister()->getState() == TR::RealRegister::Unlatched) - { - bestRegister->getHighWordRegister()->setAssignedRegister(NULL); - bestRegister->getHighWordRegister()->setState(TR::RealRegister::Free); - } + return bestRegister; } bestRegister = NULL; @@ -2419,20 +2343,14 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, { if (bestRegister != NULL && (bestRegister->getState() == TR::RealRegister::Free || - bestRegister->getState() == TR::RealRegister::Unlatched) && - (bestRegister->getHighWordRegister()->getState() == TR::RealRegister::Free || - bestRegister->getHighWordRegister()->getState() == TR::RealRegister::Unlatched)) + bestRegister->getState() == TR::RealRegister::Unlatched)) { if (bestRegister->getState() == TR::RealRegister::Unlatched) { bestRegister->setAssignedRegister(NULL); bestRegister->setState(TR::RealRegister::Free); } - if (bestRegister->getHighWordRegister()->getState() == TR::RealRegister::Unlatched) - { - bestRegister->getHighWordRegister()->setAssignedRegister(NULL); - bestRegister->getHighWordRegister()->setState(TR::RealRegister::Free); - } + return bestRegister; } bestRegister = NULL; @@ -2564,7 +2482,6 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, if (virtualReg->is64BitReg()) { bool candidateLWFree = true; - bool candidateHWFree = true; // if we have a preferred association if (preference != 0 && (prefRegMask & availRegMask) && _registerFile[preference] != NULL) @@ -2572,13 +2489,10 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, candidateLWFree = (_registerFile[preference]->getState() == TR::RealRegister::Free) || (_registerFile[preference]->getState() == TR::RealRegister::Unlatched); - candidateHWFree = - (_registerFile[preference]->getHighWordRegister()->getState() == TR::RealRegister::Free) || - (_registerFile[preference]->getHighWordRegister()->getState() == TR::RealRegister::Unlatched); } // check if the preferred Full size reg is free - if ((prefRegMask & availRegMask) && candidateLWFree && candidateHWFree && _registerFile[preference] != NULL) + if ((prefRegMask & availRegMask) && candidateLWFree && _registerFile[preference] != NULL) { bestWeightSoFar = 0x0fffffff; bestRegister = _registerFile[preference]; @@ -2587,14 +2501,8 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, bestRegister->setAssignedRegister(NULL); bestRegister->setState(TR::RealRegister::Free); } - if (bestRegister != NULL && - bestRegister->getHighWordRegister()->getState() == TR::RealRegister::Unlatched) - { - bestRegister->getHighWordRegister()->setAssignedRegister(NULL); - bestRegister->getHighWordRegister()->setState(TR::RealRegister::Free); - } - self()->cg()->setRegisterAssignmentFlag(TR_ByAssociation); + self()->cg()->setRegisterAssignmentFlag(TR_ByAssociation); if (bestRegister != NULL) self()->cg()->traceRegisterAssignment("BEST FREE REG by pref for %R is %R", virtualReg, bestRegister); @@ -2677,27 +2585,16 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, else { TR::RealRegister * candidate = _registerFile[i]; - if (candidate->getHighWordRegister()->getState() == TR::RealRegister::Locked) - { - if (candidate->getState() == TR::RealRegister::Free) - { - candidate->getHighWordRegister()->resetState(TR::RealRegister::Free); - } - } if (virtualReg->is64BitReg()) { bool candidateLWFree = (candidate->getState() == TR::RealRegister::Free) || (candidate->getState() == TR::RealRegister::Unlatched); - bool candidateHWFree = - (candidate->getHighWordRegister()->getState() == TR::RealRegister::Free) || - (candidate->getHighWordRegister()->getState() == TR::RealRegister::Unlatched); // Don't consider registers that can't be assigned. if ((candidate->getState() == TR::RealRegister::Locked) || - (candidate->getHighWordRegister()->getState() == TR::RealRegister::Locked) || ((tRegMask & availRegMask) == 0)) { continue; @@ -2705,7 +2602,7 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, //self()->cg()->traceRegWeight(candidate, candidate->getWeight()); iNew = interference & (1 << (i - maskI)); - if (candidateLWFree && candidateHWFree && + if (candidateLWFree && (freeRegister == NULL || (iOld && !iNew) || ((iOld || !iNew) && candidate->getWeight() < bestWeightSoFar))) { iOld = iNew; @@ -2760,17 +2657,6 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, freeRegister->setState(TR::RealRegister::Free); } - if (virtualReg->is64BitReg()) - { - // need to update HW for full size regs - if (freeRegister != NULL && freeRegister->getHighWordRegister()->getState() == TR::RealRegister::Unlatched) - { - freeRegister->getHighWordRegister()->setAssignedRegister(NULL); - freeRegister->getHighWordRegister()->setState(TR::RealRegister::Free); - } - } - - if (freeRegister != NULL) self()->cg()->traceRegisterAssignment("BEST FREE REG for %R is %R", virtualReg, freeRegister); else @@ -2966,8 +2852,6 @@ OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Regi } else { - TR::RealRegister * realRegHW = realReg->getHighWordRegister(); - if (virtReg->assignToGPR()) { if (realReg->getState() == TR::RealRegister::Assigned) @@ -2999,34 +2883,17 @@ OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Regi { TR::Register * associatedVirtual = NULL; bool usedInMemRef = false; - bool assignedToTwoRegs = false; // LW and HW are assigned to 2 different virtRegs, least preferred candidate - if (realReg->getState() == TR::RealRegister::Assigned && realRegHW->getState() == TR::RealRegister::Assigned) - { - if (realReg->getAssignedRegister() != realRegHW->getAssignedRegister()) - { - // prefer to spill a single Vreg - assignedToTwoRegs = true; - } - } - if (realRegHW->getState() == TR::RealRegister::Assigned) - { - associatedVirtual = realRegHW->getAssignedRegister(); - } if (realReg->getState() == TR::RealRegister::Assigned) { // candidate is LW's virtReg in case if both LW and HW need to be spilled associatedVirtual = realReg->getAssignedRegister(); usedInMemRef = associatedVirtual->isUsedInMemRef(); } - - bool doNotSpillHPR = realRegHW->getAssignedRegister() == virtReg && realReg->getAssignedRegister() != virtReg; - - if ((realReg->getState() == TR::RealRegister::Assigned || realReg->getState() == TR::RealRegister::Free) && - (realRegHW->getState() == TR::RealRegister::Assigned || realRegHW->getState() == TR::RealRegister::Free) && - !doNotSpillHPR) + + if ((realReg->getState() == TR::RealRegister::Assigned || realReg->getState() == TR::RealRegister::Free)) { - if ((!iInterfere && i==preference && pref_favored) || (!usedInMemRef && !assignedToTwoRegs)) + if ((!iInterfere && i==preference && pref_favored) || (!usedInMemRef)) { if (numCandidates == 0) { @@ -3074,21 +2941,6 @@ OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Regi candidates[i] = candidates[--numCandidates]; i--; // on continue repeat test for candidate[i] as candidate[i] is now new. } - // also need to check HW. if it's assigned, push the candidate back - else if (virtReg->is64BitReg() && candidates[i]->getAssignedRegister()) - { - TR::RealRegister *candidateHW = - toRealRegister(candidates[i]->getAssignedRegister())->getHighWordRegister(); - if (candidateHW->getState() == TR::RealRegister::Assigned && - candidateHW->getAssignedRegister()) - { - if (cursor->refsRegister(candidateHW->getAssignedRegister())) - { - candidates[i] = candidates[--numCandidates]; - i--; // on continue repeat test for candidate[i] as candidate[i] is now new. - } - } - } } cursor = cursor->getPrev(); } @@ -3106,19 +2958,6 @@ OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Regi TR_ASSERT_FATAL(false, "Virtual register (%s) is really a real register (%s)?", getRegisterName(virtReg, self()->cg()), getRegisterName(virtReg->getRealRegister(), self()->cg())); candidates[0] = virtReg; } - - // check if we need to spill both words - // todo fix this - else if (virtReg->is64BitReg() && - best->isLowWordRegister() && - best->getHighWordRegister()->getAssignedRegister() && - best->getHighWordRegister()->getAssignedRegister() != candidates[0]) - { - // todo, merge the two spills to 1 load - // bug can't spill 2ice yet - self()->cg()->traceRegisterAssignment("HW RA: freeBestReg Spill %R for fullsize reg: %R ", best->getHighWordRegister(), virtReg); - self()->spillRegister(currentInstruction, best->getHighWordRegister()->getAssignedRegister()); - } else if ((rk != TR_FPR && rk != TR_VRF) && (virtReg->is64BitReg() || virtReg->assignToGPR())) { best = best->getLowWordRegister(); @@ -3307,11 +3146,7 @@ OMR::Z::Machine::spillRegister(TR::Instruction * currentInstruction, TR::Registe } best->setAssignedRegister(NULL); best->setState(TR::RealRegister::Free); - if (virtReg->is64BitReg()) - { - best->getHighWordRegister()->setAssignedRegister(NULL); - best->getHighWordRegister()->setState(TR::RealRegister::Free); - } + virtReg->setAssignedRegister(NULL); } @@ -3379,12 +3214,6 @@ OMR::Z::Machine::reverseSpillState(TR::Instruction *currentInstruction, targetRegister->setAssignedRegister(spilledRegister); spilledRegister->setAssignedRegister(targetRegister); - if (spilledRegister->is64BitReg()) - { - targetRegister->getHighWordRegister()->setState(TR::RealRegister::Assigned); - targetRegister->getHighWordRegister()->setAssignedRegister(spilledRegister); - } - return targetRegister; } } @@ -3412,12 +3241,6 @@ OMR::Z::Machine::reverseSpillState(TR::Instruction *currentInstruction, targetRegister->setAssignedRegister(spilledRegister); spilledRegister->setAssignedRegister(targetRegister); - if (spilledRegister->is64BitReg()) - { - targetRegister->getHighWordRegister()->setState(TR::RealRegister::Assigned); - targetRegister->getHighWordRegister()->setAssignedRegister(spilledRegister); - } - TR::MemoryReference * tempMR = generateS390MemoryReference(currentNode, location->getSymbolReference(), self()->cg()); bool needMVHI = false; @@ -3585,18 +3408,6 @@ OMR::Z::Machine::isAssignable(TR::Register * virtReg, TR::RealRegister * realReg } else { - if (virtReg->getKind() != TR_FPR && virtReg->getKind() != TR_VRF) - { - if ((virtReg->is64BitReg() && realReg->getLowWordRegister()->getAssignedRegister() == realReg->getHighWordRegister()->getAssignedRegister()) || - (!virtReg->is64BitReg() && realReg->getLowWordRegister()->getAssignedRegister() != realReg->getHighWordRegister()->getAssignedRegister())) - { - return true; - } - else - { - return false; - } - } return true; } } @@ -3620,8 +3431,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction TR::Register * currentTargetVirtual = NULL; TR_RegisterKinds rk = virtualRegister->getKind(); - TR_RegisterKinds currentAssignedRegisterRK = rk; // used for register Copy, todo: use it for freeBestReg and findFreeReg - TR_RegisterKinds currentTargetVirtualRK = rk; TR::Instruction * cursor = NULL; TR::Node * currentNode = currentInstruction->getNode(); bool doNotRegCopy = false; @@ -3629,41 +3438,10 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction virtualRegister->setIsLive(); - uint32_t availHighWordRegMap; - if (rk != TR_FPR && rk != TR_VRF) - { - availHighWordRegMap = ~(toRealRegister(targetRegister)->getHighWordRegister()->getRealRegisterMask()); - } - self()->cg()->traceRegisterAssignment("COERCE %R into %R", virtualRegister, targetRegister); - - if (rk != TR_FPR && rk != TR_VRF && currentAssignedRegister) - { - if (currentAssignedRegister->isHighWordRegister()) - currentAssignedRegisterRK = TR_HPR; - } - - // in addition to the 4 GPR's involved, we have 4 more registers for high words: - // REAL VIRTUAL - // Source currentTargetVirtualHW <-> virtualRegisterHW - // Target targetRegisterHW <-> currentTargetVirtualHW - - TR::RealRegister * targetRegisterHW = NULL; - TR::Register * currentTargetVirtualHW = NULL; - TR::RealRegister * currentAssignedRegisterHW = NULL; - TR::Register * virtualRegisterHW = NULL; - TR::RealRegister * spareRegHW = NULL; - + self()->cg()->traceRegisterAssignment("COERCE %R into %R", virtualRegister, targetRegister); + if (rk != TR_FPR && rk != TR_VRF) { - targetRegisterHW = targetRegister->getHighWordRegister(); - currentTargetVirtualHW = targetRegisterHW->getAssignedRegister(); - - if (currentAssignedRegister != NULL) - { - currentAssignedRegisterHW = currentAssignedRegister->getHighWordRegister(); - virtualRegisterHW = currentAssignedRegisterHW->getAssignedRegister(); - } - if (virtualRegister->is64BitReg()) { self()->cg()->traceRegisterAssignment(" coerceRA: %R needs 64 bit reg ", virtualRegister); @@ -3735,8 +3513,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction // fix up states currentAssignedRegister->setAssignedRegister(NULL); currentAssignedRegister->setState(TR::RealRegister::Free); - currentAssignedRegisterHW->setAssignedRegister(NULL); - currentAssignedRegisterHW->setState(TR::RealRegister::Free); } // fix up the states @@ -3768,13 +3544,8 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction { // virtual register is currently assigned to a different register, // override it with the target reg - cursor = self()->registerCopy(self()->cg(), currentAssignedRegisterRK, currentAssignedRegister, targetRegister, currentInstruction); + cursor = self()->registerCopy(self()->cg(), rk, currentAssignedRegister, targetRegister, currentInstruction); - if (virtualRegister->is64BitReg()) - { - currentAssignedRegisterHW->setState(TR::RealRegister::Free); - currentAssignedRegisterHW->setAssignedRegister(NULL); - } currentAssignedRegister->setState(TR::RealRegister::Free); currentAssignedRegister->setAssignedRegister(NULL); } @@ -3785,20 +3556,8 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction currentTargetVirtual = targetRegister->getAssignedRegister(); self()->cg()->traceRegisterAssignment("target %R is blocked, assigned to %R", targetRegister, currentTargetVirtual); - if (rk != TR_FPR && rk != TR_VRF && currentTargetVirtual) - { - if (targetRegister->isHighWordRegister() && - targetRegister->getLowWordRegister()->getAssignedRegister() != currentTargetVirtual) - { - currentTargetVirtualRK = TR_HPR; - } - } + spareReg = self()->findBestFreeRegister(currentInstruction, rk, currentTargetVirtual); - // in this case we cannot use the HPR of target reg as spareReg - if (virtualRegister->is64BitReg()) - spareReg = self()->findBestFreeRegister(currentInstruction, rk, currentTargetVirtual, availHighWordRegMap); - else - spareReg = self()->findBestFreeRegister(currentInstruction, rk, currentTargetVirtual); self()->cg()->setRegisterAssignmentFlag(TR_IndirectCoercion); // We may need spare reg no matter what @@ -3834,64 +3593,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction // todo :HW fix if (!self()->isAssignable(currentTargetVirtual, currentAssignedRegister)) { - if (rk != TR_FPR && rk != TR_VRF && spareReg == NULL && currentTargetVirtualRK != currentAssignedRegisterRK) - { - // register kinds mismatch and we do not have a free spare reg, take the OSC penalty... - TR_BackingStore * location; - - location = self()->cg()->allocateSpill(8, false, NULL, true); // No chance of a gcpoint - TR::MemoryReference * tempMR = generateS390MemoryReference(currentNode, location->getSymbolReference(), self()->cg()); - - // swapping currentAssignedRegister <-> targetRegister - // virtualRegister <-> currentTargetVirtual - - cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::LG, currentNode, currentAssignedRegister, tempMR, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - cursor = generateRRInstruction(self()->cg(), TR::InstOpCode::LGR, currentNode, targetRegister, currentAssignedRegister, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - TR::MemoryReference * tempMR2 = generateS390MemoryReference(*tempMR, 0, self()->cg()); - cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::STG, currentNode, targetRegister, tempMR2, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - - self()->cg()->freeSpill(location, 8, 0); - - // fix up the low word states - currentAssignedRegister->setState(TR::RealRegister::Blocked); - currentAssignedRegister->setAssignedRegister(currentTargetVirtual); - currentTargetVirtual->setAssignedRegister(currentAssignedRegister); - - // fix up the high word states - // store old states in a temp - TR::RealRegister::RegState tempState = currentAssignedRegisterHW->getState(); - TR::Register * tempAssignedReg = currentAssignedRegisterHW->getAssignedRegister(); - - currentAssignedRegisterHW->setState(targetRegisterHW->getState()); - currentAssignedRegisterHW->setAssignedRegister(targetRegisterHW->getAssignedRegister()); - - // If the target register contained a 64-bit value then the Low-Word and High-Word real registers - // would point to the same virtual register. As such the following is true: - // - // currentTargetVirtual == targetRegisterHW->getAssignedRegister() - // - // hence the statement in the if block below would set currentTargetVirtual to point to the High-Word - // of the currentAssignedRegister which is not what we want (since it is a 64-bit value). - - if (targetRegisterHW->getAssignedRegister() && !targetRegisterHW->getAssignedRegister()->is64BitReg()) - { - targetRegisterHW->getAssignedRegister()->setAssignedRegister(currentAssignedRegisterHW); - } - - if (!virtualRegister->is64BitReg()) - { - targetRegisterHW->setState(tempState); - targetRegisterHW->setAssignedRegister(tempAssignedReg); - if (tempAssignedReg) - { - tempAssignedReg->setAssignedRegister(targetRegisterHW); - } - } - } - else { TR_ASSERT(spareReg!=NULL, "coerce reg - blocked, sparereg cannot be NULL."); self()->cg()->traceRegAssigned(currentTargetVirtual, spareReg); @@ -3908,8 +3609,8 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction // should really be the job of registerCopy however and it should be acting on virtual registers and // know whether it needs to generate a 64-bit copy or not. This workaround is placed in multiple // locations. Make sure it is removed everywhere. - cursor = self()->registerCopy(self()->cg(), currentTargetVirtualRK, targetRegisterForCopy, spareReg, currentInstruction); - cursor = self()->registerCopy(self()->cg(), currentAssignedRegisterRK, currentAssignedRegister, targetRegister, currentInstruction); + cursor = self()->registerCopy(self()->cg(), rk, targetRegisterForCopy, spareReg, currentInstruction); + cursor = self()->registerCopy(self()->cg(), rk, currentAssignedRegister, targetRegister, currentInstruction); spareReg->setState(TR::RealRegister::Assigned); currentTargetVirtual->setAssignedRegister(spareReg); @@ -3919,42 +3620,20 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction { targetRegister->getLowWordRegister()->setState(TR::RealRegister::Unlatched); targetRegister->getLowWordRegister()->setAssignedRegister(NULL); - targetRegisterHW->setState(TR::RealRegister::Unlatched); - targetRegisterHW->setAssignedRegister(NULL); - - spareReg->getHighWordRegister()->setState(TR::RealRegister::Assigned); //no need to block the HW half, we already blocked the Lw - spareReg->getHighWordRegister()->setAssignedRegister(currentTargetVirtual); } currentAssignedRegister->setState(TR::RealRegister::Unlatched); currentAssignedRegister->setAssignedRegister(NULL); - if (virtualRegister->is64BitReg()) - { - currentAssignedRegisterHW->setState(TR::RealRegister::Unlatched); - currentAssignedRegisterHW->setAssignedRegister(NULL); - } } } else { self()->cg()->traceRegAssigned(currentTargetVirtual, currentAssignedRegister); - if (rk != TR_FPR && rk != TR_VRF) - { - cursor = self()->registerExchange(self()->cg(), currentAssignedRegisterRK, targetRegister, currentAssignedRegister, spareReg, currentInstruction); - if (currentTargetVirtual->is64BitReg()) - { - //currentAssignedRegister->getHighWordRegister()->setState(TR::RealRegister::Blocked); //not necessary - currentAssignedRegister->getHighWordRegister()->setAssignedRegister(currentTargetVirtual); - } - } - else - { - // Vector coercion most likely to take this path. + cursor = self()->registerExchange(self()->cg(), rk, targetRegister, currentAssignedRegister, spareReg, currentInstruction); - } + currentAssignedRegister->setState(TR::RealRegister::Blocked); currentAssignedRegister->setAssignedRegister(currentTargetVirtual); currentTargetVirtual->setAssignedRegister(currentAssignedRegister); - } } else @@ -3975,7 +3654,7 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction // locations. Make sure it is removed everywhere. // virtual register is not assigned yet, copy register - cursor = self()->registerCopy(self()->cg(), currentTargetVirtualRK, targetRegisterForCopy, spareReg, currentInstruction); + cursor = self()->registerCopy(self()->cg(), rk, targetRegisterForCopy, spareReg, currentInstruction); spareReg->setState(TR::RealRegister::Assigned); spareReg->setAssignedRegister(currentTargetVirtual); @@ -3983,15 +3662,8 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction if (currentTargetVirtual->is64BitReg()) { - //TR_ASSERT(targetRegisterHW->getState() == TR::RealRegister::Blocked, - // "currentTargetVirtual is blocked and is fullsize, but the HW is not blocked?"); - - spareReg->getHighWordRegister()->setState(TR::RealRegister::Assigned); - spareReg->getHighWordRegister()->setAssignedRegister(currentTargetVirtual); targetRegister->getLowWordRegister()->setState(TR::RealRegister::Unlatched); targetRegister->getLowWordRegister()->setAssignedRegister(NULL); - targetRegisterHW->setState(TR::RealRegister::Unlatched); - targetRegisterHW->setAssignedRegister(NULL); } if (virtualRegister->getTotalUseCount() != virtualRegister->getFutureUseCount()) { @@ -4025,19 +3697,9 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction self()->cg()->clearRegisterAssignmentFlags(); return cursor; } - if (targetRegister->isHighWordRegister() && - targetRegister->getLowWordRegister()->getAssignedRegister() != currentTargetVirtual) - { - currentTargetVirtualRK = TR_HPR; - } } - // in this case we cannot use the HPR of target reg as spareReg - if (virtualRegister->is64BitReg()) - spareReg = self()->findBestFreeRegister(currentInstruction, rk, currentTargetVirtual, availHighWordRegMap); - else - // Look for a free reg in case we need a spare. - spareReg = self()->findBestFreeRegister(currentInstruction, rk, currentTargetVirtual); + spareReg = self()->findBestFreeRegister(currentInstruction, rk, currentTargetVirtual); self()->cg()->setRegisterAssignmentFlag(TR_IndirectCoercion); @@ -4083,14 +3745,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction targetRegister->setState(TR::RealRegister::Assigned); } - // freeBestRegister could spill currentTargetVirtual directly to free up targetRegister. - // If currentTargetVirtual is 64-bit, spareReg will be a GPR (targetRegister's low word) - // however, targetRegister could be an HPR because we might only need its high word. In this case - // we must not generate register move of LGR targetRegister,spareReg because they will be the same register - // and we must leave currentTargetVirtual spilled instead of assigning it to spareReg. - if (targetRegister->isHighWordRegister() && currentTargetVirtual->is64BitReg() && - targetRegister->getRegisterNumber() == spareReg->getHighWordRegister()->getRegisterNumber()) - doNotRegCopy = true; virtualRegister->unblock(); } @@ -4112,29 +3766,20 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction // should really be the job of registerCopy however and it should be acting on virtual registers and // know whether it needs to generate a 64-bit copy or not. This workaround is placed in multiple // locations. Make sure it is removed everywhere. - cursor = self()->registerCopy(self()->cg(), currentTargetVirtualRK, targetRegisterForCopy, spareReg, currentInstruction); + cursor = self()->registerCopy(self()->cg(), rk, targetRegisterForCopy, spareReg, currentInstruction); if (currentTargetVirtual->is64BitReg()) { - spareReg->getHighWordRegister()->setState(TR::RealRegister::Assigned); - spareReg->getHighWordRegister()->setAssignedRegister(currentTargetVirtual); targetRegister->getLowWordRegister()->setState(TR::RealRegister::Unlatched); targetRegister->getLowWordRegister()->setAssignedRegister(NULL); - targetRegisterHW->setState(TR::RealRegister::Unlatched); - targetRegisterHW->setAssignedRegister(NULL); } spareReg->setState(TR::RealRegister::Assigned); spareReg->setAssignedRegister(currentTargetVirtual); currentTargetVirtual->setAssignedRegister(spareReg); } - cursor = self()->registerCopy(self()->cg(), currentAssignedRegisterRK, currentAssignedRegister, targetRegister, currentInstruction); + cursor = self()->registerCopy(self()->cg(), rk, currentAssignedRegister, targetRegister, currentInstruction); currentAssignedRegister->setState(TR::RealRegister::Unlatched); currentAssignedRegister->setAssignedRegister(NULL); - if (virtualRegister->is64BitReg()) - { - currentAssignedRegisterHW->setState(TR::RealRegister::Unlatched); - currentAssignedRegisterHW->setAssignedRegister(NULL); - } } else { @@ -4183,36 +3828,15 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction // if (spareReg == NULL && virtualRegister->isPlaceholderReg()) { - int32_t availHWRegs = -1; - bool spillTargetHWReg = false; - if (virtualRegister->is64BitReg()) - { - // for 64-bit, do not spill to the sibling HPR - availHWRegs = availHighWordRegMap; - if (targetRegisterHW->getState() != TR::RealRegister::Free && - targetRegisterHW->getAssignedRegister() != NULL && - targetRegisterHW->getAssignedRegister() != targetRegister->getAssignedRegister()) - { - spillTargetHWReg = true; - } - } - self()->spillRegister(currentInstruction, currentTargetVirtual); targetRegister->setState(TR::RealRegister::Unlatched); targetRegister->setAssignedRegister(NULL); - if (spillTargetHWReg) - { - self()->spillRegister(currentInstruction, targetRegisterHW->getAssignedRegister()); - } - if (currentTargetVirtual->is64BitReg()) { targetRegister->getLowWordRegister()->setState(TR::RealRegister::Unlatched); targetRegister->getLowWordRegister()->setAssignedRegister(NULL); - targetRegisterHW->setState(TR::RealRegister::Unlatched); - targetRegisterHW->setAssignedRegister(NULL); } } else @@ -4244,14 +3868,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction targetRegister->setState(TR::RealRegister::Assigned); } - // freeBestRegister could spill currentTargetVirtual directly to free up targetRegister. - // If currentTargetVirtual is 64-bit, spareReg will be a GPR (targetRegister's low word) - // however, targetRegister could be an HPR because we might only need its high word. In this case - // we must not generate register move of LGR targetRegister,spareReg because they are the same register - // and we must leave currentTargetVirtual spilled instead of assigning it to spareReg. - if (targetRegister->isHighWordRegister() && currentTargetVirtual->is64BitReg() && - targetRegister->getRegisterNumber() == spareReg->getHighWordRegister()->getRegisterNumber()) - doNotRegCopy = true; virtualRegister->unblock(); } @@ -4274,18 +3890,14 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction // should really be the job of registerCopy however and it should be acting on virtual registers and // know whether it needs to generate a 64-bit copy or not. This workaround is placed in multiple // locations. Make sure it is removed everywhere. - cursor = self()->registerCopy(self()->cg(), currentTargetVirtualRK, targetRegisterForCopy, spareReg, currentInstruction); + cursor = self()->registerCopy(self()->cg(), rk, targetRegisterForCopy, spareReg, currentInstruction); spareReg->setState(TR::RealRegister::Assigned); spareReg->setAssignedRegister(currentTargetVirtual); if (currentTargetVirtual->is64BitReg()) { - spareReg->getHighWordRegister()->setState(TR::RealRegister::Assigned); - spareReg->getHighWordRegister()->setAssignedRegister(currentTargetVirtual); targetRegister->getLowWordRegister()->setState(TR::RealRegister::Unlatched); targetRegister->getLowWordRegister()->setAssignedRegister(NULL); - targetRegisterHW->setState(TR::RealRegister::Unlatched); - targetRegisterHW->setAssignedRegister(NULL); } currentTargetVirtual->setAssignedRegister(spareReg); self()->cg()->recordRegisterAssignment(spareReg,currentTargetVirtual); @@ -4352,23 +3964,15 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction // todo: HW copy, LW copy or 64bit? // if targetReg is HW, copy need to be HW - cursor = self()->registerCopy(self()->cg(), currentAssignedRegisterRK, currentAssignedRegister, targetRegister, currentInstruction); - if (virtualRegister->is64BitReg()) - { - currentAssignedRegisterHW->setState(TR::RealRegister::Free); - currentAssignedRegisterHW->setAssignedRegister(NULL); - } + cursor = self()->registerCopy(self()->cg(), rk, currentAssignedRegister, targetRegister, currentInstruction); + currentAssignedRegister->setState(TR::RealRegister::Free); currentAssignedRegister->setAssignedRegister(NULL); } } virtualRegister->setAssignedRegister(targetRegister); - if (virtualRegister->is64BitReg()) - { - targetRegisterHW->setAssignedRegister(virtualRegister); - targetRegisterHW->setState(TR::RealRegister::Assigned); - } + self()->cg()->traceRegAssigned(virtualRegister, targetRegister); self()->cg()->clearRegisterAssignmentFlags(); diff --git a/compiler/z/codegen/OMRMemoryReference.cpp b/compiler/z/codegen/OMRMemoryReference.cpp index 9c8d1fea6ee..5df888abb67 100644 --- a/compiler/z/codegen/OMRMemoryReference.cpp +++ b/compiler/z/codegen/OMRMemoryReference.cpp @@ -2381,12 +2381,6 @@ OMR::Z::MemoryReference::assignRegisters(TR::Instruction * currentInstruction, T assignedBaseRegister->setAssignedRegister(NULL); assignedBaseRegister->setState(TR::RealRegister::Free); cg->traceRegFreed(_baseRegister, assignedBaseRegister); - if (_baseRegister->is64BitReg()) - { - toRealRegister(assignedBaseRegister)->getHighWordRegister()->setAssignedRegister(NULL); - toRealRegister(assignedBaseRegister)->getHighWordRegister()->setState(TR::RealRegister::Free); - cg->traceRegFreed(_baseRegister, toRealRegister(assignedBaseRegister)->getHighWordRegister()); - } } self()->setBaseRegister(assignedBaseRegister, cg); } diff --git a/compiler/z/codegen/OMRRealRegister.cpp b/compiler/z/codegen/OMRRealRegister.cpp index 427d11958fc..9aea8c62d29 100644 --- a/compiler/z/codegen/OMRRealRegister.cpp +++ b/compiler/z/codegen/OMRRealRegister.cpp @@ -96,24 +96,6 @@ OMR::Z::RealRegister::setRegister4Field(uint32_t *instruction) TR::RealRegister::setRegister4Field(instruction, _registerNumber); } - -TR::RealRegister * -OMR::Z::RealRegister::getHighWordRegister() - { - if (_registerNumber>=FirstGPR && _registerNumber<=LastGPR) - { - return _highWordRegister; - } - if (_registerNumber>=FirstHPR && _registerNumber<=LastHPR) - { - return self(); - } - else - { - return NULL; - } - } - TR::RealRegister * OMR::Z::RealRegister::getLowWordRegister() { @@ -158,7 +140,7 @@ OMR::Z::RealRegister::setHasBeenAssignedInMethod(bool b) bool OMR::Z::RealRegister::isHighWordRegister() { - return self() == self()->getHighWordRegister(); + return false; } bool diff --git a/compiler/z/codegen/OMRRealRegister.hpp b/compiler/z/codegen/OMRRealRegister.hpp index a9bd4bd78f0..2575734355a 100644 --- a/compiler/z/codegen/OMRRealRegister.hpp +++ b/compiler/z/codegen/OMRRealRegister.hpp @@ -61,7 +61,6 @@ class OMR_EXTENSIBLE RealRegister : public OMR::RealRegister void setHighWordRegister(TR::RealRegister *r) {_highWordRegister = r;} void setLowWordRegister(TR::RealRegister *r) {_lowWordRegister = r;} - TR::RealRegister * getHighWordRegister(); TR::RealRegister * getLowWordRegister(); TR::RealRegister * getSiblingWordRegister(); diff --git a/compiler/z/codegen/OMRRegisterDependency.cpp b/compiler/z/codegen/OMRRegisterDependency.cpp index 72eb77507d2..be9ec5814ed 100644 --- a/compiler/z/codegen/OMRRegisterDependency.cpp +++ b/compiler/z/codegen/OMRRegisterDependency.cpp @@ -919,12 +919,6 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru assignedReg->setAssignedRegister(NULL); virtReg->setAssignedRegister(NULL); assignedReg->setState(TR::RealRegister::Free); - - if (virtReg->is64BitReg() && rk != TR_FPR && rk != TR_VRF) - { - assignedReg->getHighWordRegister()->setAssignedRegister(NULL); - assignedReg->getHighWordRegister()->setState(TR::RealRegister::Free); - } } // now we are leaving the OOL sequence, anything that was previously spilled in OOL hot path or main line @@ -1513,15 +1507,6 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru } if (dependentRegister->getFutureUseCount() == 0) { - // check if need to free HW - if (assignedRealRegister != NULL) - { - if (dependentRegister->is64BitReg() && dependentRegister->getKind() != TR_FPR && dependentRegister->getKind() != TR_VRF) - { - toRealRegister(assignedRealRegister)->getHighWordRegister()->setState(TR::RealRegister::Unlatched); - cg->traceRegFreed(dependentRegister, toRealRegister(assignedRealRegister)->getHighWordRegister()); - } - } dependentRegister->setAssignedRegister(NULL); dependentRegister->resetIsLive(); if(assignedRealRegister) @@ -1557,13 +1542,6 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru assignedRegister->setAssignedRegister(NULL); cg->traceRegFreed(dependentRegisterHigh, assignedRegister); - - if (dependentRegisterHigh->is64BitReg() && dependentRegisterHigh->getKind() != TR_FPR && - dependentRegisterHigh->getKind() != TR_VRF) - { - toRealRegister(assignedRegister)->getHighWordRegister()->setState(TR::RealRegister::Unlatched); - cg->traceRegFreed(dependentRegisterHigh, toRealRegister(assignedRegister)->getHighWordRegister()); - } } TR::Register * dependentRegisterLow = dependentRegister->getLowOrder(); @@ -1589,13 +1567,6 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru if (assignedRegister->getState() == TR::RealRegister::Locked) assignedRegister->setAssignedRegister(NULL); cg->traceRegFreed(dependentRegisterLow, assignedRegister); - - if (dependentRegisterLow->is64BitReg() && dependentRegisterLow->getKind() != TR_FPR && - dependentRegisterLow->getKind() != TR_VRF) - { - toRealRegister(assignedRegister)->getHighWordRegister()->setState(TR::RealRegister::Unlatched); - cg->traceRegFreed(dependentRegisterLow, toRealRegister(assignedRegister)->getHighWordRegister()); - } } } } diff --git a/compiler/z/codegen/S390Peephole.cpp b/compiler/z/codegen/S390Peephole.cpp index 2c802aba9a5..a75f6baefd3 100644 --- a/compiler/z/codegen/S390Peephole.cpp +++ b/compiler/z/codegen/S390Peephole.cpp @@ -2412,23 +2412,6 @@ TR_S390PostRAPeephole::attemptZ7distinctOperants() // AHIK GPR6,GPR0, -1 return false; } - if (!comp()->getOption(TR_DisableHighWordRA) && instr->getOpCodeValue() == TR::InstOpCode::LGR) - { - // handles this case: - // LGR GPR2,GPR9 ; LR=Clobber_eval - // LFH HPR9,#366#SPILL8 Auto[] ?+0(GPR5) ; Load Spill - // AGHI GPR2,16 - // - // cannot transform this into: - // LFH HPR9,#366#SPILL8 Auto[] 96(GPR5) ; Load Spill - // AGHIK GPR2,GPR9,16, - - TR::RealRegister * lgrSourceHighWordRegister = toRealRegister(lgrSourceReg)->getHighWordRegister(); - if (current->defsRegister(lgrSourceHighWordRegister)) - { - return false; - } - } // found the first next use/def of lgrTargetRegister if (current->usesRegister(lgrTargetReg)) { diff --git a/compiler/z/codegen/SystemLinkage.cpp b/compiler/z/codegen/SystemLinkage.cpp index 7e72d67f291..55f5242d32b 100644 --- a/compiler/z/codegen/SystemLinkage.cpp +++ b/compiler/z/codegen/SystemLinkage.cpp @@ -97,11 +97,6 @@ TR::S390SystemLinkage::initS390RealRegisterLinkage() spReal->setAssignedRegister(spReal); spReal->setHasBeenAssignedInMethod(true); - TR::RealRegister * tempHigh = toRealRegister(spReal)->getHighWordRegister(); - tempHigh->setState(TR::RealRegister::Locked); - tempHigh->setAssignedRegister(tempHigh); - tempHigh->setHasBeenAssignedInMethod(true); - // set register weight for (icount = TR::RealRegister::FirstGPR; icount >= TR::RealRegister::LastAssignableGPR; icount++) { From 989f796492fbf816e7f6e0620beb3adfdd67ce67 Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Wed, 6 Mar 2019 12:15:15 -0500 Subject: [PATCH 14/23] Restrict isAssignable to virtual registers of the same size This is needlessly restrictive. The `registerExchange` API cannot handle register exchanges with one 32-bit and one 64-bit register and the code below guards against calling the `registerExchange` API in such situations. This can definitely be relaxed and the `registerExchange` API taught how to handle those cases. If you look at the places this API (`isAssignable`) is used you will see we effectively handle it there already. That code needs to be cleaned up and consolidated into the `registerExchange` API. I've left a TODO for this to be addressed at a later point. For now, simply disallow the aforementioned case. Signed-off-by: Filip Jeremic --- compiler/z/codegen/OMRMachine.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index 0c06cdb8188..e49b20ef770 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -3408,6 +3408,19 @@ OMR::Z::Machine::isAssignable(TR::Register * virtReg, TR::RealRegister * realReg } else { + // TODO: This is needlessly restrictive. The registerExchange API cannot handle register exchanges with one + // 32-bit and one 64-bit register and the code below effectively guards against calling the registerExchange + // API in such situations. This can definitely be relaxed and the registerExchange API taught how to handle + // those cases. If you look at the places this API (isAssignable) is used you will see we effectively handle + // it there already. That code needs to be cleaned up and consolidated into the registerExchange API. + if (virtReg->getKind() != TR_FPR && virtReg->getKind() != TR_VRF) + { + if (realReg->getLowWordRegister()->getAssignedRegister() != NULL) + { + return virtReg->is64BitReg() == realReg->getLowWordRegister()->getAssignedRegister()->is64BitReg(); + } + } + return true; } } From fb3331ed4f9f592f5f5105582ca45ae9570523d0 Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Wed, 6 Mar 2019 12:27:24 -0500 Subject: [PATCH 15/23] Fold isHighWordRegister Signed-off-by: Filip Jeremic --- compiler/z/codegen/OMRMachine.cpp | 256 ++----------------- compiler/z/codegen/OMRRealRegister.cpp | 6 - compiler/z/codegen/OMRRealRegister.hpp | 1 - compiler/z/codegen/OMRRegisterDependency.cpp | 19 +- compiler/z/codegen/S390Instruction.cpp | 24 +- compiler/z/codegen/S390Instruction.hpp | 10 - 6 files changed, 21 insertions(+), 295 deletions(-) diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index e49b20ef770..f7df81c3fea 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -157,18 +157,6 @@ OMR::Z::Machine::registerCopy(TR::CodeGenerator* cg, } break; } - case TR_HPR: - { - TR_ASSERT_FATAL(targetReg->isHighWordRegister(), "Attempting HPR register copy with target real register (%s) which is not an HPR", getRegisterName(targetReg, cg)); - - auto mnemonic = sourceReg->isLowWordRegister() ? - TR::InstOpCode::LHLR : - TR::InstOpCode::LHHR; - - cursor = generateExtendedHighWordInstruction(node, cg, mnemonic, targetReg, sourceReg, 0, precedingInstruction); - TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/HPR"); - break; - } case TR_FPR: cursor = generateRRInstruction(cg, TR::InstOpCode::LDR, node, targetReg, sourceReg, precedingInstruction); TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/FPR"); @@ -310,9 +298,6 @@ OMR::Z::Machine::registerExchange(TR::CodeGenerator* cg, opStore = TR::InstOpCode::ST; } - bool srcRegIsHPR = sourceReg->isHighWordRegister(); - bool tgtRegIsHPR = targetReg->isHighWordRegister(); - // exchange general purpose registers // if (middleReg == NULL) @@ -343,30 +328,11 @@ OMR::Z::Machine::registerExchange(TR::CodeGenerator* cg, cg->traceRAInstruction(currentInstruction); cg->freeSpill(location, TR::Compiler->om.sizeofReferenceAddress(), 0); - - if (srcRegIsHPR || tgtRegIsHPR) - { - TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/HPR"); - } - else - { - TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/GPR"); - } } else { middleReg->setHasBeenAssignedInMethod(true); - bool middleRegIsHPR = middleReg->isHighWordRegister(); - - if (srcRegIsHPR || tgtRegIsHPR) - { - TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/HPR"); - } - else - { - TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/GPR"); - } currentInstruction = generateRRInstruction(cg, opLoadReg, currentNode, sourceReg, middleReg, precedingInstruction); cg->traceRAInstruction(currentInstruction); @@ -573,10 +539,6 @@ OMR::Z::Machine::isLegalEvenOddPair(TR::RealRegister * evenReg, TR::RealRegister { return false; } - if (toRealRegister(evenReg)->isHighWordRegister() || toRealRegister(oddReg)->isHighWordRegister()) - { - return false; - } else if (toRealRegister(evenReg)->getRegisterNumber() + 1 == toRealRegister(oddReg)->getRegisterNumber()) { @@ -597,11 +559,6 @@ OMR::Z::Machine::isLegalEvenRegister(TR::RealRegister * reg, bool allowBlocked, return false; } - if (toRealRegister(reg)->isHighWordRegister()) - { - return false; - } - // The reg num types are actually +1 off real reg due to NoReg taking // up slot 0 in enumeration int32_t regNum = toRealRegister(reg)->getRegisterNumber() - 1; @@ -770,12 +727,6 @@ OMR::Z::Machine::isLegalOddRegister(TR::RealRegister * reg, bool allowBlocked, u return false; } - if (toRealRegister(reg)->isHighWordRegister()) - { - return false; - } - - // The reg num types are actually +1 off real reg due to NoReg taking // up slot 0 in enumeration int32_t regNum = toRealRegister(reg)->getRegisterNumber() - 1; @@ -1061,21 +1012,7 @@ OMR::Z::Machine::assignBestRegisterSingle(TR::Register *targetRegister, assignedRegister->setState(TR::RealRegister::Free); assignedRegister = newAssignedRegister; } - else if (assignedRegister->isHighWordRegister()) - { - self()->cg()->traceRegisterAssignment("%R is 64bit but currently assigned to HPR, shuffling", targetRegister); - - // find a new 64-bit register and shuffle HPR there - assignedRegister->block(); - TR::RealRegister * assignedRegister64 = self()->findBestRegisterForShuffle(currInst, targetRegister, availRegMask); - assignedRegister->unblock(); - TR::Instruction * cursor = generateExtendedHighWordInstruction(currInst->getNode(), self()->cg(), TR::InstOpCode::LHLR, assignedRegister, assignedRegister64, 0, appendInst); - self()->cg()->traceRAInstruction(cursor); - assignedRegister->setAssignedRegister(NULL); - assignedRegister->setState(TR::RealRegister::Free); - assignedRegister = assignedRegister64; - // todo: in regdepds make sure to do the other half: if the register comes in as 64-bit but requires an HPR, need to do shuffling - } + targetRegister->setAssignedRegister(assignedRegister); assignedRegister->getLowWordRegister()->setAssignedRegister(targetRegister); assignedRegister->getLowWordRegister()->setState(TR::RealRegister::Assigned); @@ -1090,38 +1027,7 @@ OMR::Z::Machine::assignBestRegisterSingle(TR::Register *targetRegister, appendInst = currInst->getPrev(); } - if (assignedRegister->isHighWordRegister() && targetRegister->assignToGPR()) - { - // special case for RISBG, we can change the rotate amount to shuffle low word/ high word - if (currInst->getOpCodeValue() == TR::InstOpCode::RISBG || currInst->getOpCodeValue() == TR::InstOpCode::RISBGN) - { - uint8_t rotateAmnt = ((TR::S390RIEInstruction* )currInst)->getSourceImmediate8(); - ((TR::S390RIEInstruction* )currInst)->setSourceImmediate8(rotateAmnt+32); - } - else - { - // need to find a free GPR and move assignedRegister there - TR::RealRegister * assignedLowWordRegister = NULL; - if ((assignedLowWordRegister = self()->findBestFreeRegister(currInst, kindOfRegister, targetRegister, availRegMask)) == NULL) - { - //assignedRegister->block(); - assignedLowWordRegister = self()->freeBestRegister(currInst, targetRegister, kindOfRegister); - //assignedRegister->unblock(); - } - - TR::Instruction * cursor = generateExtendedHighWordInstruction(currInst->getNode(), self()->cg(), TR::InstOpCode::LHLR, assignedRegister, assignedLowWordRegister, 0, appendInst); - - assignedRegister->setState(TR::RealRegister::Blocked); - - targetRegister->setAssignedRegister(assignedLowWordRegister); - assignedLowWordRegister->setAssignedRegister(targetRegister); - assignedLowWordRegister->setState(TR::RealRegister::Assigned); - assignedRegister->setAssignedRegister(NULL); - assignedRegister = assignedLowWordRegister; - self()->cg()->traceRAInstruction(cursor); - } - } - else if ((assignedRegister->getRealRegisterMask() & availRegMask) == 0) + if ((assignedRegister->getRealRegisterMask() & availRegMask) == 0) { // Oh no.. targetRegister is assigned something it shouldn't be assigned to. Do some shuffling // find a new register to shuffle to @@ -3242,31 +3148,13 @@ OMR::Z::Machine::reverseSpillState(TR::Instruction *currentInstruction, spilledRegister->setAssignedRegister(targetRegister); TR::MemoryReference * tempMR = generateS390MemoryReference(currentNode, location->getSymbolReference(), self()->cg()); - - bool needMVHI = false; - + switch (rk) { case TR_GPR: dataSize = TR::Compiler->om.sizeofReferenceAddress(); opCode = TR::InstOpCode::getStoreOpCode(); - if (targetRegister->isHighWordRegister()) - { - //dataSize = 4; - opCode = TR::InstOpCode::STFH; - - if (spilledRegister->containsCollectedReference()) - { - // decompressing: store into the lower bytes in memory - // need to zero out the higher bytes later too - needMVHI = true; - } - else - { - TR_ASSERT_FATAL(!spilledRegister->is64BitReg(), "Spilled register (%s) is 64-bit but it was assigned to an HPR", getRegisterName(spilledRegister, self()->cg())); - } - } if (spilledRegister->assignToGPR() || targetRegister->isLowWordRegister()) { // dont want to involve halfslot spills yet @@ -3366,22 +3254,12 @@ OMR::Z::Machine::reverseSpillState(TR::Instruction *currentInstruction, } } // Need to free the spill location - if (needMVHI) - { - cursor = generateSILInstruction(self()->cg(), TR::InstOpCode::MVHI, currentNode, tempMR, 0, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::STFH, currentNode, targetRegister, generateS390MemoryReference(*tempMR, 4, self()->cg()), cursor); - self()->cg()->traceRAInstruction(cursor); - } + if (opCode == TR::InstOpCode::VST) + cursor = generateVRXInstruction(self()->cg(), opCode, currentNode, targetRegister, tempMR, 0, currentInstruction); else - { - if (opCode == TR::InstOpCode::VST) - cursor = generateVRXInstruction(self()->cg(), opCode, currentNode, targetRegister, tempMR, 0, currentInstruction); - else - cursor = generateRXInstruction(self()->cg(), opCode, currentNode, targetRegister, tempMR, currentInstruction); + cursor = generateRXInstruction(self()->cg(), opCode, currentNode, targetRegister, tempMR, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - } + self()->cg()->traceRAInstruction(cursor); if (debugObj) { @@ -3474,66 +3352,10 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction // the target reg is free else if (targetRegister->getState() == TR::RealRegister::Free || targetRegister->getState() == TR::RealRegister::Unlatched) { - if(virtualRegister->isPlaceholderReg()) + if (virtualRegister->isPlaceholderReg()) targetRegister->setIsAssignedMoreThanOnce(); // Register is killed invalidate it for moving spill out of loop self()->cg()->traceRegisterAssignment("target %R is free", targetRegister); - if (virtualRegister->is64BitReg()) - { - if (targetRegister->isHighWordRegister() && !virtualRegister->isPlaceholderReg()) - { - // this could happen for OOL, when the reg deps on the top of slow path dictates that a collectible register must be - // spilled to a specific HPR - TR_ASSERT( virtualRegister->containsCollectedReference(), " OOL HPR spill: spilling a 64 bit scalar into HPR"); - - if (currentAssignedRegister == NULL) - { - if (virtualRegister->getTotalUseCount() != virtualRegister->getFutureUseCount() && - virtualRegister->getBackingStorage() != NULL) - { - // the virtual register is currently spilled to stack, now we need to spill it onto HPR - // load it back from the stack into HPR with STFH - // since we are working with compressed refs shift = 0, simply load 32-bit value into HPR. - TR::MemoryReference * tempMR = generateS390MemoryReference(currentNode, virtualRegister->getBackingStorage()->getSymbolReference(), self()->cg()); - - // is the offset correct? +4 big endian? - TR::MemoryReference * mr = generateS390MemoryReference(*tempMR, 4, self()->cg()); - - cursor = generateSILInstruction(self()->cg(), TR::InstOpCode::MVHI, currentNode, tempMR, 0, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - cursor = generateRXInstruction(self()->cg(), TR::InstOpCode::STFH, currentNode, targetRegister, mr, cursor); - self()->cg()->traceRAInstruction(cursor); - - // fix up states - // don't need to worry about protecting backing storage because we are leaving cold path OOL now - self()->cg()->freeSpill(virtualRegister->getBackingStorage(), 8, 0); - virtualRegister->setBackingStorage(NULL); - } - else - { - TR_ASSERT(comp, " OOL HPR spill: currentAssignedRegister is NULL but virtual reg is not spilled?"); - } - } - else - { - // the virtual register is currently assigned to a 64 bit real reg - // simply spill it to HPR and decompress - TR_ASSERT(currentAssignedRegister->isLowWordRegister(), " OOL HPR spill: 64-bit reg assigned to HPR and is not spilled to HPR"); - cursor = generateExtendedHighWordInstruction(currentNode, self()->cg(), TR::InstOpCode::LLHFR, currentAssignedRegister, targetRegister, 0, currentInstruction); - self()->cg()->traceRAInstruction(cursor); - cursor = generateRILInstruction(self()->cg(), TR::InstOpCode::IIHF, currentNode, currentAssignedRegister, 0, cursor); - self()->cg()->traceRAInstruction(cursor); - - // fix up states - currentAssignedRegister->setAssignedRegister(NULL); - currentAssignedRegister->setState(TR::RealRegister::Free); - } - // fix up the states - virtualRegister->setAssignedRegister(NULL); - targetRegister->setAssignedRegister(virtualRegister); - return cursor; - } - } // the virtual register haven't be assigned to any real register yet if (currentAssignedRegister == NULL) { @@ -3610,19 +3432,7 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction TR_ASSERT(spareReg!=NULL, "coerce reg - blocked, sparereg cannot be NULL."); self()->cg()->traceRegAssigned(currentTargetVirtual, spareReg); - auto targetRegisterForCopy = currentTargetVirtual->is64BitReg() && targetRegister->isHighWordRegister() ? - targetRegister->getLowWordRegister() : - targetRegister; - - // TODO: Once registerCopy and registerExchange APIs properly keep track of register states as they - // shuffle things around we need to remove this targetRegisterForCopy hack above. The reason it was - // put in place here is because the target register can be an HPR but the virtual register inside of - // the HPR can be a 64-bit register, in which case we really wish to copy the entire 64-bit value to - // a spare register. This is what the subsequent if statement 2 lines below effectively does. This - // should really be the job of registerCopy however and it should be acting on virtual registers and - // know whether it needs to generate a 64-bit copy or not. This workaround is placed in multiple - // locations. Make sure it is removed everywhere. - cursor = self()->registerCopy(self()->cg(), rk, targetRegisterForCopy, spareReg, currentInstruction); + cursor = self()->registerCopy(self()->cg(), rk, targetRegister, spareReg, currentInstruction); cursor = self()->registerCopy(self()->cg(), rk, currentAssignedRegister, targetRegister, currentInstruction); spareReg->setState(TR::RealRegister::Assigned); @@ -3653,21 +3463,8 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction { self()->cg()->traceRegAssigned(currentTargetVirtual, spareReg); - auto targetRegisterForCopy = currentTargetVirtual->is64BitReg() && targetRegister->isHighWordRegister() ? - targetRegister->getLowWordRegister() : - targetRegister; - - // TODO: Once registerCopy and registerExchange APIs properly keep track of register states as they - // shuffle things around we need to remove this targetRegisterForCopy hack above. The reason it was - // put in place here is because the target register can be an HPR but the virtual register inside of - // the HPR can be a 64-bit register, in which case we really wish to copy the entire 64-bit value to - // a spare register. This is what the subsequent if statement 2 lines below effectively does. This - // should really be the job of registerCopy however and it should be acting on virtual registers and - // know whether it needs to generate a 64-bit copy or not. This workaround is placed in multiple - // locations. Make sure it is removed everywhere. - // virtual register is not assigned yet, copy register - cursor = self()->registerCopy(self()->cg(), rk, targetRegisterForCopy, spareReg, currentInstruction); + cursor = self()->registerCopy(self()->cg(), rk, targetRegister, spareReg, currentInstruction); spareReg->setState(TR::RealRegister::Assigned); spareReg->setAssignedRegister(currentTargetVirtual); @@ -3767,19 +3564,7 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction { self()->cg()->traceRegAssigned(currentTargetVirtual, spareReg); - auto targetRegisterForCopy = currentTargetVirtual->is64BitReg() && targetRegister->isHighWordRegister() ? - targetRegister->getLowWordRegister() : - targetRegister; - - // TODO: Once registerCopy and registerExchange APIs properly keep track of register states as they - // shuffle things around we need to remove this targetRegisterForCopy hack above. The reason it was - // put in place here is because the target register can be an HPR but the virtual register inside of - // the HPR can be a 64-bit register, in which case we really wish to copy the entire 64-bit value to - // a spare register. This is what the subsequent if statement 2 lines below effectively does. This - // should really be the job of registerCopy however and it should be acting on virtual registers and - // know whether it needs to generate a 64-bit copy or not. This workaround is placed in multiple - // locations. Make sure it is removed everywhere. - cursor = self()->registerCopy(self()->cg(), rk, targetRegisterForCopy, spareReg, currentInstruction); + cursor = self()->registerCopy(self()->cg(), rk, targetRegister, spareReg, currentInstruction); if (currentTargetVirtual->is64BitReg()) { targetRegister->getLowWordRegister()->setState(TR::RealRegister::Unlatched); @@ -3891,19 +3676,8 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction self()->cg()->resetRegisterAssignmentFlag(TR_RegisterSpilled); self()->cg()->traceRegAssigned(currentTargetVirtual, spareReg); - auto targetRegisterForCopy = currentTargetVirtual->is64BitReg() && targetRegister->isHighWordRegister() ? - targetRegister->getLowWordRegister() : - targetRegister; - - // TODO: Once registerCopy and registerExchange APIs properly keep track of register states as they - // shuffle things around we need to remove this targetRegisterForCopy hack above. The reason it was - // put in place here is because the target register can be an HPR but the virtual register inside of - // the HPR can be a 64-bit register, in which case we really wish to copy the entire 64-bit value to - // a spare register. This is what the subsequent if statement 2 lines below effectively does. This - // should really be the job of registerCopy however and it should be acting on virtual registers and - // know whether it needs to generate a 64-bit copy or not. This workaround is placed in multiple - // locations. Make sure it is removed everywhere. - cursor = self()->registerCopy(self()->cg(), rk, targetRegisterForCopy, spareReg, currentInstruction); + cursor = self()->registerCopy(self()->cg(), rk, targetRegister, spareReg, currentInstruction); + spareReg->setState(TR::RealRegister::Assigned); spareReg->setAssignedRegister(currentTargetVirtual); @@ -4798,7 +4572,7 @@ OMR::Z::Machine::takeRegisterStateSnapShot() if (_assignedRegisterSnapShot[i] && _assignedRegisterSnapShot[i]->getAssignedRegister() == NULL) { self()->cg()->traceRegisterAssignment("\nOOL: %R : %R", _registerFile[i], _assignedRegisterSnapShot[i]); - TR_ASSERT(_registerFile[i]->isHighWordRegister(), "OOL: HPR spill?? %d", i); + // TR_ASSERT(_registerFile[i]->isHighWordRegister(), "OOL: HPR spill?? %d", i); _containsHPRSpillSnapShot[i] = true; } } @@ -4856,7 +4630,7 @@ OMR::Z::Machine::restoreRegisterStateFromSnapShot() if (_registerFile[i]->getState() == TR::RealRegister::Assigned && !_containsHPRSpillSnapShot[i]) { //self()->cg()->traceRegisterAssignment("\nOOL: restoring %R : %R", _registerFile[i], _registerFile[i]->getAssignedRegister()); - if (!_registerFile[i]->getAssignedRegister()->is64BitReg() || !_registerFile[i]->isHighWordRegister()) + if (!_registerFile[i]->getAssignedRegister()->is64BitReg()) { _registerFile[i]->getAssignedRegister()->setAssignedRegister(_registerFile[i]); } diff --git a/compiler/z/codegen/OMRRealRegister.cpp b/compiler/z/codegen/OMRRealRegister.cpp index 9aea8c62d29..92edb3b9395 100644 --- a/compiler/z/codegen/OMRRealRegister.cpp +++ b/compiler/z/codegen/OMRRealRegister.cpp @@ -137,12 +137,6 @@ OMR::Z::RealRegister::setHasBeenAssignedInMethod(bool b) return OMR::RealRegister::setHasBeenAssignedInMethod(b); //call base class } -bool -OMR::Z::RealRegister::isHighWordRegister() - { - return false; - } - bool OMR::Z::RealRegister::isLowWordRegister() { diff --git a/compiler/z/codegen/OMRRealRegister.hpp b/compiler/z/codegen/OMRRealRegister.hpp index 2575734355a..cfb34f957b4 100644 --- a/compiler/z/codegen/OMRRealRegister.hpp +++ b/compiler/z/codegen/OMRRealRegister.hpp @@ -64,7 +64,6 @@ class OMR_EXTENSIBLE RealRegister : public OMR::RealRegister TR::RealRegister * getLowWordRegister(); TR::RealRegister * getSiblingWordRegister(); - bool isHighWordRegister(); bool isLowWordRegister(); diff --git a/compiler/z/codegen/OMRRegisterDependency.cpp b/compiler/z/codegen/OMRRegisterDependency.cpp index be9ec5814ed..fb2f153587e 100644 --- a/compiler/z/codegen/OMRRegisterDependency.cpp +++ b/compiler/z/codegen/OMRRegisterDependency.cpp @@ -895,22 +895,7 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru break; } - if (rk != TR_FPR && rk != TR_VRF) - { - if (assignedReg->isHighWordRegister()) - { - // virtReg was spilled to an HPR and now we need it spilled to stack - opCode = TR::InstOpCode::LFH; - if (virtReg->is64BitReg()) - { - TR_ASSERT(virtReg->containsCollectedReference(), - "virtReg is assigned to HPR but is not a spilled compress pointer"); - // we need to decompress pointer - tempMR = generateS390MemoryReference(*tempMR, 4, cg); - } - } - } - bool isVector = rk == TR_VRF ? true : false; + bool isVector = (rk == TR_VRF); TR::Instruction *inst = isVector ? generateVRXInstruction(cg, opCode, currentNode, assignedReg, tempMR, 0, currentInstruction) : generateRXInstruction (cg, opCode, currentNode, assignedReg, tempMR, currentInstruction); @@ -1589,7 +1574,7 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru traceMsg(comp,"\nOOL HPR Spill: %s", cg->getDebug()->getName(highWordReg)); traceMsg(comp,":%s\n", cg->getDebug()->getName(virtReg)); TR_ASSERT(virtReg, "\nOOL HPR spill: spilled HPR should have a virt Reg assigned!"); - TR_ASSERT(highWordReg->isHighWordRegister(), "\nOOL HPR spill: spilled HPR should be a real HPR!"); + // TR_ASSERT(highWordReg->isHighWordRegister(), "\nOOL HPR spill: spilled HPR should be a real HPR!"); virtReg->setAssignedRegister(NULL); } } diff --git a/compiler/z/codegen/S390Instruction.cpp b/compiler/z/codegen/S390Instruction.cpp index 95a2238816c..9ec800a4d21 100644 --- a/compiler/z/codegen/S390Instruction.cpp +++ b/compiler/z/codegen/S390Instruction.cpp @@ -3239,11 +3239,7 @@ TR::S390MemInstruction::refsRegister(TR::Register * reg) { TR::RealRegister * realReg = (TR::RealRegister *)reg; TR::Register * regMem = reg; - if (realReg->isHighWordRegister()) - { - // Highword aliasing low word regs - regMem = realReg->getLowWordRegister(); - } + if (getMemoryReference()->refsRegister(regMem)) { return true; @@ -3292,11 +3288,7 @@ TR::S390RXInstruction::refsRegister(TR::Register * reg) { TR::RealRegister * realReg = (TR::RealRegister *)reg; TR::Register * regMem = reg; - if (realReg->isHighWordRegister()) - { - // Highword aliasing low word regs - regMem = (TR::Register *)(realReg->getLowWordRegister()); - } + if (getMemoryReference()->refsRegister(regMem)) { return true; @@ -3476,11 +3468,7 @@ TR::S390RXFInstruction::refsRegister(TR::Register * reg) { TR::RealRegister * realReg = (TR::RealRegister *)reg; TR::Register * regMem = reg; - if (realReg->isHighWordRegister()) - { - // Highword aliasing low word regs - regMem = (TR::Register *)(realReg->getLowWordRegister()); - } + if (getMemoryReference()->refsRegister(regMem)) { return true; @@ -4845,11 +4833,7 @@ TR::S390SSFInstruction::refsRegister(TR::Register * reg) { TR::RealRegister * realReg = (TR::RealRegister *)reg; TR::Register * regMem = reg; - if (realReg->isHighWordRegister()) - { - // Highword aliasing low word regs - regMem = (TR::Register *)(realReg->getLowWordRegister()); - } + if (getMemoryReference()->refsRegister(regMem)) { return true; diff --git a/compiler/z/codegen/S390Instruction.hpp b/compiler/z/codegen/S390Instruction.hpp index 8a21ed6e0fb..9ea31ebef4e 100644 --- a/compiler/z/codegen/S390Instruction.hpp +++ b/compiler/z/codegen/S390Instruction.hpp @@ -1361,11 +1361,6 @@ class S390RegInstruction : public TR::Instruction if (reg->getKind() != TR_FPR && reg->getKind() != TR_VRF && reg->getRealRegister()) { realReg = toRealRegister(reg); - if (realReg->isHighWordRegister()) - { - // Highword aliasing low word regs - realReg = realReg->getLowWordRegister(); - } } if (isTargetPair()) { @@ -2454,11 +2449,6 @@ class S390RILInstruction : public TR::Instruction if (reg->getKind() != TR_FPR && reg->getKind() != TR_VRF && reg->getRealRegister()) { realReg = (TR::RealRegister *)reg; - if (realReg->isHighWordRegister()) - { - // Highword aliasing low word regs - realReg = realReg->getLowWordRegister(); - } } // if we are matching real regs From 9b40b443fb489607d138c85e790bd0f2c7cffce6 Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Wed, 6 Mar 2019 12:40:01 -0500 Subject: [PATCH 16/23] Fold RealRegister related HPR APIs Signed-off-by: Filip Jeremic --- compiler/z/codegen/OMRMachine.cpp | 135 ++++++------------------- compiler/z/codegen/OMRMachine.hpp | 2 - compiler/z/codegen/OMRRealRegister.cpp | 41 -------- compiler/z/codegen/OMRRealRegister.hpp | 24 +---- compiler/z/codegen/S390Instruction.hpp | 4 +- 5 files changed, 34 insertions(+), 172 deletions(-) diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index f7df81c3fea..da1ece916ea 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -134,27 +134,16 @@ OMR::Z::Machine::registerCopy(TR::CodeGenerator* cg, { case TR_GPR: { - TR_ASSERT_FATAL(targetReg->isLowWordRegister(), "Attempting GPR register copy with target real register (%s) which is not a GPR", getRegisterName(targetReg, cg)); + // TODO: Once above is fixed we can always rely on targetReg->getAssignedRegister() + auto nonNullAssignedReg = targetReg->getAssignedRegister() != NULL ? + targetReg->getAssignedRegister() : + sourceReg->getAssignedRegister(); - if (sourceReg->isLowWordRegister()) - { - // TODO: Once above is fixed we can always rely on targetReg->getAssignedRegister() - auto nonNullAssignedReg = targetReg->getAssignedRegister() != NULL ? - targetReg->getAssignedRegister() : - sourceReg->getAssignedRegister(); - - auto mnemonic = nonNullAssignedReg->is64BitReg() ? - TR::InstOpCode::LGR : - TR::InstOpCode::LR; + auto mnemonic = nonNullAssignedReg->is64BitReg() ? + TR::InstOpCode::LGR : + TR::InstOpCode::LR; - cursor = generateRRInstruction(cg, mnemonic, node, targetReg, sourceReg, precedingInstruction); - TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/GPR"); - } - else - { - cursor = generateExtendedHighWordInstruction(node, cg, TR::InstOpCode::LLHFR, targetReg, sourceReg, 0, precedingInstruction); - TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/HPR"); - } + cursor = generateRRInstruction(cg, mnemonic, node, targetReg, sourceReg, precedingInstruction); break; } case TR_FPR: @@ -1014,8 +1003,8 @@ OMR::Z::Machine::assignBestRegisterSingle(TR::Register *targetRegister, } targetRegister->setAssignedRegister(assignedRegister); - assignedRegister->getLowWordRegister()->setAssignedRegister(targetRegister); - assignedRegister->getLowWordRegister()->setState(TR::RealRegister::Assigned); + assignedRegister->setAssignedRegister(targetRegister); + assignedRegister->setState(TR::RealRegister::Assigned); } else { @@ -2424,7 +2413,7 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, TR::RealRegister * candidate = NULL; if (preference != 0 && (prefRegMask & availRegMask) && _registerFile[preference] != NULL) { - candidate = _registerFile[preference]->getLowWordRegister(); + candidate = _registerFile[preference]; } if (candidate != NULL && (prefRegMask & availRegMask) && @@ -2527,7 +2516,7 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, } else { - candidate = _registerFile[i]->getLowWordRegister(); + candidate = _registerFile[i]; //self()->cg()->traceRegWeight(candidate, candidate->getWeight()); // Don't consider registers that can't be assigned. @@ -2852,23 +2841,7 @@ OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Regi } TR::RealRegister * best = toRealRegister(candidates[0]->getAssignedRegister()); - - // Shortcut the selection when a virtReg is specified, and it is already assigned a real, we spill - // that real - if ( virtReg && virtReg->getRealRegister() ) - { - // TODO: I'm fairly certain this should never happen as the input parameter virtReg to this function must be a - // virtual register, and calling virtReg->getRealRegister() should always return NULL so we should not be able - // to get into this if statement. Leaving the fatal assert here however so this gets baked in for a while. We - // need to remove this eventually. - TR_ASSERT_FATAL(false, "Virtual register (%s) is really a real register (%s)?", getRegisterName(virtReg, self()->cg()), getRegisterName(virtReg->getRealRegister(), self()->cg())); - candidates[0] = virtReg; - } - else if ((rk != TR_FPR && rk != TR_VRF) && (virtReg->is64BitReg() || virtReg->assignToGPR())) - { - best = best->getLowWordRegister(); - } - + self()->spillRegister(currentInstruction, candidates[0]); return best; @@ -3153,14 +3126,8 @@ OMR::Z::Machine::reverseSpillState(TR::Instruction *currentInstruction, { case TR_GPR: dataSize = TR::Compiler->om.sizeofReferenceAddress(); - opCode = TR::InstOpCode::getStoreOpCode(); + opCode = TR::InstOpCode::ST; - if (spilledRegister->assignToGPR() || targetRegister->isLowWordRegister()) - { - // dont want to involve halfslot spills yet - //dataSize = 4; - opCode = TR::InstOpCode::ST; - } if (spilledRegister->is64BitReg()) { dataSize = 8; @@ -3293,9 +3260,9 @@ OMR::Z::Machine::isAssignable(TR::Register * virtReg, TR::RealRegister * realReg // it there already. That code needs to be cleaned up and consolidated into the registerExchange API. if (virtReg->getKind() != TR_FPR && virtReg->getKind() != TR_VRF) { - if (realReg->getLowWordRegister()->getAssignedRegister() != NULL) + if (realReg->getAssignedRegister() != NULL) { - return virtReg->is64BitReg() == realReg->getLowWordRegister()->getAssignedRegister()->is64BitReg(); + return virtReg->is64BitReg() == realReg->getAssignedRegister()->is64BitReg(); } } @@ -3441,8 +3408,8 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction if (currentTargetVirtual->is64BitReg()) { - targetRegister->getLowWordRegister()->setState(TR::RealRegister::Unlatched); - targetRegister->getLowWordRegister()->setAssignedRegister(NULL); + targetRegister->setState(TR::RealRegister::Unlatched); + targetRegister->setAssignedRegister(NULL); } currentAssignedRegister->setState(TR::RealRegister::Unlatched); currentAssignedRegister->setAssignedRegister(NULL); @@ -3472,8 +3439,8 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction if (currentTargetVirtual->is64BitReg()) { - targetRegister->getLowWordRegister()->setState(TR::RealRegister::Unlatched); - targetRegister->getLowWordRegister()->setAssignedRegister(NULL); + targetRegister->setState(TR::RealRegister::Unlatched); + targetRegister->setAssignedRegister(NULL); } if (virtualRegister->getTotalUseCount() != virtualRegister->getFutureUseCount()) { @@ -3567,8 +3534,8 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction cursor = self()->registerCopy(self()->cg(), rk, targetRegister, spareReg, currentInstruction); if (currentTargetVirtual->is64BitReg()) { - targetRegister->getLowWordRegister()->setState(TR::RealRegister::Unlatched); - targetRegister->getLowWordRegister()->setAssignedRegister(NULL); + targetRegister->setState(TR::RealRegister::Unlatched); + targetRegister->setAssignedRegister(NULL); } spareReg->setState(TR::RealRegister::Assigned); spareReg->setAssignedRegister(currentTargetVirtual); @@ -3633,8 +3600,8 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction if (currentTargetVirtual->is64BitReg()) { - targetRegister->getLowWordRegister()->setState(TR::RealRegister::Unlatched); - targetRegister->getLowWordRegister()->setAssignedRegister(NULL); + targetRegister->setState(TR::RealRegister::Unlatched); + targetRegister->setAssignedRegister(NULL); } } else @@ -3683,8 +3650,8 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction if (currentTargetVirtual->is64BitReg()) { - targetRegister->getLowWordRegister()->setState(TR::RealRegister::Unlatched); - targetRegister->getLowWordRegister()->setAssignedRegister(NULL); + targetRegister->setState(TR::RealRegister::Unlatched); + targetRegister->setAssignedRegister(NULL); } currentTargetVirtual->setAssignedRegister(spareReg); self()->cg()->recordRegisterAssignment(spareReg,currentTargetVirtual); @@ -4007,39 +3974,7 @@ OMR::Z::Machine::initializeRegisterFile() _registerFile[TR::RealRegister::VRF31] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_VRF, 0, TR::RealRegister::Free, TR::RealRegister::VRF31, TR::RealRegister::VRF31Mask, self()->cg()); - _registerFile[TR::RealRegister::HPR0]->setLowWordRegister(_registerFile[TR::RealRegister::GPR0]); - _registerFile[TR::RealRegister::HPR1]->setLowWordRegister(_registerFile[TR::RealRegister::GPR1]); - _registerFile[TR::RealRegister::HPR2]->setLowWordRegister(_registerFile[TR::RealRegister::GPR2]); - _registerFile[TR::RealRegister::HPR3]->setLowWordRegister(_registerFile[TR::RealRegister::GPR3]); - _registerFile[TR::RealRegister::HPR4]->setLowWordRegister(_registerFile[TR::RealRegister::GPR4]); - _registerFile[TR::RealRegister::HPR5]->setLowWordRegister(_registerFile[TR::RealRegister::GPR5]); - _registerFile[TR::RealRegister::HPR6]->setLowWordRegister(_registerFile[TR::RealRegister::GPR6]); - _registerFile[TR::RealRegister::HPR7]->setLowWordRegister(_registerFile[TR::RealRegister::GPR7]); - _registerFile[TR::RealRegister::HPR8]->setLowWordRegister(_registerFile[TR::RealRegister::GPR8]); - _registerFile[TR::RealRegister::HPR9]->setLowWordRegister(_registerFile[TR::RealRegister::GPR9]); - _registerFile[TR::RealRegister::HPR10]->setLowWordRegister(_registerFile[TR::RealRegister::GPR10]); - _registerFile[TR::RealRegister::HPR11]->setLowWordRegister(_registerFile[TR::RealRegister::GPR11]); - _registerFile[TR::RealRegister::HPR12]->setLowWordRegister(_registerFile[TR::RealRegister::GPR12]); - _registerFile[TR::RealRegister::HPR13]->setLowWordRegister(_registerFile[TR::RealRegister::GPR13]); - _registerFile[TR::RealRegister::HPR14]->setLowWordRegister(_registerFile[TR::RealRegister::GPR14]); - _registerFile[TR::RealRegister::HPR15]->setLowWordRegister(_registerFile[TR::RealRegister::GPR15]); - - _registerFile[TR::RealRegister::GPR0]->setHighWordRegister(_registerFile[TR::RealRegister::HPR0]); - _registerFile[TR::RealRegister::GPR1]->setHighWordRegister(_registerFile[TR::RealRegister::HPR1]); - _registerFile[TR::RealRegister::GPR2]->setHighWordRegister(_registerFile[TR::RealRegister::HPR2]); - _registerFile[TR::RealRegister::GPR3]->setHighWordRegister(_registerFile[TR::RealRegister::HPR3]); - _registerFile[TR::RealRegister::GPR4]->setHighWordRegister(_registerFile[TR::RealRegister::HPR4]); - _registerFile[TR::RealRegister::GPR5]->setHighWordRegister(_registerFile[TR::RealRegister::HPR5]); - _registerFile[TR::RealRegister::GPR6]->setHighWordRegister(_registerFile[TR::RealRegister::HPR6]); - _registerFile[TR::RealRegister::GPR7]->setHighWordRegister(_registerFile[TR::RealRegister::HPR7]); - _registerFile[TR::RealRegister::GPR8]->setHighWordRegister(_registerFile[TR::RealRegister::HPR8]); - _registerFile[TR::RealRegister::GPR9]->setHighWordRegister(_registerFile[TR::RealRegister::HPR9]); - _registerFile[TR::RealRegister::GPR10]->setHighWordRegister(_registerFile[TR::RealRegister::HPR10]); - _registerFile[TR::RealRegister::GPR11]->setHighWordRegister(_registerFile[TR::RealRegister::HPR11]); - _registerFile[TR::RealRegister::GPR12]->setHighWordRegister(_registerFile[TR::RealRegister::HPR12]); - _registerFile[TR::RealRegister::GPR13]->setHighWordRegister(_registerFile[TR::RealRegister::HPR13]); - _registerFile[TR::RealRegister::GPR14]->setHighWordRegister(_registerFile[TR::RealRegister::HPR14]); - _registerFile[TR::RealRegister::GPR15]->setHighWordRegister(_registerFile[TR::RealRegister::HPR15]); + // set siblings for Floating Point register pairs used by long doubles _registerFile[TR::RealRegister::FPR0]->setSiblingRegister(_registerFile[TR::RealRegister::FPR2]); _registerFile[TR::RealRegister::FPR1]->setSiblingRegister(_registerFile[TR::RealRegister::FPR3]); @@ -4566,15 +4501,7 @@ OMR::Z::Machine::takeRegisterStateSnapShot() _registerAssociationsSnapShot[i] = self()->getVirtualAssociatedWithReal((TR::RealRegister::RegNum)(i)); _assignedRegisterSnapShot[i] = _registerFile[i]->getAssignedRegister(); _registerAssignedSnapShot[i] = _registerFile[i]->getHasBeenAssignedInMethod(); - _registerAssignedHighSnapShot[i] = _registerFile[i]->getAssignedHigh(); _registerWeightSnapShot[i] = _registerFile[i]->getWeight(); - _containsHPRSpillSnapShot[i] = false; - if (_assignedRegisterSnapShot[i] && _assignedRegisterSnapShot[i]->getAssignedRegister() == NULL) - { - self()->cg()->traceRegisterAssignment("\nOOL: %R : %R", _registerFile[i], _assignedRegisterSnapShot[i]); - // TR_ASSERT(_registerFile[i]->isHighWordRegister(), "OOL: HPR spill?? %d", i); - _containsHPRSpillSnapShot[i] = true; - } } } @@ -4625,15 +4552,11 @@ OMR::Z::Machine::restoreRegisterStateFromSnapShot() } _registerFile[i]->setAssignedRegister(_assignedRegisterSnapShot[i]); //_registerFile[i]->setHasBeenAssignedInMethod(_registerAssignedSnapShot[i]); - //_registerFile[i]->setAssignedHigh(_registerAssignedHighSnapShot[i]); // make sure to double link virt - real reg if assigned - if (_registerFile[i]->getState() == TR::RealRegister::Assigned && !_containsHPRSpillSnapShot[i]) + if (_registerFile[i]->getState() == TR::RealRegister::Assigned) { //self()->cg()->traceRegisterAssignment("\nOOL: restoring %R : %R", _registerFile[i], _registerFile[i]->getAssignedRegister()); - if (!_registerFile[i]->getAssignedRegister()->is64BitReg()) - { - _registerFile[i]->getAssignedRegister()->setAssignedRegister(_registerFile[i]); - } + _registerFile[i]->getAssignedRegister()->setAssignedRegister(_registerFile[i]); } // If a register is only created and used in multiple OOL hot paths (created in one OOL hot path diff --git a/compiler/z/codegen/OMRMachine.hpp b/compiler/z/codegen/OMRMachine.hpp index 556426bb63c..bdad3098ddf 100644 --- a/compiler/z/codegen/OMRMachine.hpp +++ b/compiler/z/codegen/OMRMachine.hpp @@ -187,11 +187,9 @@ class OMR_EXTENSIBLE Machine : public OMR::Machine TR::RealRegister::RegState _registerStatesSnapShot[TR::RealRegister::NumRegisters]; TR::Register *_registerAssociationsSnapShot[TR::RealRegister::NumRegisters]; bool _registerAssignedSnapShot[TR::RealRegister::NumRegisters]; - bool _registerAssignedHighSnapShot[TR::RealRegister::NumRegisters]; uint16_t _registerWeightSnapShot[TR::RealRegister::NumRegisters]; TR::Register *_assignedRegisterSnapShot[TR::RealRegister::NumRegisters]; uint32_t _globalRegisterNumberToRealRegisterMapSnapShot[TR::RealRegister::NumRegisters]; - bool _containsHPRSpillSnapShot[TR::RealRegister::NumRegisters]; TR_GlobalRegisterNumber _firstGlobalGPRRegisterNumber; TR_GlobalRegisterNumber _lastGlobalGPRRegisterNumber; diff --git a/compiler/z/codegen/OMRRealRegister.cpp b/compiler/z/codegen/OMRRealRegister.cpp index 92edb3b9395..1b4929264f1 100644 --- a/compiler/z/codegen/OMRRealRegister.cpp +++ b/compiler/z/codegen/OMRRealRegister.cpp @@ -96,53 +96,12 @@ OMR::Z::RealRegister::setRegister4Field(uint32_t *instruction) TR::RealRegister::setRegister4Field(instruction, _registerNumber); } -TR::RealRegister * -OMR::Z::RealRegister::getLowWordRegister() - { - if (_registerNumber>=FirstGPR && _registerNumber<=LastGPR) - { - return self(); - } - if (_registerNumber>=FirstHPR && _registerNumber<=LastHPR) - { - return _lowWordRegister; - } - else - { - return NULL; - } - } - -TR::RealRegister * -OMR::Z::RealRegister::getSiblingWordRegister() - { - if (_registerNumber>=FirstGPR && _registerNumber<=LastGPR) - { - return _highWordRegister; - } - if (_registerNumber>=FirstHPR && _registerNumber<=LastHPR) - { - return _lowWordRegister; - } - else - return NULL; - } - bool OMR::Z::RealRegister::setHasBeenAssignedInMethod(bool b) { - if (self()->getAssignedRegister() && self()->getAssignedRegister()->isUpperBitsAreDirty()) - (b)? self()->setAssignedHigh(true) : self()->setAssignedHigh(false); - return OMR::RealRegister::setHasBeenAssignedInMethod(b); //call base class } -bool -OMR::Z::RealRegister::isLowWordRegister() - { - return self() == self()->getLowWordRegister(); - } - /** \details * diff --git a/compiler/z/codegen/OMRRealRegister.hpp b/compiler/z/codegen/OMRRealRegister.hpp index cfb34f957b4..15bcb4cc78b 100644 --- a/compiler/z/codegen/OMRRealRegister.hpp +++ b/compiler/z/codegen/OMRRealRegister.hpp @@ -56,25 +56,11 @@ class OMR_EXTENSIBLE RealRegister : public OMR::RealRegister RealRegister(TR_RegisterKinds, uint16_t, RegState, RegNum, RegMask, TR::CodeGenerator *); public: - - // getters/setters - void setHighWordRegister(TR::RealRegister *r) {_highWordRegister = r;} - void setLowWordRegister(TR::RealRegister *r) {_lowWordRegister = r;} - - TR::RealRegister * getLowWordRegister(); - TR::RealRegister * getSiblingWordRegister(); - - bool isLowWordRegister(); - - - + // methods for manipulating flags bool getModified() {return _modified.testAny(isModified);} bool setModified(bool b) { (b)? _modified.set(isModified) : _modified.reset(isModified); return b; } - - bool getAssignedHigh() {return _realRegFlags.testAny(isAssignedHigh);} - bool setAssignedHigh(bool b) {b? _realRegFlags.set(isAssignedHigh) : _realRegFlags.reset(isAssignedHigh); return b;} - + bool setHasBeenAssignedInMethod(bool b); // derived from base class @@ -114,13 +100,9 @@ class OMR_EXTENSIBLE RealRegister : public OMR::RealRegister enum { - isAssignedHigh = 0x02, // Indicates use of high word on 32-bit platform isModified = 0x01, }; - - TR::RealRegister *_highWordRegister; - TR::RealRegister *_lowWordRegister; - + flags8_t _modified; static const uint8_t _fullRegBinaryEncodings[NumRegisters]; diff --git a/compiler/z/codegen/S390Instruction.hpp b/compiler/z/codegen/S390Instruction.hpp index 9ea31ebef4e..dba2bd12167 100644 --- a/compiler/z/codegen/S390Instruction.hpp +++ b/compiler/z/codegen/S390Instruction.hpp @@ -1381,7 +1381,7 @@ class S390RegInstruction : public TR::Instruction // if we are matching real regs if (reg->getKind() != TR_FPR && reg->getKind() != TR_VRF && getRegisterOperand(1)->getRealRegister()) { - targetReg1 = ((TR::RealRegister *)getRegisterOperand(1))->getLowWordRegister(); + targetReg1 = (TR::RealRegister *)getRegisterOperand(1); return realReg == targetReg1; } @@ -2454,7 +2454,7 @@ class S390RILInstruction : public TR::Instruction // if we are matching real regs if (reg->getKind() != TR_FPR && reg->getKind() != TR_VRF && getRegisterOperand(1) && getRegisterOperand(1)->getRealRegister()) { - targetReg = ((TR::RealRegister *)getRegisterOperand(1))->getLowWordRegister(); + targetReg = (TR::RealRegister *)getRegisterOperand(1); return realReg == targetReg; } // if we are matching virt regs From 5a3390eadfd0e5bae78b9b4a7a2e4f03091ba3f5 Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Wed, 6 Mar 2019 13:39:57 -0500 Subject: [PATCH 17/23] Fold blockHPR and unblockHPR Signed-off-by: Filip Jeremic --- compiler/z/codegen/OMRInstruction.cpp | 49 --------------------------- compiler/z/codegen/OMRInstruction.hpp | 3 +- 2 files changed, 1 insertion(+), 51 deletions(-) diff --git a/compiler/z/codegen/OMRInstruction.cpp b/compiler/z/codegen/OMRInstruction.cpp index b526dc0a4b3..9bdad580a3e 100644 --- a/compiler/z/codegen/OMRInstruction.cpp +++ b/compiler/z/codegen/OMRInstruction.cpp @@ -1676,19 +1676,6 @@ OMR::Z::Instruction::renameRegister(TR::Register *from, TR::Register *to) return numReplaced; } - -void -OMR::Z::Instruction::blockHPR(TR::Register * reg) - { - - } - -void -OMR::Z::Instruction::unblockHPR(TR::Register * reg) - { - - } - void OMR::Z::Instruction::block(TR::Register **sourceReg, int sourceRegSize, TR::Register** targetReg, int targetRegSize, TR::MemoryReference ** sourceMem, TR::MemoryReference ** targetMem) @@ -1699,39 +1686,21 @@ OMR::Z::Instruction::block(TR::Register **sourceReg, int sourceRegSize, TR::Regi for (i = 0; i < targetRegSize; ++i) { (targetReg[i])->block(); - self()->blockHPR(targetReg[i]); } for (i = 0; i < sourceRegSize; ++i) { (sourceReg[i])->block(); - self()->blockHPR(sourceReg[i]); } for (i = 0; i < _targetMemSize; ++i) { targetMem[i]->blockRegisters(); - if (targetMem[i]->getBaseRegister()) - { - self()->blockHPR(targetMem[i]->getBaseRegister()); - } - if (targetMem[i]->getIndexRegister()) - { - self()->blockHPR(targetMem[i]->getIndexRegister()); - } } for (i = 0; i < _sourceMemSize; ++i) { sourceMem[i]->blockRegisters(); - if (sourceMem[i]->getBaseRegister()) - { - self()->blockHPR(sourceMem[i]->getBaseRegister()); - } - if (sourceMem[i]->getIndexRegister()) - { - self()->blockHPR(sourceMem[i]->getIndexRegister()); - } } } @@ -1747,39 +1716,21 @@ OMR::Z::Instruction::unblock(TR::Register **sourceReg, int sourceRegSize, TR::Re for (i = 0; i < targetRegSize; ++i) { targetReg[i]->unblock(); - self()->unblockHPR(targetReg[i]); } for (i = 0; i < sourceRegSize; ++i) { (sourceReg[i])->unblock(); - self()->unblockHPR(sourceReg[i]); } for (i = 0; i < _targetMemSize; ++i) { targetMem[i]->unblockRegisters(); - if (targetMem[i]->getBaseRegister()) - { - self()->unblockHPR(targetMem[i]->getBaseRegister()); - } - if (targetMem[i]->getIndexRegister()) - { - self()->unblockHPR(targetMem[i]->getIndexRegister()); - } } for (i = 0; i < _sourceMemSize; ++i) { sourceMem[i]->unblockRegisters(); - if (sourceMem[i]->getBaseRegister()) - { - self()->unblockHPR(sourceMem[i]->getBaseRegister()); - } - if (sourceMem[i]->getIndexRegister()) - { - self()->unblockHPR(sourceMem[i]->getIndexRegister()); - } } } diff --git a/compiler/z/codegen/OMRInstruction.hpp b/compiler/z/codegen/OMRInstruction.hpp index 44e586762b2..49f0b86cfcb 100644 --- a/compiler/z/codegen/OMRInstruction.hpp +++ b/compiler/z/codegen/OMRInstruction.hpp @@ -424,8 +424,7 @@ class OMR_EXTENSIBLE Instruction : public OMR::Instruction TR::Register* assignRegisterNoDependencies(TR::Register* reg); void assignOrderedRegisters(TR_RegisterKinds kindToBeAssigned); virtual void assignRegistersAndDependencies(TR_RegisterKinds kindToBeAssigned); - void blockHPR(TR::Register * reg); - void unblockHPR(TR::Register * reg); + void block(TR::Register** sourceReg, int32_t _sourceRegSize, TR::Register** targetReg, int targetRegSize, TR::MemoryReference** sourceMem, TR::MemoryReference** targetMem); void unblock(TR::Register** sourceReg, int32_t sourceRegSize, TR::Register** targetReg, int targetRegSize, From 8799d6b4834accaccf1fdd00f71c2a335a9111fd Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Wed, 6 Mar 2019 13:46:51 -0500 Subject: [PATCH 18/23] Fold TR_HPR register kind and HPR real registers Signed-off-by: Filip Jeremic --- compiler/codegen/OMRMachine.hpp | 4 - compiler/codegen/RegisterConstants.hpp | 6 +- compiler/ras/Debug.cpp | 11 ++- compiler/z/codegen/OMRCodeGenerator.cpp | 2 +- compiler/z/codegen/OMRInstruction.cpp | 11 --- compiler/z/codegen/OMRMachine.cpp | 84 ++++---------------- compiler/z/codegen/OMRRealRegister.cpp | 31 +------- compiler/z/codegen/OMRRealRegister.hpp | 1 - compiler/z/codegen/OMRRegister.cpp | 6 -- compiler/z/codegen/OMRRegister.hpp | 16 +--- compiler/z/codegen/OMRRegisterDependency.cpp | 10 +-- compiler/z/codegen/PseudoRegisterEnum.hpp | 22 ++--- compiler/z/codegen/RealRegisterEnum.hpp | 24 +----- compiler/z/codegen/RealRegisterMaskEnum.hpp | 17 ---- compiler/z/codegen/S390Debug.cpp | 32 -------- 15 files changed, 41 insertions(+), 236 deletions(-) diff --git a/compiler/codegen/OMRMachine.hpp b/compiler/codegen/OMRMachine.hpp index 3e3000cdffc..0fdc63b3611 100644 --- a/compiler/codegen/OMRMachine.hpp +++ b/compiler/codegen/OMRMachine.hpp @@ -48,7 +48,6 @@ class OMR_EXTENSIBLE Machine { int16_t numLockedGPRs; - int16_t numLockedHPRs; int16_t numLockedFPRs; int16_t numLockedVRFs; @@ -60,7 +59,6 @@ class OMR_EXTENSIBLE Machine : _cg(cg), numLockedGPRs(-1), - numLockedHPRs(-1), numLockedFPRs(-1), numLockedVRFs(-1) { @@ -101,7 +99,6 @@ class OMR_EXTENSIBLE Machine switch (kind) { case TR_GPR: numLockedGPRs = numLocked; return numLockedGPRs; - case TR_HPR: numLockedHPRs = numLocked; return numLockedHPRs; case TR_FPR: numLockedFPRs = numLocked; return numLockedFPRs; case TR_VRF: numLockedVRFs = numLocked; return numLockedVRFs; default: @@ -124,7 +121,6 @@ class OMR_EXTENSIBLE Machine switch (kind) { case TR_GPR: TR_ASSERT(numLockedGPRs >= 0, "Expecting number of locked registers to be >= 0"); return numLockedGPRs; - case TR_HPR: TR_ASSERT(numLockedHPRs >= 0, "Expecting number of locked registers to be >= 0"); return numLockedHPRs; case TR_FPR: TR_ASSERT(numLockedFPRs >= 0, "Expecting number of locked registers to be >= 0"); return numLockedFPRs; case TR_VRF: TR_ASSERT(numLockedVRFs >= 0, "Expecting number of locked registers to be >= 0"); return numLockedVRFs; default: diff --git a/compiler/codegen/RegisterConstants.hpp b/compiler/codegen/RegisterConstants.hpp index b881f7cd928..3212847dff3 100644 --- a/compiler/codegen/RegisterConstants.hpp +++ b/compiler/codegen/RegisterConstants.hpp @@ -40,8 +40,7 @@ enum TR_RegisterKinds TR_VSX_SCALAR = 5, TR_VSX_VECTOR = 6, TR_SSR = 7, // used for TR_PseudoRegisters for SS (storage to storage) instructions to return results - TR_HPR = 8, // High word register for zGryphon - LastRegisterKind = TR_HPR, + LastRegisterKind = TR_SSR, NumRegisterKinds = LastRegisterKind+1, TR_NoRegister = LastRegisterKind+1, @@ -54,8 +53,7 @@ enum TR_RegisterKinds TR_VRF_Mask = TO_KIND_MASK(TR_VRF), TR_VSX_SCALAR_Mask = TO_KIND_MASK(TR_VSX_SCALAR), TR_VSX_VECTOR_Mask = TO_KIND_MASK(TR_VSX_VECTOR), - TR_SSR_Mask = TO_KIND_MASK(TR_SSR), - TR_HPR_Mask = TO_KIND_MASK(TR_HPR) + TR_SSR_Mask = TO_KIND_MASK(TR_SSR) }; enum TR_RegisterSizes diff --git a/compiler/ras/Debug.cpp b/compiler/ras/Debug.cpp index cdb333ff920..05bacc8c7af 100644 --- a/compiler/ras/Debug.cpp +++ b/compiler/ras/Debug.cpp @@ -3186,11 +3186,11 @@ TR_Debug::print(TR::FILE *pOutFile, TR::Register * reg, TR_RegisterSizes size) /* TODO: Work in progress, column based, side-by-side traceRA={*} format that looks like this (note order will change, columns will widen etc): Initially for Java on z, then sTR on z, then Java on other platforms. S = State; W = Weight; V = Virtual Register; RC = Ref Count) - +---------------------------------+----------------------------------+------------------------------+------------------------------+ - | Name S W Flag V RC | Name S W Flag V RC | Name S W Flag V RC | Name S W Flag V RC | - +---------------------------------+----------------------------------+------------------------------+------------------------------+ - | GPR0 80 Free | HPR0 80 Free | VRF16 80 Free | FPR0 80 Free FPR_34 4/5 | - | GPR1 80 Free | HPR1 80 Free | VRF17 80 Free | FPR1 80 Free | + +---------------------------------+------------------------------+------------------------------+ + | Name S W Flag V RC | Name S W Flag V RC | Name S W Flag V RC | + +---------------------------------+------------------------------+------------------------------+ + | GPR0 80 Free | VRF16 80 Free | FPR0 80 Free FPR_34 4/5 | + | GPR1 80 Free | VRF17 80 Free | FPR1 80 Free | .. */ void TR_Debug::printFullRegInfoNewFormat(TR::FILE *pOutFile, TR::Register * rr) @@ -4691,7 +4691,6 @@ TR_Debug::traceRegisterAssignment(TR::Instruction *instr, bool insertedByRA, boo #if 0 /* Work in progress side-by side traceRA={*} */ const bool isGPR = _registerKindsToAssign & TR_GPR_Mask; - const bool isHPR = _registerKindsToAssign & TR_HPR_Mask; const bool isVRF = _registerKindsToAssign & TR_VRF_Mask; const bool isFPR = _registerKindsToAssign & TR_FPR_Mask; const bool isX87 = _registerKindsToAssign & TR_X87_Mask; diff --git a/compiler/z/codegen/OMRCodeGenerator.cpp b/compiler/z/codegen/OMRCodeGenerator.cpp index c372211a2bd..e19f6c9ac1d 100644 --- a/compiler/z/codegen/OMRCodeGenerator.cpp +++ b/compiler/z/codegen/OMRCodeGenerator.cpp @@ -1987,7 +1987,7 @@ OMR::Z::CodeGenerator::doRegisterAssignment(TR_RegisterKinds kindsToAssign) { if (self()->getDebug()) { - TR_RegisterKinds rks = (TR_RegisterKinds)(TR_GPR_Mask | TR_HPR_Mask | TR_FPR_Mask | TR_VRF_Mask); + TR_RegisterKinds rks = (TR_RegisterKinds)(TR_GPR_Mask | TR_FPR_Mask | TR_VRF_Mask); self()->getDebug()->startTracingRegisterAssignment("backward", rks); } diff --git a/compiler/z/codegen/OMRInstruction.cpp b/compiler/z/codegen/OMRInstruction.cpp index 9bdad580a3e..df72646182d 100644 --- a/compiler/z/codegen/OMRInstruction.cpp +++ b/compiler/z/codegen/OMRInstruction.cpp @@ -394,22 +394,11 @@ OMR::Z::Instruction::useRegister(TR::Register * reg, bool isDummy) "[%p] Register Pairs should be allocated using allocateConsecutivePair.\n", self()); } - if (_opcode.is64bit() || _opcode.is32to64bit()) - { - firstRegister->setIsUpperBitsAreDirty(true); - lastRegister->setIsUpperBitsAreDirty(true); - } - OMR::Instruction::useRegister(firstRegister); OMR::Instruction::useRegister(lastRegister); } else { - if (_opcode.is64bit() || _opcode.is32to64bit()) - { - reg->setIsUpperBitsAreDirty(true); - } - OMR::Instruction::useRegister(reg); // If an instruction uses a dummy register, that register should no longer be considered dummy. diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index da1ece916ea..9012e234465 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -2099,7 +2099,6 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, if (!useGPR0) { availRegMask &= ~TR::RealRegister::GPR0Mask; - availRegMask &= ~TR::RealRegister::HPR0Mask; } // We can't use FPRs for vector registers when current instruction is a call @@ -2747,14 +2746,21 @@ OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Regi } else { - if (virtReg->assignToGPR()) + if (virtReg->is64BitReg()) { + TR::Register * associatedVirtual = NULL; + bool usedInMemRef = false; + if (realReg->getState() == TR::RealRegister::Assigned) { - TR::Register * associatedVirtual = realReg->getAssignedRegister(); - bool usedInMemRef = associatedVirtual->isUsedInMemRef(); - - if ((!iInterfere && i==preference && pref_favored) || !usedInMemRef) + // candidate is LW's virtReg in case if both LW and HW need to be spilled + associatedVirtual = realReg->getAssignedRegister(); + usedInMemRef = associatedVirtual->isUsedInMemRef(); + } + + if ((realReg->getState() == TR::RealRegister::Assigned || realReg->getState() == TR::RealRegister::Free)) + { + if ((!iInterfere && i==preference && pref_favored) || (!usedInMemRef)) { if (numCandidates == 0) { @@ -2774,21 +2780,14 @@ OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Regi numCandidates++; } } - else if (virtReg->is64BitReg()) + else { - TR::Register * associatedVirtual = NULL; - bool usedInMemRef = false; - if (realReg->getState() == TR::RealRegister::Assigned) { - // candidate is LW's virtReg in case if both LW and HW need to be spilled - associatedVirtual = realReg->getAssignedRegister(); - usedInMemRef = associatedVirtual->isUsedInMemRef(); - } - - if ((realReg->getState() == TR::RealRegister::Assigned || realReg->getState() == TR::RealRegister::Free)) - { - if ((!iInterfere && i==preference && pref_favored) || (!usedInMemRef)) + TR::Register * associatedVirtual = realReg->getAssignedRegister(); + bool usedInMemRef = associatedVirtual->isUsedInMemRef(); + + if ((!iInterfere && i==preference && pref_favored) || !usedInMemRef) { if (numCandidates == 0) { @@ -3859,55 +3858,6 @@ OMR::Z::Machine::initializeRegisterFile() _registerFile[TR::RealRegister::FPR15] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_FPR, 0, TR::RealRegister::Free, TR::RealRegister::FPR15, TR::RealRegister::FPR15Mask, self()->cg()); - // Initialize High Regs - _registerFile[TR::RealRegister::HPR0] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_GPR, 0, TR::RealRegister::Free, - TR::RealRegister::HPR0, TR::RealRegister::HPR0Mask, self()->cg()); - - _registerFile[TR::RealRegister::HPR1] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_GPR, 0, TR::RealRegister::Free, - TR::RealRegister::HPR1, TR::RealRegister::HPR1Mask, self()->cg()); - - _registerFile[TR::RealRegister::HPR2] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_GPR, 0, TR::RealRegister::Free, - TR::RealRegister::HPR2, TR::RealRegister::HPR2Mask, self()->cg()); - - _registerFile[TR::RealRegister::HPR3] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_GPR, 0, TR::RealRegister::Free, - TR::RealRegister::HPR3, TR::RealRegister::HPR3Mask, self()->cg()); - - _registerFile[TR::RealRegister::HPR4] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_GPR, 0, TR::RealRegister::Free, - TR::RealRegister::HPR4, TR::RealRegister::HPR4Mask, self()->cg()); - - _registerFile[TR::RealRegister::HPR5] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_GPR, 0, TR::RealRegister::Free, - TR::RealRegister::HPR5, TR::RealRegister::HPR5Mask, self()->cg()); - - _registerFile[TR::RealRegister::HPR6] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_GPR, 0, TR::RealRegister::Free, - TR::RealRegister::HPR6, TR::RealRegister::HPR6Mask, self()->cg()); - - _registerFile[TR::RealRegister::HPR7] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_GPR, 0, TR::RealRegister::Free, - TR::RealRegister::HPR7, TR::RealRegister::HPR7Mask, self()->cg()); - - _registerFile[TR::RealRegister::HPR8] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_GPR, 0, TR::RealRegister::Free, - TR::RealRegister::HPR8, TR::RealRegister::HPR8Mask, self()->cg()); - - _registerFile[TR::RealRegister::HPR9] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_GPR, 0, TR::RealRegister::Free, - TR::RealRegister::HPR9, TR::RealRegister::HPR9Mask, self()->cg()); - - _registerFile[TR::RealRegister::HPR10] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_GPR, 0, TR::RealRegister::Free, - TR::RealRegister::HPR10, TR::RealRegister::HPR10Mask, self()->cg()); - - _registerFile[TR::RealRegister::HPR11] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_GPR, 0, TR::RealRegister::Free, - TR::RealRegister::HPR11, TR::RealRegister::HPR11Mask, self()->cg()); - - _registerFile[TR::RealRegister::HPR12] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_GPR, 0, TR::RealRegister::Free, - TR::RealRegister::HPR12, TR::RealRegister::HPR12Mask, self()->cg()); - - _registerFile[TR::RealRegister::HPR13] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_GPR, 0, TR::RealRegister::Free, - TR::RealRegister::HPR13, TR::RealRegister::HPR13Mask, self()->cg()); - - _registerFile[TR::RealRegister::HPR14] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_GPR, 0, TR::RealRegister::Free, - TR::RealRegister::HPR14, TR::RealRegister::HPR14Mask, self()->cg()); - - _registerFile[TR::RealRegister::HPR15] = new (self()->cg()->trHeapMemory()) TR::RealRegister(TR_GPR, 0, TR::RealRegister::Free, - TR::RealRegister::HPR15, TR::RealRegister::HPR15Mask, self()->cg()); - // Initialize Vector Regs // first 16 overlaps with FPRs _registerFile[TR::RealRegister::VRF0] = _registerFile[TR::RealRegister::FPR0]; diff --git a/compiler/z/codegen/OMRRealRegister.cpp b/compiler/z/codegen/OMRRealRegister.cpp index 1b4929264f1..5e7e5a48e6e 100644 --- a/compiler/z/codegen/OMRRealRegister.cpp +++ b/compiler/z/codegen/OMRRealRegister.cpp @@ -239,14 +239,14 @@ OMR::Z::RealRegister::setRegister4Field(uint32_t *instruction,RegNum reg) bool OMR::Z::RealRegister::isPseudoRealReg(RegNum reg) { - return (reg < FirstGPR || reg > LastHPR); + return (reg < FirstGPR || reg > LastVRF); } // static method bool OMR::Z::RealRegister::isRealReg(RegNum reg) { - return (reg >= FirstGPR && reg <= LastHPR); + return (reg >= FirstGPR && reg <= LastVRF); } // static method @@ -269,16 +269,6 @@ OMR::Z::RealRegister::isFPR(RegNum reg) return false; } -// static method -bool -OMR::Z::RealRegister::isHPR(RegNum reg) - { - if(reg >= FirstHPR && reg <= LastHPR) - return true; - else - return false; - } - // static method bool OMR::Z::RealRegister::isVRF(RegNum reg) @@ -359,21 +349,4 @@ const uint8_t OMR::Z::RealRegister::_fullRegBinaryEncodings[TR::RealRegister::Nu 0x1D, // VRF29 0x1E, // VRF30 0x1F, // VRF31 - - 0x00, // HPR0 - 0x01, // HPR1 - 0x02, // HPR2 - 0x03, // HPR3 - 0x04, // HPR4 - 0x05, // HPR5 - 0x06, // HPR6 - 0x07, // HPR7 - 0x08, // HPR8 - 0x09, // HPR9 - 0x0A, // HPR10 - 0x0B, // HPR11 - 0x0C, // HPR12 - 0x0D, // HPR13 - 0x0E, // HPR14 - 0x0F, // HPR15 }; diff --git a/compiler/z/codegen/OMRRealRegister.hpp b/compiler/z/codegen/OMRRealRegister.hpp index 15bcb4cc78b..f2e9d7290f1 100644 --- a/compiler/z/codegen/OMRRealRegister.hpp +++ b/compiler/z/codegen/OMRRealRegister.hpp @@ -93,7 +93,6 @@ class OMR_EXTENSIBLE RealRegister : public OMR::RealRegister static bool isRealReg(RegNum reg); static bool isGPR(RegNum reg); static bool isFPR(RegNum reg); - static bool isHPR(RegNum reg); static bool isVRF(RegNum reg); private: diff --git a/compiler/z/codegen/OMRRegister.cpp b/compiler/z/codegen/OMRRegister.cpp index 40643f9747d..3d6757170ff 100644 --- a/compiler/z/codegen/OMRRegister.cpp +++ b/compiler/z/codegen/OMRRegister.cpp @@ -79,12 +79,6 @@ OMR::Z::Register::setPlaceholderReg() OMR::Register::setPlaceholderReg(); } -bool -OMR::Z::Register::assignToGPR() - { - return !(self()->is64BitReg()); - } - ncount_t OMR::Z::Register::decFutureUseCount(ncount_t fuc) { diff --git a/compiler/z/codegen/OMRRegister.hpp b/compiler/z/codegen/OMRRegister.hpp index 79bc30125e4..e0c46fe530f 100644 --- a/compiler/z/codegen/OMRRegister.hpp +++ b/compiler/z/codegen/OMRRegister.hpp @@ -59,7 +59,6 @@ class OMR_EXTENSIBLE Register: public OMR::Register Register(TR_RegisterKinds rk); Register(TR_RegisterKinds rk, uint16_t ar); - public: /* @@ -75,9 +74,6 @@ class OMR_EXTENSIBLE Register: public OMR::Register TR::MemoryReference *getMemRef() { return _memRef; } void setMemRef(TR::MemoryReference *memRef) { _memRef = memRef; } - - - /* * Methods for manipulating flags */ @@ -88,18 +84,13 @@ class OMR_EXTENSIBLE Register: public OMR::Register bool is64BitReg(); void setIs64BitReg(bool b = true); - bool assignToGPR(); - bool isDependencySet() {return _flags.testAny(DependencySet);} void setDependencySet(bool v) {if (v) _flags.set(DependencySet);} bool alreadySignExtended() {return _flags.testAny(AlreadySignExtended);} void setAlreadySignExtended() {_flags.set(AlreadySignExtended);} void resetAlreadySignExtended() {_flags.reset(AlreadySignExtended);} - - bool isUpperBitsAreDirty() {return _flags.testAny(UpperBitsAreDirty);} - void setIsUpperBitsAreDirty(bool b = true) {_flags.set(UpperBitsAreDirty, b);} - + /* * Overriding Base Class Implementation of these methods */ @@ -110,7 +101,6 @@ class OMR_EXTENSIBLE Register: public OMR::Register bool containsCollectedReference(); void setContainsCollectedReference(); - /* * Methods specialized in derived classes */ @@ -134,7 +124,6 @@ class OMR_EXTENSIBLE Register: public OMR::Register DependencySet = 0x0200, // 390 flag, post dependancy was assigned AlreadySignExtended = 0x1000, // determine whether i2l should be nops - UpperBitsAreDirty = 0x8000, // Bits 63-32 were clobbered }; //Both x and z have this field, but power has own specialization, may move to base @@ -146,11 +135,8 @@ class OMR_EXTENSIBLE Register: public OMR::Register // Both x and z have this, but power doesn't, so duplicating in both x and z TR::MemoryReference *_memRef; - }; - } - } #endif /* OMR_Z_REGISTER_INCL */ diff --git a/compiler/z/codegen/OMRRegisterDependency.cpp b/compiler/z/codegen/OMRRegisterDependency.cpp index fb2f153587e..e92e133f0c0 100644 --- a/compiler/z/codegen/OMRRegisterDependency.cpp +++ b/compiler/z/codegen/OMRRegisterDependency.cpp @@ -695,11 +695,7 @@ TR_S390RegisterDependencyGroup::checkRegisterPairSufficiencyAndHPRAssignment(TR: virtRegI->setIs64BitReg(true); } - if (TR::RealRegister::isHPR(realRegI)) - { - cg->maskAvailableHPRSpillMask(~(machine->getRealRegister(realRegI)->getRealRegisterMask())); - } - else if (TR::RealRegister::isGPR(realRegI) && virtRegI->is64BitReg()) + if (virtRegI->is64BitReg()) { cg->maskAvailableHPRSpillMask(~(machine->getRealRegister(realRegI)->getRealRegisterMask() << 16)); } @@ -936,7 +932,6 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru } uint32_t numGPRs = 0; - uint32_t numHPRs = 0; uint32_t numFPRs = 0; uint32_t numVRFs = 0; @@ -959,9 +954,6 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru case TR_GPR: ++numGPRs; break; - case TR_HPR: - ++numHPRs; - break; case TR_FPR: ++numFPRs; break; diff --git a/compiler/z/codegen/PseudoRegisterEnum.hpp b/compiler/z/codegen/PseudoRegisterEnum.hpp index 6cfd0d2f353..708c510986b 100644 --- a/compiler/z/codegen/PseudoRegisterEnum.hpp +++ b/compiler/z/codegen/PseudoRegisterEnum.hpp @@ -24,16 +24,16 @@ * definitions are permitted. */ - EvenOddPair = LastHPR + 1, // Assign an even/odd pair to the reg pair - LegalEvenOfPair = LastHPR + 2, // Assign an even reg that is followed by an unlocked odd register - LegalOddOfPair = LastHPR + 3, // Assign an odd reg that is preceded by an unlocked even register - FPPair = LastHPR + 4, // Assign an FP pair to the reg pair - LegalFirstOfFPPair = LastHPR + 5, // Assign first FP reg of a FP reg Pair - LegalSecondOfFPPair = LastHPR + 6, // Assign second FP reg of a FP reg Pair - AssignAny = LastHPR + 7, // Assign any register - KillVolHighRegs = LastHPR + 8, // Kill all volatile access regs - MayDefine = LastHPR + 9, // This instruction's result should be modelled as live before as this instruction only 'may defines' the register - SpilledReg = LastHPR + 10, // OOL: Any Spilled register cross OOL sequences + EvenOddPair = LastVRF + 1, // Assign an even/odd pair to the reg pair + LegalEvenOfPair = LastVRF + 2, // Assign an even reg that is followed by an unlocked odd register + LegalOddOfPair = LastVRF + 3, // Assign an odd reg that is preceded by an unlocked even register + FPPair = LastVRF + 4, // Assign an FP pair to the reg pair + LegalFirstOfFPPair = LastVRF + 5, // Assign first FP reg of a FP reg Pair + LegalSecondOfFPPair = LastVRF + 6, // Assign second FP reg of a FP reg Pair + AssignAny = LastVRF + 7, // Assign any register + KillVolHighRegs = LastVRF + 8, // Kill all volatile access regs + MayDefine = LastVRF + 9, // This instruction's result should be modelled as live before as this instruction only 'may defines' the register + SpilledReg = LastVRF + 10, // OOL: Any Spilled register cross OOL sequences - NumRegisters = LastHPR + 1 // (include noReg) + NumRegisters = LastVRF + 1 // (include noReg) diff --git a/compiler/z/codegen/RealRegisterEnum.hpp b/compiler/z/codegen/RealRegisterEnum.hpp index 70d8884af8a..8165ef0e634 100644 --- a/compiler/z/codegen/RealRegisterEnum.hpp +++ b/compiler/z/codegen/RealRegisterEnum.hpp @@ -112,26 +112,4 @@ FirstAssignableVRF= VRF0, /* Need this until we complete overlapping FPR/VRF implementation */ LastAssignableVRF = VRF31, FirstOverlapVRF = VRF0, - LastOverlapVRF = VRF15, - - HPRBase = LastVRF, - - HPR0 = HPRBase + 1, - HPR1 = HPRBase + 2, - HPR2 = HPRBase + 3, - HPR3 = HPRBase + 4, - HPR4 = HPRBase + 5, - HPR5 = HPRBase + 6, - HPR6 = HPRBase + 7, - HPR7 = HPRBase + 8, - HPR8 = HPRBase + 9, - HPR9 = HPRBase + 10, - HPR10 = HPRBase + 11, - HPR11 = HPRBase + 12, - HPR12 = HPRBase + 13, - HPR13 = HPRBase + 14, - HPR14 = HPRBase + 15, - HPR15 = HPRBase + 16, - - FirstHPR = HPR0, - LastHPR = HPR15 + LastOverlapVRF = VRF15 diff --git a/compiler/z/codegen/RealRegisterMaskEnum.hpp b/compiler/z/codegen/RealRegisterMaskEnum.hpp index bf2b9c14f22..9b96ff2b363 100644 --- a/compiler/z/codegen/RealRegisterMaskEnum.hpp +++ b/compiler/z/codegen/RealRegisterMaskEnum.hpp @@ -59,23 +59,6 @@ FPR14Mask = 0x0000000000004000, FPR15Mask = 0x0000000000008000, - HPR0Mask = 0x0000000000010000, - HPR1Mask = 0x0000000000020000, - HPR2Mask = 0x0000000000040000, - HPR3Mask = 0x0000000000080000, - HPR4Mask = 0x0000000000100000, - HPR5Mask = 0x0000000000200000, - HPR6Mask = 0x0000000000400000, - HPR7Mask = 0x0000000000800000, - HPR8Mask = 0x0000000001000000, - HPR9Mask = 0x0000000002000000, - HPR10Mask = 0x0000000004000000, - HPR11Mask = 0x0000000008000000, - HPR12Mask = 0x0000000010000000, - HPR13Mask = 0x0000000020000000, - HPR14Mask = 0x0000000040000000, - HPR15Mask = 0x0000000080000000, - VRF0Mask = FPR0Mask, VRF1Mask = FPR1Mask, VRF2Mask = FPR2Mask, diff --git a/compiler/z/codegen/S390Debug.cpp b/compiler/z/codegen/S390Debug.cpp index ef5c7b501c8..8fbab62030a 100644 --- a/compiler/z/codegen/S390Debug.cpp +++ b/compiler/z/codegen/S390Debug.cpp @@ -2310,38 +2310,6 @@ getRegisterName(TR::RealRegister::RegNum num, bool isVRF = false) return "VRF30"; case TR::RealRegister::VRF31: return "VRF31"; - case TR::RealRegister::HPR0: - return "HPR0"; - case TR::RealRegister::HPR1: - return "HPR1"; - case TR::RealRegister::HPR2: - return "HPR2"; - case TR::RealRegister::HPR3: - return "HPR3"; - case TR::RealRegister::HPR4: - return "HPR4"; - case TR::RealRegister::HPR5: - return "HPR5"; - case TR::RealRegister::HPR6: - return "HPR6"; - case TR::RealRegister::HPR7: - return "HPR7"; - case TR::RealRegister::HPR8: - return "HPR8"; - case TR::RealRegister::HPR9: - return "HPR9"; - case TR::RealRegister::HPR10: - return "HPR10"; - case TR::RealRegister::HPR11: - return "HPR11"; - case TR::RealRegister::HPR12: - return "HPR12"; - case TR::RealRegister::HPR13: - return "HPR13"; - case TR::RealRegister::HPR14: - return "HPR14"; - case TR::RealRegister::HPR15: - return "HPR15"; case TR::RealRegister::FPPair: return "FPPair"; case TR::RealRegister::LegalFirstOfFPPair: From 078b63a3f6dec4042f296e5e790736915f4fd93d Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Wed, 6 Mar 2019 14:14:38 -0500 Subject: [PATCH 19/23] Fold checkDependencyGroup This API really served two purposes: 1. Calculate the available register mask 2. Various HPR related checks We fold away the API and in the single place that it is used we replace with with just the caluclation of the available register map. In fact we leave a TODO here to pre-calculate this value as it should be a compile time constant for every method compilation. There should be no need to dynamically calculate it for every register dependency. The various HPR related checks set flags like `is64BitReg` and verified that there were no duplicate HPR/GPR register dependencies. Anecdotally this API actually consumed the most compile time in the entire compiler (not just the codegen, even the optimizer) because of the O(n^2) algorithm it used for each dependency list which can be rather large given GPRS, FPRs, VRFs, and HPRs. Signed-off-by: Filip Jeremic --- compiler/z/codegen/OMRCodeGenerator.hpp | 4 - compiler/z/codegen/OMRRegisterDependency.cpp | 197 +------------------ compiler/z/codegen/OMRRegisterDependency.hpp | 12 -- 3 files changed, 5 insertions(+), 208 deletions(-) diff --git a/compiler/z/codegen/OMRCodeGenerator.hpp b/compiler/z/codegen/OMRCodeGenerator.hpp index 1ddae09de21..118519d4aaa 100644 --- a/compiler/z/codegen/OMRCodeGenerator.hpp +++ b/compiler/z/codegen/OMRCodeGenerator.hpp @@ -446,9 +446,6 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator virtual bool getSupportsBitPermute(); int32_t getEstimatedExtentOfLitLoop() {return _extentOfLitPool;} - int64_t setAvailableHPRSpillMask(int64_t i) {return _availableHPRSpillMask = i;} - int64_t maskAvailableHPRSpillMask(int64_t i) {return _availableHPRSpillMask &= i;} - int64_t getAvailableHPRSpillMask() {return _availableHPRSpillMask;} int32_t getPreprologueOffset() { return _preprologueOffset; } int32_t setPreprologueOffset(int32_t offset) { return _preprologueOffset = offset; } @@ -819,7 +816,6 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator TR::S390ImmInstruction *_returnTypeInfoInstruction; int32_t _extentOfLitPool; // excludes snippets - uint64_t _availableHPRSpillMask; protected: TR::list _constantList; diff --git a/compiler/z/codegen/OMRRegisterDependency.cpp b/compiler/z/codegen/OMRRegisterDependency.cpp index e92e133f0c0..1ddb719ee77 100644 --- a/compiler/z/codegen/OMRRegisterDependency.cpp +++ b/compiler/z/codegen/OMRRegisterDependency.cpp @@ -627,6 +627,10 @@ TR_S390RegisterDependencyGroup::genBitMapOfAssignableGPRs(TR::CodeGenerator * cg { TR::Machine* machine = cg->machine(); + // TODO: This looks like it can be cached as it should be the same value every time in a single compilation. Should + // also investigate whether we even need this? Don't we already block registers which are part of a dependency? I + // suppose with a mask we can avoid shuffling things into GPRs which are part of the dependency and may need to get + // other virtual registers shuffled into such GPRs. Need to think about this. Are other codegens doing this? uint32_t availRegMap = machine->genBitMapOfAssignableGPRs(); for (uint32_t i = 0; i < numberOfRegisters; i++) @@ -641,197 +645,6 @@ TR_S390RegisterDependencyGroup::genBitMapOfAssignableGPRs(TR::CodeGenerator * cg return availRegMap; } - -/** \brief - * Checks to ensure that we have enough register pairs available to satisfy all register - * dependencies in the current dependency group and aborts the - * compilation if not enough register pairs are available. - * - * Also, if highword facility is supported, this function checks the type of each register - * dependency condition and sets HPR related flags for future register assignment steps. - * - * \param cg - * The code generator used to query various machine state. - * - * \param currentInstruction - * The instruction on which the register dependency group is attached. - * - * \param availableGPRMap - * The bitmask of available GRP registers. - * - * \param numOfDependencies - * The number of pre or post dependencies in the register dependency group. - **/ -void -TR_S390RegisterDependencyGroup::checkRegisterPairSufficiencyAndHPRAssignment(TR::CodeGenerator *cg, - TR::Instruction* currentInstruction, - const uint32_t availableGPRMap, - uint32_t numOfDependencies) - { - TR::Machine* machine = cg->machine(); - - uint32_t numReqPairs = 0, numAvailPairs = 0; - - // Count the number of required pairs to be assigned in reg deps - for (int32_t i = 0; i < numOfDependencies; i++) - { - TR::RealRegister::RegNum realRegI = _dependencies[i].getRealRegister(); - TR::Register* virtRegI = _dependencies[i].getRegister(); - - if (realRegI == TR::RealRegister::EvenOddPair) - numReqPairs++; - - if (virtRegI && - virtRegI->getKind() != TR_FPR && - virtRegI->getKind() != TR_VRF) - { - // on 64-bit conservatively assume rEP and rRA are going to clobber highword - if (TR::Compiler->target.is64Bit() && - !(currentInstruction->isLabel() && - toS390LabelInstruction(currentInstruction)->getLabelSymbol()->isStartOfColdInstructionStream()) && - (realRegI == cg->getReturnAddressRegister() || - realRegI == cg->getEntryPointRegister())) - { - virtRegI->setIs64BitReg(true); - } - - if (virtRegI->is64BitReg()) - { - cg->maskAvailableHPRSpillMask(~(machine->getRealRegister(realRegI)->getRealRegisterMask() << 16)); - } - } - } - - // Count the number of even-odd GPR pairs remaining after deps are filled and breaks early if the - // number of register pairs in available is sufficient. - bool isRegPairSufficient = false; - - if (numReqPairs > 0) - { - for (int32_t i = 0; i < NUM_S390_GPR; i += 2) - { - if ((availableGPRMap >> i) & 0x3 == 0x3) - { - numAvailPairs++; - if (numAvailPairs >= numReqPairs) - { - isRegPairSufficient = true; - break; - } - } - } - } - else - { - isRegPairSufficient = true; - } - - if (!isRegPairSufficient) - { - TR::Compilation *comp = cg->comp(); - if (cg->getDebug()) - { - trfprintf(comp->getOutFile(), "\nNum AVAIL PAIRS %d, Num REQ PAIRS %d\n", numAvailPairs, numReqPairs); - trfprintf(comp->getOutFile(), "AVAIL REG MAP %x\n", availableGPRMap); - cg->getDebug()->printRegisterDependencies(comp->getOutFile(), this, numOfDependencies); - } - TR_ASSERT( 0, "checkDependencyGroup::Insufficient available pairs to satisfy all reg deps.\n"); - comp->failCompilation("checkDependencyGroup::Insufficient available pairs to satisfy all reg deps, abort compilation\n"); - } - } - -/** - * - * \brief - * Performs pairwise checks in dependencies to find duplicates - * - * 1. If the duplicated registers are virtual registers or real registers, assert fail. - * 2. If the duplicated registers are GPR/HPR dependencies, remove the duplicates. - * - * \param cg - * The CodeGenerator object used to query machine states - * - * \param numOfDependencies - * The number of register dependency conditions to examine. - */ -void -TR_S390RegisterDependencyGroup::checkRegisterDependencyDuplicates(TR::CodeGenerator* cg, - const uint32_t numOfDependencies) - { - TR::Compilation *comp = cg->comp(); - - if (numOfDependencies <= 1) - return; - - for (uint32_t i = 0; i < numOfDependencies - 1; ++i) - { - TR::Register* virtRegI = _dependencies[i].getRegister(); - TR::Register* virtRegJ; - TR::RealRegister::RegNum realRegI = _dependencies[i].getRealRegister(); - TR::RealRegister::RegNum realRegJ; - - for (uint32_t j = i + 1; j < numOfDependencies; ++j) - { - virtRegJ = _dependencies[j].getRegister(); - realRegJ = _dependencies[j].getRealRegister(); - - if (virtRegI == virtRegJ - && realRegI != TR::RealRegister::SpilledReg - && realRegJ != TR::RealRegister::SpilledReg) - { - TR_ASSERT(false, "Virtual register duplicate found in a register dependency\n"); - } - - if (realRegI == realRegJ && - TR::RealRegister::isRealReg(realRegI)) - { - TR_ASSERT(false, "Real register duplicate found in a register dependency\n"); - } - } - } - } - -/** - * - * \brief - * Generates a uint32_t bit map for available GPR registers. - * This function also checks to make sure that there are enough register pairs - * for assignment, and that there are no duplicates in real, virtual, and - * HPR registers. - * - * \param cg - * The CodeGenerator object used to query machine states - * - * \param currentInstruction - * The current instruction on which the register dependency group is attached. - * - * \param numOfDependencies - * The number of register dependency conditions to examine. - * - * \return - * a bit mask of available GPR map. - * Bit is set to 1 if the GPR is available, and 0 otherwise. -*/ -uint32_t -TR_S390RegisterDependencyGroup::checkDependencyGroup(TR::CodeGenerator * cg, - TR::Instruction * currentInstruction, - uint32_t numOfDependencies) - { - // availableGPRMap is a bitmap of all available (not locked) GPRs on the machine - // excluding the real registers already specified in the _dependencies. - uint32_t availableGPRMap = genBitMapOfAssignableGPRs(cg, numOfDependencies); - cg->setAvailableHPRSpillMask(0xFFFF0000); - - ///// Check the number of register pairs. The compilation may fail due to insufficient register pairs - checkRegisterPairSufficiencyAndHPRAssignment(cg, currentInstruction, availableGPRMap, - numOfDependencies); - - ///// Check and remove duplicates - checkRegisterDependencyDuplicates(cg, numOfDependencies); - - return availableGPRMap; - } - void TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstruction, TR_RegisterKinds kindToBeAssigned, @@ -845,7 +658,7 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru TR::RealRegister * dependentRealReg, * assignedRegister; int32_t i, j; bool changed; - uint32_t availRegMask = checkDependencyGroup(cg, currentInstruction, numOfDependencies); + uint32_t availRegMask = genBitMapOfAssignableGPRs(cg, numOfDependencies); if (!comp->getOption(TR_DisableOOL)) { diff --git a/compiler/z/codegen/OMRRegisterDependency.hpp b/compiler/z/codegen/OMRRegisterDependency.hpp index 010e567efa8..771cc39ed5b 100644 --- a/compiler/z/codegen/OMRRegisterDependency.hpp +++ b/compiler/z/codegen/OMRRegisterDependency.hpp @@ -157,18 +157,6 @@ class TR_S390RegisterDependencyGroup _dependencies[index].setRealRegister(regNum); } - void checkRegisterPairSufficiencyAndHPRAssignment(TR::CodeGenerator *cg, - TR::Instruction *currentInstruction, - const uint32_t availableGPRMap, - uint32_t numOfDependencies); - - void checkRegisterDependencyDuplicates(TR::CodeGenerator* cg, - const uint32_t numOfDependencies); - - uint32_t checkDependencyGroup(TR::CodeGenerator *cg, - TR::Instruction *currentInstruction, - uint32_t numOfDependencies); - void assignRegisters(TR::Instruction *currentInstruction, TR_RegisterKinds kindToBeAssigned, uint32_t numberOfRegisters, From 6b5b5331c229b91c15d61c8eb24f18d70dafa231 Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Wed, 6 Mar 2019 14:26:17 -0500 Subject: [PATCH 20/23] Fold generateExtendedHighWordInstruction Signed-off-by: Filip Jeremic --- compiler/z/codegen/S390Debug.cpp | 51 ++----- .../z/codegen/S390GenerateInstructions.cpp | 135 ------------------ .../z/codegen/S390GenerateInstructions.hpp | 9 -- compiler/z/codegen/S390Instruction.hpp | 9 -- 4 files changed, 9 insertions(+), 195 deletions(-) diff --git a/compiler/z/codegen/S390Debug.cpp b/compiler/z/codegen/S390Debug.cpp index 8fbab62030a..f3e837d7f89 100644 --- a/compiler/z/codegen/S390Debug.cpp +++ b/compiler/z/codegen/S390Debug.cpp @@ -564,15 +564,8 @@ TR_Debug::print(TR::FILE *pOutFile, TR::S390RIEInstruction * instr) printPrefix(pOutFile, instr); // print the opcode - if (RIE5 && instr->getExtendedHighWordOpCode().getOpCodeValue() != TR::InstOpCode::BAD) - { - // print extended-mnemonics for highword rotate instructions on zG - trfprintf(pOutFile, "%-*s", OPCODE_SPACING, instr->getExtendedHighWordOpCode().getMnemonicName()); - } - else - { - trfprintf(pOutFile, "%-*s", OPCODE_SPACING, instr->getOpCode().getMnemonicName()); - } + + trfprintf(pOutFile, "%-*s", OPCODE_SPACING, instr->getOpCode().getMnemonicName()); // grab the registers. TR::Register * targetRegister = instr->getRegisterOperand(1); @@ -611,34 +604,11 @@ TR_Debug::print(TR::FILE *pOutFile, TR::S390RIEInstruction * instr) // print the source regiser (R2) print(pOutFile, sourceRegister); - // do not print out the rest for highword extended-mnemonics - if (instr->getExtendedHighWordOpCode().getOpCodeValue() == TR::InstOpCode::BAD) - { - trfprintf(pOutFile, ","); - // print the immediate value - trfprintf(pOutFile, "%u,", (uint8_t)instr->getSourceImmediate8One()); - // print the immediate value - trfprintf(pOutFile, "%u,", (uint8_t)instr->getSourceImmediate8Two()); - } - if (instr->getExtendedHighWordOpCode().getOpCodeValue() == TR::InstOpCode::SLLHH) - { - trfprintf(pOutFile, ","); - // print the immediate value - trfprintf(pOutFile, "%u", (uint8_t)instr->getSourceImmediate8()); - } - if (instr->getExtendedHighWordOpCode().getOpCodeValue() == TR::InstOpCode::SLLLH) - { - trfprintf(pOutFile, ","); - // print the immediate value - trfprintf(pOutFile, "%u", (uint8_t)instr->getSourceImmediate8()-32); - } - if (instr->getExtendedHighWordOpCode().getOpCodeValue() == TR::InstOpCode::SRLHH || - instr->getExtendedHighWordOpCode().getOpCodeValue() == TR::InstOpCode::SRLLH) - { - trfprintf(pOutFile, ","); - // print the immediate value - trfprintf(pOutFile, "%u", (uint8_t)instr->getSourceImmediate8One()); - } + trfprintf(pOutFile, ","); + // print the immediate value + trfprintf(pOutFile, "%u,", (uint8_t)instr->getSourceImmediate8One()); + // print the immediate value + trfprintf(pOutFile, "%u,", (uint8_t)instr->getSourceImmediate8Two()); } else { @@ -648,11 +618,8 @@ TR_Debug::print(TR::FILE *pOutFile, TR::S390RIEInstruction * instr) if (RIE5) { - if (instr->getExtendedHighWordOpCode().getOpCodeValue() == TR::InstOpCode::BAD) - { - // print the immediate value - trfprintf(pOutFile, "%u", (uint8_t)instr->getSourceImmediate8()); - } + // print the immediate value + trfprintf(pOutFile, "%u", (uint8_t)instr->getSourceImmediate8()); } else if(!RIE4) { diff --git a/compiler/z/codegen/S390GenerateInstructions.cpp b/compiler/z/codegen/S390GenerateInstructions.cpp index 2b398212bf9..db1d3e24e31 100644 --- a/compiler/z/codegen/S390GenerateInstructions.cpp +++ b/compiler/z/codegen/S390GenerateInstructions.cpp @@ -463,19 +463,6 @@ TR::Instruction * generateRRInstruction(TR::CodeGenerator * cg, TR::InstOpCode::Mnemonic op, TR::Node * n, TR::Register * treg, TR::Register * sreg, TR::Instruction * preced) { - switch(op) - { - case TR::InstOpCode::LHHR: - return generateExtendedHighWordInstruction(n, cg, TR::InstOpCode::LHHR, treg, sreg, 0, preced); - break; - case TR::InstOpCode::LLHFR: - return generateExtendedHighWordInstruction(n, cg, TR::InstOpCode::LLHFR, treg, sreg, 0, preced); - break; - case TR::InstOpCode::LHLR: - return generateExtendedHighWordInstruction(n, cg, TR::InstOpCode::LHLR, treg, sreg, 0, preced); - break; - } - TR::Instruction *instr; if (preced) instr = new (INSN_HEAP) TR::S390RRInstruction(op, n, treg, sreg, preced, cg); @@ -2980,128 +2967,6 @@ generateSerializationInstruction(TR::CodeGenerator *cg, TR::Node *node, TR::Inst return instr; } -/** - * Generate Highword instructions using extended-mnemonic syntax - * for example: - * Load (High <- Low) LHLR R1 R2 = RISBHGZ (R1, R2, 0, 31, 32) z7 only - */ -TR::Instruction * -generateExtendedHighWordInstruction(TR::Node * node, TR::CodeGenerator *cg, TR::InstOpCode::Mnemonic op, - TR::Register * targetReg, TR::Register * srcReg, int8_t imm8, TR::Instruction * preced) - { - TR::Instruction * cursor = NULL; - TR_Debug * debugObj = cg->getDebug(); - char * COMMENT; - bool isTargetHWUsed, isSrcHWUsed, isTargetLWUsed, isSrcLWUsed; // make sure to not clobber the flags - TR::Compilation *comp = cg->comp(); - - switch(op) - { - case TR::InstOpCode::LHHR: // Load (High <- High) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RISBHG, node, targetReg, srcReg, 0, 31+0x80, 0, preced); - COMMENT = "LHHR : Load (High <- High)"; - break; - case TR::InstOpCode::LHLR: // Load (High <- Low) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RISBHG, node, targetReg, srcReg, 0, 31+0x80, 32, preced); - COMMENT = "LHLR : Load (High <- Low)"; - break; - case TR::InstOpCode::LLHFR: // Load (Low <- High) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RISBLG, node, targetReg, srcReg, 0, 31+0x80, 32, preced); - COMMENT = "LLHFR : Load (Low <- High)"; - break; - case TR::InstOpCode::LLHHHR: // Load Logical Halfword (High <- High) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RISBHG, node, targetReg, srcReg, 16, 31+0x80, 0, preced); - COMMENT = "LLHHHR : Load Logical Halfword (High <- High)"; - break; - case TR::InstOpCode::LLHHLR: // Load Logical Halfword (High <- Low) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RISBHG, node, targetReg, srcReg, 16, 31+0x80, 32, preced); - COMMENT = "LLHHLR : Load Logical Halfword (High <- Low)"; - break; - case TR::InstOpCode::LLHLHR: // Load Logical Halfword (Low <- High) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RISBLG, node, targetReg, srcReg, 16, 31+0x80, 32, preced); - COMMENT = "LLHLHR : Load Logical Halfword (Low <- High)"; - break; - case TR::InstOpCode::LLCHHR: // Load Logical Character (High <- High) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RISBHG, node, targetReg, srcReg, 24, 31+0x80, 0, preced); - COMMENT = "LLCHHR : Load Logical Character (High <- High)"; - break; - case TR::InstOpCode::LLCHLR: // Load Logical Character (High <- Low) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RISBHG, node, targetReg, srcReg, 24, 31+0x80, 32, preced); - COMMENT = "LLCHLR : Load Logical Character (High <- Low)"; - break; - case TR::InstOpCode::LLCLHR: // Load Logical Character (Low <- High) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RISBLG, node, targetReg, srcReg, 24, 31+0x80, 32, preced); - COMMENT = "LLCLHR : Load Logical Character (Low <- High)"; - break; - case TR::InstOpCode::SLLHH: // Shift Left Logical (High <- High) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RISBHG, node, targetReg, srcReg, 0, 31-imm8+0x80, imm8, preced); - COMMENT = "SLLHH : Shift Left Logical (High <- High)"; - break; - case TR::InstOpCode::SLLLH: // Shift Left Logical (Low <- High) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RISBLG, node, targetReg, srcReg, 0, 31-imm8+0x80, 32+imm8, preced); - COMMENT = "SLLLH : Shift Left Logical (Low <- High)"; - break; - case TR::InstOpCode::SRLHH: // Shift Right Logical (High <- High) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RISBHG, node, targetReg, srcReg, imm8, 31+0x80, -imm8, preced); - COMMENT = "SRLHH : Shift Right Logical (High <- High)"; - break; - case TR::InstOpCode::SRLLH: // Shift Right Logical (Low <- High) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RISBLG, node, targetReg, srcReg, imm8, 31+0x80, 32-imm8, preced); - COMMENT = "SRLHH : Shift Right Logical (Low <- High)"; - break; - case TR::InstOpCode::NHHR: // AND High (High <- High) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RNSBG, node, targetReg, srcReg, 0, 31, 0, preced); - COMMENT = "NHHR : AND High (High <- High)"; - break; - case TR::InstOpCode::NHLR: // AND High (High <- Low) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RNSBG, node, targetReg, srcReg, 0, 31, 32, preced); - COMMENT = "NHLR : AND High (High <- Low)"; - break; - case TR::InstOpCode::NLHR: // AND High (Low <- High) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RNSBG, node, targetReg, srcReg, 32, 63, 32, preced); - COMMENT = "NLHR : AND High (Low <- High)"; - break; - case TR::InstOpCode::XHHR: // XOR High (High <- High) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RXSBG, node, targetReg, srcReg, 0, 31, 0, preced); - COMMENT = "XHHR : XOR High (High <- High)"; - break; - case TR::InstOpCode::XHLR: // XOR High (High <- Low) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RXSBG, node, targetReg, srcReg, 0, 31, 32, preced); - COMMENT = "XHLR : XOR High (High <- Low)"; - break; - case TR::InstOpCode::XLHR: // XOR High (Low <- High) - cursor = generateRIEInstruction(cg, TR::InstOpCode::RXSBG, node, targetReg, srcReg, 32, 63, 32, preced); - COMMENT = "XLHR : XOR High (Low <- High)"; - break; - case TR::InstOpCode::OHHR: // OR High (High <- High) - cursor = generateRIEInstruction(cg, TR::InstOpCode::ROSBG, node, targetReg, srcReg, 0, 31, 0, preced); - COMMENT = "OHHR : OR High (High <- High)"; - break; - case TR::InstOpCode::OHLR: // OR High (High <- Low) - cursor = generateRIEInstruction(cg, TR::InstOpCode::ROSBG, node, targetReg, srcReg, 0, 31, 32, preced); - COMMENT = "OHLR : OR High (High <- Low)"; - break; - case TR::InstOpCode::OLHR: // OR High (Low <- High) - cursor = generateRIEInstruction(cg, TR::InstOpCode::ROSBG, node, targetReg, srcReg, 32, 63, 32, preced); - COMMENT = "OLHR : OR High (Low <- High)"; - break; - default: - TR_ASSERT(0, "OpCode not supported when calling generateExtendedHighWordInstruction()"); - break; - } - - ((TR::S390RIEInstruction *)cursor)->setExtendedHighWordOpCode(op); - - TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/HPR"); - - if (debugObj) - { - debugObj->addInstructionComment(cursor, COMMENT); - } - - return cursor; - } - /** * @deprecated - DO NOT USE. Use vsplatsEvaluator instead * Replicates node containing element to the given target vector register. diff --git a/compiler/z/codegen/S390GenerateInstructions.hpp b/compiler/z/codegen/S390GenerateInstructions.hpp index 44c75fe7362..75987205ada 100644 --- a/compiler/z/codegen/S390GenerateInstructions.hpp +++ b/compiler/z/codegen/S390GenerateInstructions.hpp @@ -1505,15 +1505,6 @@ TR::Instruction *generateRuntimeInstrumentationInstruction( TR::Register *target = NULL, TR::Instruction *preced = NULL); -TR::Instruction *generateExtendedHighWordInstruction( - TR::Node * node, - TR::CodeGenerator *cg, - TR::InstOpCode::Mnemonic op, - TR::Register * targetReg, - TR::Register * srcReg, - int8_t imm8, - TR::Instruction *preced = 0); - TR::Instruction * generateReplicateNodeInVectorReg(TR::Node * node, TR::CodeGenerator *cg, TR::Register * targetVRF, TR::Node * srcElementNode, int elementSize, TR::Register *zeroReg=NULL, TR::Instruction * preced=NULL); diff --git a/compiler/z/codegen/S390Instruction.hpp b/compiler/z/codegen/S390Instruction.hpp index dba2bd12167..71f4c9661b0 100644 --- a/compiler/z/codegen/S390Instruction.hpp +++ b/compiler/z/codegen/S390Instruction.hpp @@ -3129,7 +3129,6 @@ class S390RIEInstruction : public TR::S390RegInstruction private: /** This member will determine which form of RIE you have based on how we get constructed */ RIEForm _instructionFormat; - TR::InstOpCode _extendedHighWordOpCode; ///< for zG highword rotate instructions public: @@ -3220,7 +3219,6 @@ class S390RIEInstruction : public TR::S390RegInstruction TR::CodeGenerator * cg) : S390RegInstruction(op, n, targetRegister, cg), _instructionFormat(RIE_IMM), - _extendedHighWordOpCode(TR::InstOpCode::BAD), _branchDestination(0), _branchCondition(TR::InstOpCode::COND_NOPR), _sourceImmediate8(sourceImmediate), @@ -3243,7 +3241,6 @@ class S390RIEInstruction : public TR::S390RegInstruction TR::CodeGenerator * cg) : S390RegInstruction(op, n, targetRegister, precedingInstruction, cg), _instructionFormat(RIE_IMM), - _extendedHighWordOpCode(TR::InstOpCode::BAD), _branchDestination(0), _branchCondition(TR::InstOpCode::COND_NOPR), _sourceImmediate8(sourceImmediate), @@ -3305,7 +3302,6 @@ class S390RIEInstruction : public TR::S390RegInstruction TR::CodeGenerator * cg) : S390RegInstruction(op, n, targetRegister, precedingInstruction, cg), _instructionFormat(RIE_RRI16), - _extendedHighWordOpCode(TR::InstOpCode::BAD), _branchDestination(0), _branchCondition(TR::InstOpCode::COND_NOPR), _sourceImmediate8(0), @@ -3325,7 +3321,6 @@ class S390RIEInstruction : public TR::S390RegInstruction TR::CodeGenerator * cg) : S390RegInstruction(op, n, targetRegister, cg), _instructionFormat(RIE_RRI16), - _extendedHighWordOpCode(TR::InstOpCode::BAD), _branchDestination(0), _branchCondition(TR::InstOpCode::COND_NOPR), _sourceImmediate8(0), @@ -3345,10 +3340,6 @@ class S390RIEInstruction : public TR::S390RegInstruction virtual Kind getKind() { return IsRIE; } virtual RIEForm getRieForm() { return _instructionFormat; } - /** For zGryphon highword rotate instructions, extended mnemonics */ - virtual void setExtendedHighWordOpCode(TR::InstOpCode op) {_extendedHighWordOpCode = op;} - virtual TR::InstOpCode& getExtendedHighWordOpCode() { return _extendedHighWordOpCode;} - // get register information //virtual TR::Register * getSourceRegister() { return (_sourceRegSize!=0) ? (sourceRegBase())[0] : NULL; } // virtual TR::Register * getTargetRegister() { return S390RegInstruction::getTargetRegister(); } From a6f27540f7dbfd704261990ae3ffb0681c1649b2 Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Wed, 6 Mar 2019 14:50:15 -0500 Subject: [PATCH 21/23] Deprecate HPR related metadata Deprecate GCMap support for HPRs and all metadata stored for a particular method compilation. Signed-off-by: Filip Jeremic --- compiler/codegen/GCStackMap.hpp | 6 -- compiler/codegen/OMRGCRegisterMap.hpp | 9 +- compiler/codegen/OMRGCStackAtlas.cpp | 2 - compiler/z/codegen/InstOpCode.cpp | 37 ------- compiler/z/codegen/OMRCodeGenerator.cpp | 2 - compiler/z/codegen/OMRInstOpCode.hpp | 1 - compiler/z/codegen/OMRInstruction.cpp | 103 ------------------- compiler/z/codegen/OMRInstruction.hpp | 8 +- compiler/z/codegen/OMRLinkage.cpp | 5 +- compiler/z/codegen/OMRMachine.cpp | 46 ++------- compiler/z/codegen/OMRMachine.hpp | 5 +- compiler/z/codegen/OMRRegisterDependency.cpp | 18 ++-- compiler/z/codegen/S390Instruction.hpp | 1 - compiler/z/codegen/S390SystemLinkage.hpp | 18 +--- compiler/z/codegen/SystemLinkage.cpp | 53 +--------- compiler/z/env/OMRCPU.hpp | 2 +- fvtest/compilertest/env/FrontEnd.cpp | 3 - jitbuilder/env/FrontEnd.cpp | 3 - jitbuilder/env/FrontEnd.hpp | 2 +- 19 files changed, 28 insertions(+), 296 deletions(-) diff --git a/compiler/codegen/GCStackMap.hpp b/compiler/codegen/GCStackMap.hpp index fc9fdca8d56..a97551be443 100644 --- a/compiler/codegen/GCStackMap.hpp +++ b/compiler/codegen/GCStackMap.hpp @@ -224,11 +224,6 @@ class TR_GCStackMap uint32_t info) {_registerMap.maskRegistersWithInfoBits(mask, info);} void setInfoBits(uint32_t info) {_registerMap.setInfoBits(info);} - void setHighWordRegisterBits(uint32_t bits) {_registerMap.setHighWordRegisterBits(bits);} - void resetHighWordRegistersBits(uint32_t bits) {_registerMap.resetHighWordRegisterBits(bits);} - uint32_t getHighWordRegisterMap() {return _registerMap.getHPRMap();} - void clearHighWordRegisterMap() {_registerMap.emptyHPR();} - uint32_t getRegisterSaveDescription() {return _registerMap.getRegisterSaveDescription();} void setRegisterSaveDescription(uint32_t bits) {_registerMap.setRegisterSaveDescription(bits);} @@ -273,7 +268,6 @@ class TR_GCStackMap memcpy(newMap->_liveMonitorBits, getLiveMonitorBits(), getMapSizeInBytes()); } newMap->setRegisterBits(getRegisterMap()); - newMap->setHighWordRegisterBits(getHighWordRegisterMap()); return newMap; } diff --git a/compiler/codegen/OMRGCRegisterMap.hpp b/compiler/codegen/OMRGCRegisterMap.hpp index 37e9e21a2cd..7bca07e2b68 100644 --- a/compiler/codegen/OMRGCRegisterMap.hpp +++ b/compiler/codegen/OMRGCRegisterMap.hpp @@ -45,7 +45,7 @@ class GCRegisterMap TR_ALLOC(TR_Memory::GCRegisterMap) - GCRegisterMap() : _map(0), _registerSaveDescription(0), _hprmap(0) {} + GCRegisterMap() : _map(0), _registerSaveDescription(0) {} TR::GCRegisterMap * self(); @@ -57,11 +57,6 @@ class GCRegisterMap void maskRegistersWithInfoBits(uint32_t mask, uint32_t info) {_map = (mask & (_map | info));} void setInfoBits(uint32_t info) {_map |= info;} - uint32_t getHPRMap() {return _hprmap;} - void setHighWordRegisterBits(uint32_t bits) {_hprmap |= bits;} - void resetHighWordRegisterBits(uint32_t bits) { _hprmap &= ~bits; } - void emptyHPR() {_hprmap = 0;} - uint32_t getRegisterSaveDescription() {return _registerSaveDescription;} void setRegisterSaveDescription(uint32_t bits) {_registerSaveDescription = bits;} @@ -69,8 +64,6 @@ class GCRegisterMap uint32_t _map; uint32_t _registerSaveDescription; - uint32_t _hprmap; - }; } diff --git a/compiler/codegen/OMRGCStackAtlas.cpp b/compiler/codegen/OMRGCStackAtlas.cpp index 04f9b280e99..4373bb77199 100644 --- a/compiler/codegen/OMRGCStackAtlas.cpp +++ b/compiler/codegen/OMRGCStackAtlas.cpp @@ -79,7 +79,6 @@ OMR::GCStackAtlas::close(TR::CodeGenerator *cg) int32_t mapBytes = map->getMapSizeInBytes(); if (mapBytes == nextMap->getMapSizeInBytes() && map->getRegisterMap() == nextMap->getRegisterMap() && - map->getHighWordRegisterMap() == nextMap->getHighWordRegisterMap() && !memcmp(map->getMapBits(), nextMap->getMapBits(), mapBytes) && map->isByteCodeInfoIdenticalTo(nextMap)) { @@ -135,7 +134,6 @@ OMR::GCStackAtlas::addStackMap(TR_GCStackMap *m) map->isInternalPointerMapIdenticalTo(m)))) { map->setRegisterBits(m->getRegisterMap()); - map->setHighWordRegisterBits(m->getHighWordRegisterMap()); // Adjust for the fact that we're not adding a map // diff --git a/compiler/z/codegen/InstOpCode.cpp b/compiler/z/codegen/InstOpCode.cpp index ed4380f5e00..54dece46309 100644 --- a/compiler/z/codegen/InstOpCode.cpp +++ b/compiler/z/codegen/InstOpCode.cpp @@ -69,43 +69,6 @@ OMR::Z::InstOpCode::isAdmin() _mnemonic == DCB); } -uint32_t -OMR::Z::InstOpCode::isHighWordInstruction() - { - return (_mnemonic == AHHHR || - _mnemonic == AHHLR || - _mnemonic == AIH || - _mnemonic == ALHHHR || - _mnemonic == ALHHLR || - _mnemonic == ALSIH || - _mnemonic == ALSIHN || - _mnemonic == BRCTH || - _mnemonic == CHF || - _mnemonic == CHHR || - _mnemonic == CHLR || - _mnemonic == CIH || - _mnemonic == CLHF || - _mnemonic == CLHHR || - _mnemonic == CLHLR || - _mnemonic == CLIH || - _mnemonic == LBH || - _mnemonic == LHH || - _mnemonic == LFH || - _mnemonic == LFHAT || - _mnemonic == LLCH || - _mnemonic == LLHH || - _mnemonic == RISBHG || - _mnemonic == RISBLG || - _mnemonic == STCH || - _mnemonic == STHH || - _mnemonic == STFH || - _mnemonic == SHHHR || - _mnemonic == SHHLR || - _mnemonic == SLHHHR || - _mnemonic == SLHHLR); - } - - uint64_t OMR::Z::InstOpCode::setsOperand(uint32_t opNum) { diff --git a/compiler/z/codegen/OMRCodeGenerator.cpp b/compiler/z/codegen/OMRCodeGenerator.cpp index e19f6c9ac1d..6c2a0ea6888 100644 --- a/compiler/z/codegen/OMRCodeGenerator.cpp +++ b/compiler/z/codegen/OMRCodeGenerator.cpp @@ -549,8 +549,6 @@ OMR::Z::CodeGenerator::CodeGenerator() TR::Compilation *comp = self()->comp(); _cgFlags = 0; - TR::DebugCounter::incStaticDebugCounter(comp, "hpr/total-compilations"); - // Initialize Linkage for Code Generator self()->initializeLinkage(); diff --git a/compiler/z/codegen/OMRInstOpCode.hpp b/compiler/z/codegen/OMRInstOpCode.hpp index 6a28fa4fce6..22a79d9d7fd 100644 --- a/compiler/z/codegen/OMRInstOpCode.hpp +++ b/compiler/z/codegen/OMRInstOpCode.hpp @@ -639,7 +639,6 @@ class InstOpCode: public OMR::InstOpCode /* Queries for instruction properties */ uint32_t hasBypass(); uint32_t isAdmin(); - uint32_t isHighWordInstruction(); uint64_t isOperandHW(uint32_t i); uint64_t setsOperand(uint32_t opNum); diff --git a/compiler/z/codegen/OMRInstruction.cpp b/compiler/z/codegen/OMRInstruction.cpp index df72646182d..f2f686d9e67 100644 --- a/compiler/z/codegen/OMRInstruction.cpp +++ b/compiler/z/codegen/OMRInstruction.cpp @@ -819,109 +819,6 @@ OMR::Z::Instruction::assignRegisters(TR_RegisterKinds kindToBeAssigned) } - - -///// registerSets utilities for generic register assignment - -bool -OMR::Z::Instruction::isHPRUpgradable(uint16_t operandNumber) - { - if (_opcode.is64bit()) - return false; - - switch (self()->getOpCodeValue()) - { - case TR::InstOpCode::AR: - case TR::InstOpCode::ALR: - //AHHHR, AHHLR, - //ALHHHR, ALHHLR - //Target Reg cannot be low word - if (operandNumber == 0) return true; - break; - case TR::InstOpCode::AHI: - //AIH - return true; - break; - case TR::InstOpCode::BRCT: - //BRCTH - return true; - break; - case TR::InstOpCode::CR: - case TR::InstOpCode::CLR: - //CHHR, CHLR - //CLHHR, CLHLR - if (operandNumber == 0) - return true; - break; - case TR::InstOpCode::C: - case TR::InstOpCode::CY: - case TR::InstOpCode::CL: - case TR::InstOpCode::CLY: - //CHF, CIH - if (operandNumber == 0) return true; - break; - case TR::InstOpCode::CFI: - case TR::InstOpCode::CLFI: - //CLHF, CLIH - return true; - break; - case TR::InstOpCode::LB: - case TR::InstOpCode::LH: - case TR::InstOpCode::LHY: - case TR::InstOpCode::L: - case TR::InstOpCode::LY: - case TR::InstOpCode::LLC: - case TR::InstOpCode::LLH: - //LBH LHH LFH LLCH LLHH - if (operandNumber == 0) return true; - break; - case TR::InstOpCode::LR: - case TR::InstOpCode::LLCR: - case TR::InstOpCode::LLHR: - //LHHR, LHLR, LLHFR - //LLCHHR, LLCHLR, LLCLHR - //LLHHR, LLHHLR, LLHLHR - return true; - break; - case TR::InstOpCode::LHI: - //IIHF need to manually sign-extend - return true; - break; - /* --- RNSBG etc are cracked, not worth it - case TR::InstOpCode::NR: - case TR::InstOpCode::OR: - case TR::InstOpCode::XR: - //NHHR, NHLR, NLHR - //OHHR, OHLR, OLHR - //XHHR, XHLR, XLHR - return true; - break; - */ - case TR::InstOpCode::ST: - case TR::InstOpCode::STY: - case TR::InstOpCode::STC: - case TR::InstOpCode::STCY: - case TR::InstOpCode::STH: - case TR::InstOpCode::STHY: - //STFH, STCH, STHH - if (operandNumber == 0) return true; - break; - case TR::InstOpCode::SR: - case TR::InstOpCode::SLR: - //SHHHR, SHHLR - //SLHHHR, SLHHR - if (operandNumber == 0) return true; - break; - case TR::InstOpCode::SLFI: - //ALSIH - return true; - break; - default: - return false; - } - return false; - } - uint32_t OMR::Z::Instruction::useSourceRegister(TR::Register * reg) { diff --git a/compiler/z/codegen/OMRInstruction.hpp b/compiler/z/codegen/OMRInstruction.hpp index 49f0b86cfcb..6fcbc00223b 100644 --- a/compiler/z/codegen/OMRInstruction.hpp +++ b/compiler/z/codegen/OMRInstruction.hpp @@ -436,14 +436,8 @@ class OMR_EXTENSIBLE Instruction : public OMR::Instruction uint32_t useTargetRegister(TR::Register* reg); uint32_t useSourceMemoryReference(TR::MemoryReference* memRef); uint32_t useTargetMemoryReference(TR::MemoryReference* memRef, TR::MemoryReference* sourceMemRef); - - - bool isHPRUpgradable(uint16_t regType); - + bool checkRegForGPR0Disable(TR::InstOpCode::Mnemonic op, TR::Register* reg); - - - }; } diff --git a/compiler/z/codegen/OMRLinkage.cpp b/compiler/z/codegen/OMRLinkage.cpp index 95019be288d..b61969169f2 100644 --- a/compiler/z/codegen/OMRLinkage.cpp +++ b/compiler/z/codegen/OMRLinkage.cpp @@ -2634,9 +2634,8 @@ OMR::Z::Linkage::setupRegisterDepForLinkage(TR::Node * callNode, TR_DispatchType TR::RegisterDependencyConditions * &deps, int64_t & killMask, TR::SystemLinkage * systemLinkage, TR::Node * &GlobalRegDeps, bool &hasGlRegDeps, TR::Register ** methodAddressReg, TR::Register * &JavaLitOffsetReg) { - int32_t numDeps = systemLinkage->getNumberOfDependencyGPRegisters(); - - numDeps += 16; //HPRs need to be spilled + // Extra dependency for killing volatile high registers (see KillVolHighRegs) + int32_t numDeps = systemLinkage->getNumberOfDependencyGPRegisters() + 1; if (self()->cg()->getSupportsVectorRegisters()) numDeps += 32; //VRFs need to be spilled diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index 9012e234465..7a935cf2f80 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -148,11 +148,9 @@ OMR::Z::Machine::registerCopy(TR::CodeGenerator* cg, } case TR_FPR: cursor = generateRRInstruction(cg, TR::InstOpCode::LDR, node, targetReg, sourceReg, precedingInstruction); - TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/FPR"); break; case TR_VRF: cursor = generateVRRaInstruction(cg, TR::InstOpCode::VLR, node, targetReg, sourceReg, precedingInstruction); - TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/VRF"); break; } @@ -208,8 +206,6 @@ OMR::Z::Machine::registerExchange(TR::CodeGenerator* cg, } else { - TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/FPR", 3); - TR::Instruction * currentInstruction = precedingInstruction; TR_BackingStore * location; location = cg->allocateSpill(8, false, NULL); @@ -246,8 +242,6 @@ OMR::Z::Machine::registerExchange(TR::CodeGenerator* cg, } else { - TR::DebugCounter::incStaticDebugCounter(cg->comp(), "hpr/shuffle/VRF", 3); - TR_BackingStore * location; location = cg->allocateSpill(16, false, NULL); TR::MemoryReference * tempMR = generateS390MemoryReference(currentNode, location->getSymbolReference(), cg); @@ -1029,7 +1023,7 @@ OMR::Z::Machine::assignBestRegisterSingle(TR::Register *targetRegister, assignedRegister = newAssignedRegister; } } - } // end if(enabledHighWordRA && assignedRegister != NULL) + } else if(assignedRegister != NULL && (assignedRegister->getRealRegisterMask() & availRegMask) == 0) { // Oh no.. targetRegister is assigned something it shouldn't be assigned to @@ -2190,7 +2184,7 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, } bestRegister = NULL; } - else // Pre zG+ machine don't support Highword facility + else { if (bestRegister != NULL && (bestRegister->getState() == TR::RealRegister::Free || bestRegister->getState() == TR::RealRegister::Unlatched)) @@ -2408,7 +2402,6 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, } else { - // Only need LW or HW TR::RealRegister * candidate = NULL; if (preference != 0 && (prefRegMask & availRegMask) && _registerFile[preference] != NULL) { @@ -2753,7 +2746,6 @@ OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Regi if (realReg->getState() == TR::RealRegister::Assigned) { - // candidate is LW's virtReg in case if both LW and HW need to be spilled associatedVirtual = realReg->getAssignedRegister(); usedInMemRef = associatedVirtual->isUsedInMemRef(); } @@ -2947,7 +2939,6 @@ OMR::Z::Machine::spillRegister(TR::Instruction * currentInstruction, TR::Registe } else { - TR::DebugCounter::incStaticDebugCounter(comp, "hpr/spill/FPR"); location = self()->cg()->allocateSpill(8, false, NULL, true); // TODO: Use 4 for single-precision values if (debugObj) self()->cg()->traceRegisterAssignment("\nSpilling FPR %s to (%p)\n", debugObj->getName(virtReg),location); @@ -2955,7 +2946,6 @@ OMR::Z::Machine::spillRegister(TR::Instruction * currentInstruction, TR::Registe opCode = TR::InstOpCode::LD; break; case TR_VRF: - TR::DebugCounter::incStaticDebugCounter(comp, "hpr/spill/VRF"); // Spill of size 16 has never been done before. The call hierarchy seems to support it but this should be watched closely. location = self()->cg()->allocateSpill(16, false, NULL, true); if (debugObj) @@ -3368,19 +3358,8 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction virtualRegister->block(); currentTargetVirtual->block(); - if (virtualRegister->is64BitReg()) - { - // if we end up spilling currentTargetVirtual to HPR, make sure to not pick the HPR of targetRegister since it will not - // free up the full 64 bit register - spareReg = self()->freeBestRegister(currentInstruction, currentTargetVirtual, currentTargetVirtual->getKind(), true); - } - else - { - // we can allow freeBestRegister() to return NULL here, as long as we can perform register exchange later via memory - // and take a bad OSC penalty - // todo: fix HW RA to enable register exchange later - spareReg = self()->freeBestRegister(currentInstruction, currentTargetVirtual, currentTargetVirtual->getKind(), true); - } + spareReg = self()->freeBestRegister(currentInstruction, currentTargetVirtual, currentTargetVirtual->getKind(), true); + virtualRegister->unblock(); currentTargetVirtual->unblock(); } @@ -3390,8 +3369,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction // virtual register is currently assigned to a different register, if (currentAssignedRegister != NULL) { - - // todo :HW fix if (!self()->isAssignable(currentTargetVirtual, currentAssignedRegister)) { { @@ -3465,7 +3442,7 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction if (rk != TR_FPR && rk != TR_VRF && currentTargetVirtual) { - // this happens for OOL HPR spill, simply return + // this happens for OOL spill, simply return if (currentTargetVirtual == virtualRegister) { virtualRegister->setAssignedRegister(targetRegister); @@ -3489,7 +3466,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction { // We may not be able to do an exchange as the target virtReg is not // allowed to be assigned to the source's realReg (e.g. GPR0). - // reg exchange with HW not implemented yet if (!self()->isAssignable(currentTargetVirtual, currentAssignedRegister) || (rk != TR_FPR && rk != TR_VRF)) { // There is an alternative to blindly spilling because: @@ -3503,8 +3479,7 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction virtualRegister->block(); if (virtualRegister->is64BitReg()) { - // if we end up spilling currentTargetVirtual to HPR, make sure to not pick the HPR of targetRegister since it will not - // free up the full 64 bit register + // TODO: Can we allow a null return here? Why are the two paths different? spareReg = self()->freeBestRegister(currentInstruction, currentTargetVirtual, currentTargetVirtual->getKind()); } else @@ -3614,8 +3589,8 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction virtualRegister->block(); if (virtualRegister->is64BitReg()) { - // if we end up spilling currentTargetVirtual to HPR, make sure to not pick the HPR of targetRegister since it will not - // free up the full 64 bit register + // TODO: Can we allow a null return here? Why are the two paths different? There is a similar case + // above. spareReg = self()->freeBestRegister(currentInstruction, currentTargetVirtual, currentTargetVirtual->getKind()); } else @@ -3714,9 +3689,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction { // virtual register is currently assigned to a different register, // override it with the target reg - - // todo: HW copy, LW copy or 64bit? - // if targetReg is HW, copy need to be HW cursor = self()->registerCopy(self()->cg(), rk, currentAssignedRegister, targetRegister, currentInstruction); currentAssignedRegister->setState(TR::RealRegister::Free); @@ -4274,7 +4246,7 @@ OMR::Z::Machine::initGlobalVectorRegisterMap(uint32_t vectorOffset) self()->setFirstOverlappedGlobalVRFRegisterNumber(firstOverlappingVecOffset); // equiv to VRF0 self()->setLastOverlappedGlobalVRFRegisterNumber(lastOverlappingVecOffset); // equiv to VRF16 - // Similar to HPR/GPR overlap, FPR and VRF will have same 'lastOverlapping' grn. + // Similar FPR and VRF will have same 'lastOverlapping' grn. self()->setLastGlobalFPRRegisterNumber(self()->getLastOverlappedGlobalVRFRegisterNumber()); if (traceVectorGRN) diff --git a/compiler/z/codegen/OMRMachine.hpp b/compiler/z/codegen/OMRMachine.hpp index bdad3098ddf..619bd92d916 100644 --- a/compiler/z/codegen/OMRMachine.hpp +++ b/compiler/z/codegen/OMRMachine.hpp @@ -54,7 +54,6 @@ template class List; // Number of machine registers #define NUM_S390_GPR 16 -#define NUM_S390_HPR 16 #define NUM_S390_FPR 16 #define NUM_S390_VRF 16 ///< 32 after full RA complete #define NUM_S390_FPR_PAIRS 8 @@ -179,7 +178,7 @@ namespace Z class OMR_EXTENSIBLE Machine : public OMR::Machine { TR::Register *_registerAssociations[TR::RealRegister::NumRegisters]; - uint32_t _globalRegisterNumberToRealRegisterMap[NUM_S390_GPR+NUM_S390_FPR+NUM_S390_VRF+NUM_S390_HPR]; + uint32_t _globalRegisterNumberToRealRegisterMap[NUM_S390_GPR+NUM_S390_FPR+NUM_S390_VRF]; TR::RealRegister::RegNum _S390FirstOfFPRegisterPairs[NUM_S390_FPR_PAIRS]; TR::RealRegister::RegNum _S390SecondOfFPRegisterPairs[NUM_S390_FPR_PAIRS]; @@ -232,8 +231,6 @@ class OMR_EXTENSIBLE Machine : public OMR::Machine uint8_t getGPRSize(); uint8_t getFPRSize() const { return 8;} - uint8_t getARSize() const { return 4;} - uint8_t getHPRSize() const { return 4;} uint8_t getVRFSize() const { return 16;} TR::RegisterDependencyConditions * createDepCondForLiveGPRs(TR::list *spilledRegisterList); diff --git a/compiler/z/codegen/OMRRegisterDependency.cpp b/compiler/z/codegen/OMRRegisterDependency.cpp index 1ddb719ee77..67c809b299e 100644 --- a/compiler/z/codegen/OMRRegisterDependency.cpp +++ b/compiler/z/codegen/OMRRegisterDependency.cpp @@ -1361,31 +1361,27 @@ TR_S390RegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstru } } - - // OOL slow path HPR spills if (!comp->getOption(TR_DisableOOL)) { - for (i = 0; i< numOfDependencies; i++) + // TODO: Is this HPR related? Do we need this code? + for (i = 0; i < numOfDependencies; i++) { - // we put {real HPR:SpilledReg} as deps for OOL HPR spills if (_dependencies[i].getRegister()->getRealRegister()) { - TR::RealRegister * highWordReg = toRealRegister(_dependencies[i].getRegister()); + TR::RealRegister* realReg = toRealRegister(_dependencies[i].getRegister()); dependentRegNum = _dependencies[i].getRealRegister(); if (dependentRegNum == TR::RealRegister::SpilledReg) { - virtReg = highWordReg->getAssignedRegister(); - //printf ("\nOOL HPR Spill in %s", comp->signature());fflush(stdout); - traceMsg(comp,"\nOOL HPR Spill: %s", cg->getDebug()->getName(highWordReg)); + virtReg = realReg->getAssignedRegister(); + + traceMsg(comp,"\nOOL HPR Spill: %s", cg->getDebug()->getName(realReg)); traceMsg(comp,":%s\n", cg->getDebug()->getName(virtReg)); - TR_ASSERT(virtReg, "\nOOL HPR spill: spilled HPR should have a virt Reg assigned!"); - // TR_ASSERT(highWordReg->isHighWordRegister(), "\nOOL HPR spill: spilled HPR should be a real HPR!"); + virtReg->setAssignedRegister(NULL); } } } } - } /** diff --git a/compiler/z/codegen/S390Instruction.hpp b/compiler/z/codegen/S390Instruction.hpp index 71f4c9661b0..76cb1f91a97 100644 --- a/compiler/z/codegen/S390Instruction.hpp +++ b/compiler/z/codegen/S390Instruction.hpp @@ -1367,7 +1367,6 @@ class S390RegInstruction : public TR::Instruction // if we are matching real regs if (reg->getKind() != TR_FPR && reg->getKind() != TR_VRF && getFirstRegister()->getRealRegister()) { - // reg pairs do not use HPRs targetReg1 = (TR::RealRegister *)getFirstRegister(); targetReg2 = toRealRegister(getLastRegister()); return realReg == targetReg1 || realReg == targetReg2; diff --git a/compiler/z/codegen/S390SystemLinkage.hpp b/compiler/z/codegen/S390SystemLinkage.hpp index 7402ae633f9..f8047054231 100644 --- a/compiler/z/codegen/S390SystemLinkage.hpp +++ b/compiler/z/codegen/S390SystemLinkage.hpp @@ -71,13 +71,10 @@ class S390SystemLinkage : public TR::Linkage TR::RealRegister::RegNum _debugHooksRegister; int16_t _GPRSaveMask; int16_t _FPRSaveMask; - int16_t _HPRSaveMask; int32_t _incomingParmAreaBeginOffset; int32_t _incomingParmAreaEndOffset; int32_t _FPRSaveAreaBeginOffset; int32_t _FPRSaveAreaEndOffset; - int32_t _HPRSaveAreaBeginOffset; - int32_t _HPRSaveAreaEndOffset; int32_t _LocalsAreaBeginOffset; int32_t _LocalsAreaEndOffset; int32_t _OutgoingParmAreaBeginOffset; @@ -108,9 +105,6 @@ class S390SystemLinkage : public TR::Linkage int16_t setFPRSaveMask(int16_t FPRSaveMask) { return _FPRSaveMask = FPRSaveMask; } int16_t getFPRSaveMask() { return _FPRSaveMask; } - int16_t setHPRSaveMask(int16_t HPRSaveMask) { return _HPRSaveMask = HPRSaveMask; } - int16_t getHPRSaveMask() { return _HPRSaveMask; } - static uint16_t flipBitsRegisterSaveMask(uint16_t mask); int32_t setGPRSaveAreaBeginOffset(int32_t GPRSaveAreaBeginOffset) { return _GPRSaveAreaBeginOffset = GPRSaveAreaBeginOffset; } @@ -123,11 +117,6 @@ class S390SystemLinkage : public TR::Linkage int32_t setFPRSaveAreaEndOffset(int32_t FPRSaveAreaEndOffset) { return _FPRSaveAreaEndOffset = FPRSaveAreaEndOffset; } int32_t getFPRSaveAreaEndOffset() { return _FPRSaveAreaEndOffset; } - int32_t setHPRSaveAreaBeginOffset(int32_t HPRSaveAreaBeginOffset) { return _HPRSaveAreaBeginOffset = HPRSaveAreaBeginOffset; } - int32_t getHPRSaveAreaBeginOffset() { return _HPRSaveAreaBeginOffset; } - int32_t setHPRSaveAreaEndOffset(int32_t HPRSaveAreaEndOffset) { return _HPRSaveAreaEndOffset = HPRSaveAreaEndOffset; } - int32_t getHPRSaveAreaEndOffset() { return _HPRSaveAreaEndOffset; } - int32_t setOutgoingParmAreaBeginOffset(int32_t OutgoingParmAreaBeginOffset) { return _OutgoingParmAreaBeginOffset = OutgoingParmAreaBeginOffset; } int32_t getOutgoingParmAreaBeginOffset() { return _OutgoingParmAreaBeginOffset; } int32_t setOutgoingParmAreaEndOffset(int32_t OutgoingParmAreaEndOffset) { return _OutgoingParmAreaEndOffset = OutgoingParmAreaEndOffset; } @@ -164,9 +153,9 @@ class S390SystemLinkage : public TR::Linkage public: S390SystemLinkage(TR::CodeGenerator * cg, TR_S390LinkageConventions elc=TR_S390LinkageDefault, TR_LinkageConventions lc=TR_System) : TR::Linkage(cg, elc,lc), - _GPRSaveMask(0), _FPRSaveMask(0), _HPRSaveMask(0) - { - } + _GPRSaveMask(0), + _FPRSaveMask(0) + {} virtual uint32_t getIntArgOffset(int32_t index) @@ -228,7 +217,6 @@ class S390SystemLinkage : public TR::Linkage // == General utilities (linkage independent) virtual TR::Instruction *addImmediateToRealRegister(TR::RealRegister * targetReg, int32_t immediate, TR::RealRegister *tempReg, TR::Node *node, TR::Instruction *cursor, bool *checkTempNeeded=NULL); virtual TR::Instruction *getputFPRs(TR::InstOpCode::Mnemonic opcode, TR::Instruction *cursor, TR::Node *node, TR::RealRegister *spReg=0); - virtual TR::Instruction *getputHPRs(TR::InstOpCode::Mnemonic opcode, TR::Instruction *cursor, TR::Node *node, TR::RealRegister *spReg=0); }; diff --git a/compiler/z/codegen/SystemLinkage.cpp b/compiler/z/codegen/SystemLinkage.cpp index 55f5242d32b..733a43b4e06 100644 --- a/compiler/z/codegen/SystemLinkage.cpp +++ b/compiler/z/codegen/SystemLinkage.cpp @@ -203,55 +203,6 @@ TR::S390SystemLinkage::getputFPRs(TR::InstOpCode::Mnemonic opcode, TR::Instructi return cursor; } -TR::Instruction * -TR::S390SystemLinkage::getputHPRs(TR::InstOpCode::Mnemonic opcode, TR::Instruction * cursor, TR::Node *node, TR::RealRegister *spReg) - { - int16_t HPRSaveMask; - int32_t offset, firstSaved, lastSaved, beginSaveOffset; - TR::MemoryReference *rsa; - int32_t i, j, hprSize; - - if (spReg == NULL) - { - spReg = getNormalStackPointerRealRegister(); - } - - HPRSaveMask = getHPRSaveMask(); - beginSaveOffset = getHPRSaveAreaEndOffset(); // following suit, see other getput functions, map stack - - lastSaved = TR::Linkage::getLastMaskedBit(HPRSaveMask); - firstSaved = TR::Linkage::getFirstMaskedBit(HPRSaveMask); - hprSize = cg()->machine()->getHPRSize(); - - j = 0; - uint8_t k = firstSaved; // dispel warning - bool previousWasOne = false; - offset = beginSaveOffset; // dispel warning - for(i = firstSaved; i <= lastSaved; ++i) - { - if(HPRSaveMask & (1 << i)) - { - if(!previousWasOne) - { - offset = beginSaveOffset + (j*hprSize); - k = i; - } - j++; - } - if(previousWasOne && (i == lastSaved || !(HPRSaveMask & (1 << i)))) - { - rsa = generateS390MemoryReference(spReg, offset, cg()); - int shift = (i == lastSaved) && (HPRSaveMask & (1 << i)) ? 0 : 1; - cursor = generateRSInstruction(cg(), opcode, - node, getRealRegister(REGNUM(k+TR::RealRegister::FirstGPR)), - getRealRegister(REGNUM(i-shift+TR::RealRegister::FirstGPR)), rsa, cursor); - } - previousWasOne = HPRSaveMask & (1 << i); - } - - return cursor; - } - /** * General utility * Returns @@ -1666,10 +1617,10 @@ TR::S390zLinuxSystemLinkage::checkLeafRoutine(int32_t stackFrameSize, TR::Instru // c) ensure stack pointer isn't used. TR::RealRegister * spReg = getStackPointerRealRegister(); - if(spReg->isUsedInMemRef() || getHPRSaveMask()) //don't need to check gprmask or hpr mask as these are saved in caller stack. + if (spReg->isUsedInMemRef()) //don't need to check gprmask as these are saved in caller stack. { if(comp()->getOption(TR_TraceCG)) - traceMsg(comp(), "LeafRoutine: stack pointer isUsedInMemRef = %d or hprsavemask = %d is set to 1\n",spReg->isUsedInMemRef(),getHPRSaveMask()); + traceMsg(comp(), "LeafRoutine: stack pointer isUsedInMemRef = %d is set to 1\n",spReg->isUsedInMemRef()); return ft; } diff --git a/compiler/z/env/OMRCPU.hpp b/compiler/z/env/OMRCPU.hpp index 048422b31c0..3a26d0f2a30 100644 --- a/compiler/z/env/OMRCPU.hpp +++ b/compiler/z/env/OMRCPU.hpp @@ -73,7 +73,7 @@ class CPU : public OMR::CPU bool getS390SupportsZNext() { return false; } - bool getS390SupportsHPRDebug() { return false; } + bool getS390SupportsHPR() { return false; } bool getS390SupportsDFP() { return false; } diff --git a/fvtest/compilertest/env/FrontEnd.cpp b/fvtest/compilertest/env/FrontEnd.cpp index 3816a63927e..e4897bef203 100644 --- a/fvtest/compilertest/env/FrontEnd.cpp +++ b/fvtest/compilertest/env/FrontEnd.cpp @@ -123,9 +123,6 @@ FrontEnd::mapsAreIdentical( mapCursor != stackAtlas->getParameterMap() && mapCursor->getMapSizeInBytes() == nextMapCursor->getMapSizeInBytes() && mapCursor->getRegisterMap() == nextMapCursor->getRegisterMap() && -#ifdef TR_HOST_S390 - (mapCursor->getHighWordRegisterMap() == nextMapCursor->getHighWordRegisterMap()) && -#endif !memcmp(mapCursor->getMapBits(), nextMapCursor->getMapBits(), mapCursor->getMapSizeInBytes())) { return true; diff --git a/jitbuilder/env/FrontEnd.cpp b/jitbuilder/env/FrontEnd.cpp index a03dadfc83d..5e090850057 100644 --- a/jitbuilder/env/FrontEnd.cpp +++ b/jitbuilder/env/FrontEnd.cpp @@ -125,9 +125,6 @@ FrontEnd::mapsAreIdentical( mapCursor != stackAtlas->getParameterMap() && mapCursor->getMapSizeInBytes() == nextMapCursor->getMapSizeInBytes() && mapCursor->getRegisterMap() == nextMapCursor->getRegisterMap() && -#ifdef TR_HOST_S390 - (mapCursor->getHighWordRegisterMap() == nextMapCursor->getHighWordRegisterMap()) && -#endif !memcmp(mapCursor->getMapBits(), nextMapCursor->getMapBits(), mapCursor->getMapSizeInBytes())) { return true; diff --git a/jitbuilder/env/FrontEnd.hpp b/jitbuilder/env/FrontEnd.hpp index 3483abf77db..5a92ac57bc4 100644 --- a/jitbuilder/env/FrontEnd.hpp +++ b/jitbuilder/env/FrontEnd.hpp @@ -60,7 +60,7 @@ class FrontEnd : public TR::FEBase #if defined(TR_TARGET_S390) virtual void generateBinaryEncodingPrologue(TR_BinaryEncodingData *beData, TR::CodeGenerator *cg); - virtual bool getS390SupportsHPRDebug() { return false; } + virtual bool getS390SupportsHPR() { return false; } #endif virtual intptrj_t methodTrampolineLookup(TR::Compilation *comp, TR::SymbolReference *symRef, void *currentCodeCache); From 3823e56840f4b7d2f8e53f28f6fbcf590855e8c3 Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Fri, 8 Mar 2019 16:26:56 -0500 Subject: [PATCH 22/23] Eliminate unnecessary uses of is64BitReg During the refactoring and folding away of HPR related code we notice quite a bit of code duplication becomes apparent particularly in the local RA (OMRMachine.cpp). Because we do not need to special case for HPRs a lot of the code can actually be commoned up and various `is64BitReg` queries removed because the `if` and `else` paths are identical. Once the `is64BitReg` paths are folded away then it becomes apparent that the FPR and VRF paths are now identical to that of GPR and those can then be further folded away. Signed-off-by: Filip Jeremic --- compiler/z/codegen/OMRMachine.cpp | 460 +++++------------------- compiler/z/codegen/OMRMachine.hpp | 5 - compiler/z/codegen/OMRTreeEvaluator.cpp | 14 +- 3 files changed, 90 insertions(+), 389 deletions(-) diff --git a/compiler/z/codegen/OMRMachine.cpp b/compiler/z/codegen/OMRMachine.cpp index 7a935cf2f80..cebbe1cbbb6 100644 --- a/compiler/z/codegen/OMRMachine.cpp +++ b/compiler/z/codegen/OMRMachine.cpp @@ -983,48 +983,21 @@ OMR::Z::Machine::assignBestRegisterSingle(TR::Register *targetRegister, { appendInst = currInst->getPrev(); } - if (targetRegister->is64BitReg()) - { - if ((assignedRegister->getRealRegisterMask() & availRegMask) == 0) - { - // Oh no.. targetRegister is assigned something it shouldn't be assigned to. Do some shuffling - // find a new register to shuffle to - TR::RealRegister * newAssignedRegister = self()->findBestRegisterForShuffle(currInst, targetRegister, availRegMask); - TR::Instruction *cursor = self()->registerCopy(self()->cg(), kindOfRegister, toRealRegister(assignedRegister), newAssignedRegister, appendInst); - assignedRegister->setAssignedRegister(NULL); - assignedRegister->setState(TR::RealRegister::Free); - assignedRegister = newAssignedRegister; - } - targetRegister->setAssignedRegister(assignedRegister); - assignedRegister->setAssignedRegister(targetRegister); - assignedRegister->setState(TR::RealRegister::Assigned); - } - else + if ((assignedRegister->getRealRegisterMask() & availRegMask) == 0) { - // if the register we are assigning is a source register of the instruction, - // the high-low word shuffling should happen before this instruction - TR::Instruction *appendInst = currInst; - if (!defsRegister && currInst->usesRegister(targetRegister) ) - { - appendInst = currInst->getPrev(); - } - - if ((assignedRegister->getRealRegisterMask() & availRegMask) == 0) - { - // Oh no.. targetRegister is assigned something it shouldn't be assigned to. Do some shuffling - // find a new register to shuffle to - TR::RealRegister * newAssignedRegister = self()->findBestRegisterForShuffle(currInst, targetRegister, availRegMask); - TR::Instruction *cursor = self()->registerCopy(self()->cg(), kindOfRegister, toRealRegister(assignedRegister), newAssignedRegister, appendInst); - newAssignedRegister->setAssignedRegister(targetRegister); - newAssignedRegister->setState(TR::RealRegister::Assigned); - assignedRegister->setAssignedRegister(NULL); - assignedRegister->setState(TR::RealRegister::Free); - assignedRegister = newAssignedRegister; - } + // Oh no.. targetRegister is assigned something it shouldn't be assigned to. Do some shuffling + // find a new register to shuffle to + TR::RealRegister * newAssignedRegister = self()->findBestRegisterForShuffle(currInst, targetRegister, availRegMask); + TR::Instruction *cursor = self()->registerCopy(self()->cg(), kindOfRegister, toRealRegister(assignedRegister), newAssignedRegister, appendInst); + newAssignedRegister->setAssignedRegister(targetRegister); + newAssignedRegister->setState(TR::RealRegister::Assigned); + assignedRegister->setAssignedRegister(NULL); + assignedRegister->setState(TR::RealRegister::Free); + assignedRegister = newAssignedRegister; } } - else if(assignedRegister != NULL && (assignedRegister->getRealRegisterMask() & availRegMask) == 0) + else if (assignedRegister != NULL && (assignedRegister->getRealRegisterMask() & availRegMask) == 0) { // Oh no.. targetRegister is assigned something it shouldn't be assigned to // Do some shuffling @@ -2168,34 +2141,15 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, * 4. TR::RealRegister::LegalSecondOfFPPair * 5. None of the above */ - if (virtualReg->is64BitReg()) - { - if (bestRegister != NULL && - (bestRegister->getState() == TR::RealRegister::Free || - bestRegister->getState() == TR::RealRegister::Unlatched)) - { - if (bestRegister->getState() == TR::RealRegister::Unlatched) - { - bestRegister->setAssignedRegister(NULL); - bestRegister->setState(TR::RealRegister::Free); - } - - return bestRegister; - } - bestRegister = NULL; - } - else + if (bestRegister != NULL && + (bestRegister->getState() == TR::RealRegister::Free || bestRegister->getState() == TR::RealRegister::Unlatched)) { - if (bestRegister != NULL && - (bestRegister->getState() == TR::RealRegister::Free || bestRegister->getState() == TR::RealRegister::Unlatched)) + if (bestRegister->getState() == TR::RealRegister::Unlatched) { - if (bestRegister->getState() == TR::RealRegister::Unlatched) - { - bestRegister->setAssignedRegister(NULL); - bestRegister->setState(TR::RealRegister::Free); - } - return bestRegister; + bestRegister->setAssignedRegister(NULL); + bestRegister->setState(TR::RealRegister::Free); } + return bestRegister; } } else if (self()->cg()->enableRegisterPairAssociation() && preference == TR::RealRegister::LegalOddOfPair) @@ -2227,34 +2181,15 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, // If the desired register is indeed free use it. // If not, default to standard search - if (virtualReg->is64BitReg()) - { - if (bestRegister != NULL && - (bestRegister->getState() == TR::RealRegister::Free || - bestRegister->getState() == TR::RealRegister::Unlatched)) - { - if (bestRegister->getState() == TR::RealRegister::Unlatched) - { - bestRegister->setAssignedRegister(NULL); - bestRegister->setState(TR::RealRegister::Free); - } - - return bestRegister; - } - bestRegister = NULL; - } - else + if (bestRegister != NULL && + (bestRegister->getState() == TR::RealRegister::Free || bestRegister->getState() == TR::RealRegister::Unlatched)) { - if (bestRegister != NULL && - (bestRegister->getState() == TR::RealRegister::Free || bestRegister->getState() == TR::RealRegister::Unlatched)) + if (bestRegister->getState() == TR::RealRegister::Unlatched) { - if (bestRegister->getState() == TR::RealRegister::Unlatched) - { - bestRegister->setAssignedRegister(NULL); - bestRegister->setState(TR::RealRegister::Free); - } - return bestRegister; + bestRegister->setAssignedRegister(NULL); + bestRegister->setState(TR::RealRegister::Free); } + return bestRegister; } } else if (self()->cg()->enableRegisterPairAssociation() && preference == TR::RealRegister::LegalFirstOfFPPair) @@ -2347,89 +2282,28 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, prefRegMask = TR::RealRegister::isRealReg((TR::RealRegister::RegNum)preference) ? _registerFile[preference]->getRealRegisterMask() : 0; } - if (rk != TR_GPR) + // Check if the preferred register is free + if ((prefRegMask & availRegMask) && _registerFile[preference] != NULL && + (_registerFile[preference]->getState() == TR::RealRegister::Free || + _registerFile[preference]->getState() == TR::RealRegister::Unlatched)) { - if ((prefRegMask & availRegMask) && _registerFile[preference] != NULL && - ((_registerFile[preference]->getState() == TR::RealRegister::Free) || - (_registerFile[preference]->getState() == TR::RealRegister::Unlatched))) - { - bestWeightSoFar = 0x0fffffff; + bestWeightSoFar = 0x0fffffff; + bestRegister = _registerFile[preference]; - bestRegister = _registerFile[preference]; - if (bestRegister != NULL && bestRegister->getState() == TR::RealRegister::Unlatched) - { - bestRegister->setAssignedRegister(NULL); - bestRegister->setState(TR::RealRegister::Free); - } - self()->cg()->setRegisterAssignmentFlag(TR_ByAssociation); - return bestRegister; - } - } - else - { - if (virtualReg->is64BitReg()) + if (bestRegister->getState() == TR::RealRegister::Unlatched) { - bool candidateLWFree = true; - - // if we have a preferred association - if (preference != 0 && (prefRegMask & availRegMask) && _registerFile[preference] != NULL) - { - candidateLWFree = - (_registerFile[preference]->getState() == TR::RealRegister::Free) || - (_registerFile[preference]->getState() == TR::RealRegister::Unlatched); - } - - // check if the preferred Full size reg is free - if ((prefRegMask & availRegMask) && candidateLWFree && _registerFile[preference] != NULL) - { - bestWeightSoFar = 0x0fffffff; - bestRegister = _registerFile[preference]; - if (bestRegister != NULL && bestRegister->getState() == TR::RealRegister::Unlatched) - { - bestRegister->setAssignedRegister(NULL); - bestRegister->setState(TR::RealRegister::Free); - } - - self()->cg()->setRegisterAssignmentFlag(TR_ByAssociation); - - if (bestRegister != NULL) - self()->cg()->traceRegisterAssignment("BEST FREE REG by pref for %R is %R", virtualReg, bestRegister); - else - self()->cg()->traceRegisterAssignment("BEST FREE REG by pref for %R is NULL", virtualReg); - - return bestRegister; - } + bestRegister->setAssignedRegister(NULL); + bestRegister->setState(TR::RealRegister::Free); } - else - { - TR::RealRegister * candidate = NULL; - if (preference != 0 && (prefRegMask & availRegMask) && _registerFile[preference] != NULL) - { - candidate = _registerFile[preference]; - } - if (candidate != NULL && - (prefRegMask & availRegMask) && - ((candidate->getState() == TR::RealRegister::Free) || - (candidate->getState() == TR::RealRegister::Unlatched))) - { - bestWeightSoFar = 0x0fffffff; - bestRegister = candidate; - if (bestRegister != NULL && bestRegister->getState() == TR::RealRegister::Unlatched) - { - bestRegister->setAssignedRegister(NULL); - bestRegister->setState(TR::RealRegister::Free); - } - self()->cg()->setRegisterAssignmentFlag(TR_ByAssociation); + self()->cg()->setRegisterAssignmentFlag(TR_ByAssociation); - if (bestRegister != NULL) - self()->cg()->traceRegisterAssignment("BEST FREE REG by pref for %R is %R", virtualReg, bestRegister); - else - self()->cg()->traceRegisterAssignment("BEST FREE REG by pref for %R is NULL", virtualReg); + if (bestRegister != NULL) + self()->cg()->traceRegisterAssignment("BEST FREE REG by pref for %R is %R", virtualReg, bestRegister); + else + self()->cg()->traceRegisterAssignment("BEST FREE REG by pref for %R is NULL", virtualReg); - return bestRegister; - } - } + return bestRegister; } } @@ -2441,100 +2315,30 @@ OMR::Z::Machine::findBestFreeRegister(TR::Instruction *currentInstruction, { uint64_t tRegMask = _registerFile[i]->getRealRegisterMask(); - if (rk != TR_GPR) + // Don't consider registers that can't be assigned. + if ((_registerFile[i]->getState() == TR::RealRegister::Locked) || ((tRegMask & availRegMask) == 0)) { - // Don't consider registers that can't be assigned. - if ((_registerFile[i]->getState() == TR::RealRegister::Locked) || ((tRegMask & availRegMask) == 0)) - { - continue; - } - //self()->cg()->traceRegWeight(_registerFile[i], _registerFile[i]->getWeight()); - - iNew = interference & (1 << (i - maskI)); - if ((_registerFile[i]->getState() == TR::RealRegister::Free || (_registerFile[i]->getState() == TR::RealRegister::Unlatched)) && - (freeRegister == NULL || (iOld && !iNew) || ((iOld || !iNew) && _registerFile[i]->getWeight() < bestWeightSoFar))) - { - iOld = iNew; - - freeRegister = _registerFile[i]; - bestWeightSoFar = freeRegister->getWeight(); - if (comp->getOption(TR_Randomize)) - { - randomWeight = self()->cg()->randomizer.randomInt(0, 0xFFF); - if (performTransformation(comp, "O^O Random Codegen - Randomizing Weight for %s, Original bestWeightSoFar: %x randomized to: %x\n", self()->cg()->getDebug()->getName(_registerFile[i]), bestWeightSoFar, randomWeight)) - { - bestWeightSoFar = randomWeight; - } - } - - } + continue; } - else + //self()->cg()->traceRegWeight(_registerFile[i], _registerFile[i]->getWeight()); + + iNew = interference & (1 << (i - maskI)); + if ((_registerFile[i]->getState() == TR::RealRegister::Free || (_registerFile[i]->getState() == TR::RealRegister::Unlatched)) && + (freeRegister == NULL || (iOld && !iNew) || ((iOld || !iNew) && _registerFile[i]->getWeight() < bestWeightSoFar))) { - TR::RealRegister * candidate = _registerFile[i]; + iOld = iNew; - if (virtualReg->is64BitReg()) + freeRegister = _registerFile[i]; + bestWeightSoFar = freeRegister->getWeight(); + if (comp->getOption(TR_Randomize)) { - bool candidateLWFree = - (candidate->getState() == TR::RealRegister::Free) || - (candidate->getState() == TR::RealRegister::Unlatched); - - - // Don't consider registers that can't be assigned. - if ((candidate->getState() == TR::RealRegister::Locked) || - ((tRegMask & availRegMask) == 0)) + randomWeight = self()->cg()->randomizer.randomInt(0, 0xFFF); + if (performTransformation(comp, "O^O Random Codegen - Randomizing Weight for %s, Original bestWeightSoFar: %x randomized to: %x\n", self()->cg()->getDebug()->getName(_registerFile[i]), bestWeightSoFar, randomWeight)) { - continue; - } - //self()->cg()->traceRegWeight(candidate, candidate->getWeight()); - - iNew = interference & (1 << (i - maskI)); - if (candidateLWFree && - (freeRegister == NULL || (iOld && !iNew) || ((iOld || !iNew) && candidate->getWeight() < bestWeightSoFar))) - { - iOld = iNew; - - freeRegister = candidate; - bestWeightSoFar = freeRegister->getWeight(); - if (comp->getOption(TR_Randomize)) - { - randomWeight = self()->cg()->randomizer.randomInt(0, 0xFFF); - if (performTransformation(comp, "O^O Random Codegen - Randomizing Weight for %s, Original bestWeightSoFar: %x randomized to: %x\n", self()->cg()->getDebug()->getName(_registerFile[i]), bestWeightSoFar, randomWeight)) - { - bestWeightSoFar = randomWeight; - } - } + bestWeightSoFar = randomWeight; } } - else - { - candidate = _registerFile[i]; - - //self()->cg()->traceRegWeight(candidate, candidate->getWeight()); - // Don't consider registers that can't be assigned. - if ((candidate->getState() == TR::RealRegister::Locked) || ((tRegMask & availRegMask) == 0)) - { - continue; - } - iNew = interference & (1 << (i - maskI)); - if ((candidate->getState() == TR::RealRegister::Free || (candidate->getState() == TR::RealRegister::Unlatched)) && - (freeRegister == NULL || (iOld && !iNew) || ((iOld || !iNew) && candidate->getWeight() < bestWeightSoFar))) - { - iOld = iNew; - - freeRegister = candidate; - bestWeightSoFar = freeRegister->getWeight(); - if (comp->getOption(TR_Randomize)) - { - randomWeight = self()->cg()->randomizer.randomInt(0, 0xFFF); - if (performTransformation(comp, "O^O Random Codegen - Randomizing Weight for %s, Original bestWeightSoFar: %x randomized to: %x\n", self()->cg()->getDebug()->getName(_registerFile[i]), bestWeightSoFar, randomWeight)) - { - bestWeightSoFar = randomWeight; - } - } - } - } } } @@ -2701,104 +2505,38 @@ OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Regi int32_t iInterfere = interference & (1 << (i - maskI)); TR::RealRegister * realReg = machine->getRealRegister((TR::RealRegister::RegNum) i); - if (rk == TR_FPR || rk == TR_VRF) - { - if (realReg->getState() == TR::RealRegister::Assigned) - { - TR::Register * associatedVirtual = realReg->getAssignedRegister(); - bool usedInMemRef = associatedVirtual->isUsedInMemRef(); + // TODO: This assert was added as it existed in a path which was guarded by is64BitReg. I'm fairly certain + // this assert should never fire because otherwise we would be trying to free the best register when a free + // register already exists, meaning that the caller is to blame for not checking if a free register was + // available. An alternative would be to just return the free register right away? In either event we'll + // leave this assert here for a little while and we can remove it once it has had time to bake. + TR_ASSERT_FATAL(realReg->getState() != TR::RealRegister::Free, "Attempting to free best register for virtual register (%s) when a free register (%s) already exists", + getRegisterName(virtReg, self()->cg()), + getRegisterName(realReg, self()->cg())); - if (currentInstruction->getDependencyConditions() && - currentInstruction->getDependencyConditions()->searchPostConditionRegister(associatedVirtual)) - { - // we just assigned this virtual in the reg deps, do not free it - traceMsg(self()->cg(), " Reg[@%d] associatedVirtual[%s] was excluded from spill target because of reg dependency\n", - realReg->getRegisterNumber()-1, self()->cg()->getDebug()->getName(associatedVirtual)); - continue; - } - - if ((!iInterfere && i==preference && pref_favored) || !usedInMemRef) - { - if (numCandidates == 0) - { - candidates[0] = associatedVirtual; - } - else - { - tempReg = candidates[0]; - candidates[0] = associatedVirtual; - candidates[numCandidates] = tempReg; - } - } - else - { - candidates[numCandidates] = associatedVirtual; - } - numCandidates++; - } - } - else + if (realReg->getState() == TR::RealRegister::Assigned) { - if (virtReg->is64BitReg()) - { - TR::Register * associatedVirtual = NULL; - bool usedInMemRef = false; + TR::Register * associatedVirtual = realReg->getAssignedRegister(); + bool usedInMemRef = associatedVirtual->isUsedInMemRef(); - if (realReg->getState() == TR::RealRegister::Assigned) + if ((!iInterfere && i==preference && pref_favored) || !usedInMemRef) + { + if (numCandidates == 0) { - associatedVirtual = realReg->getAssignedRegister(); - usedInMemRef = associatedVirtual->isUsedInMemRef(); + candidates[0] = associatedVirtual; } - - if ((realReg->getState() == TR::RealRegister::Assigned || realReg->getState() == TR::RealRegister::Free)) + else { - if ((!iInterfere && i==preference && pref_favored) || (!usedInMemRef)) - { - if (numCandidates == 0) - { - candidates[0] = associatedVirtual; - } - else - { - tempReg = candidates[0]; - candidates[0] = associatedVirtual; - candidates[numCandidates] = tempReg; - } - } - else - { - candidates[numCandidates] = associatedVirtual; - } - numCandidates++; + tempReg = candidates[0]; + candidates[0] = associatedVirtual; + candidates[numCandidates] = tempReg; } } else { - if (realReg->getState() == TR::RealRegister::Assigned) - { - TR::Register * associatedVirtual = realReg->getAssignedRegister(); - bool usedInMemRef = associatedVirtual->isUsedInMemRef(); - - if ((!iInterfere && i==preference && pref_favored) || !usedInMemRef) - { - if (numCandidates == 0) - { - candidates[0] = associatedVirtual; - } - else - { - tempReg = candidates[0]; - candidates[0] = associatedVirtual; - candidates[numCandidates] = tempReg; - } - } - else - { - candidates[numCandidates] = associatedVirtual; - } - numCandidates++; - } + candidates[numCandidates] = associatedVirtual; } + numCandidates++; } } @@ -2838,17 +2576,6 @@ OMR::Z::Machine::freeBestRegister(TR::Instruction * currentInstruction, TR::Regi return best; } -/** - * Free up a real register - */ -void OMR::Z::Machine::freeRealRegister(TR::Instruction *currentInstruction, TR::RealRegister *targetReal, bool is64BitReg) - { - TR::Compilation *comp = self()->cg()->comp(); - TR::Register *virtReg=targetReal->getAssignedRegister(); - - self()->spillRegister(currentInstruction, virtReg); - } - /** * Spill in a virt register, which frees up the assigned real reg, as we do * assignment in reverse-order of execution. @@ -3382,11 +3109,9 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction currentTargetVirtual->setAssignedRegister(spareReg); spareReg->setAssignedRegister(currentTargetVirtual); - if (currentTargetVirtual->is64BitReg()) - { - targetRegister->setState(TR::RealRegister::Unlatched); - targetRegister->setAssignedRegister(NULL); - } + targetRegister->setState(TR::RealRegister::Unlatched); + targetRegister->setAssignedRegister(NULL); + currentAssignedRegister->setState(TR::RealRegister::Unlatched); currentAssignedRegister->setAssignedRegister(NULL); } @@ -3413,11 +3138,9 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction spareReg->setAssignedRegister(currentTargetVirtual); currentTargetVirtual->setAssignedRegister(spareReg); - if (currentTargetVirtual->is64BitReg()) - { - targetRegister->setState(TR::RealRegister::Unlatched); - targetRegister->setAssignedRegister(NULL); - } + targetRegister->setState(TR::RealRegister::Unlatched); + targetRegister->setAssignedRegister(NULL); + if (virtualRegister->getTotalUseCount() != virtualRegister->getFutureUseCount()) { self()->cg()->setRegisterAssignmentFlag(TR_RegisterReloaded); @@ -3506,11 +3229,10 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction self()->cg()->traceRegAssigned(currentTargetVirtual, spareReg); cursor = self()->registerCopy(self()->cg(), rk, targetRegister, spareReg, currentInstruction); - if (currentTargetVirtual->is64BitReg()) - { - targetRegister->setState(TR::RealRegister::Unlatched); - targetRegister->setAssignedRegister(NULL); - } + + targetRegister->setState(TR::RealRegister::Unlatched); + targetRegister->setAssignedRegister(NULL); + spareReg->setState(TR::RealRegister::Assigned); spareReg->setAssignedRegister(currentTargetVirtual); currentTargetVirtual->setAssignedRegister(spareReg); @@ -3571,12 +3293,6 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction targetRegister->setState(TR::RealRegister::Unlatched); targetRegister->setAssignedRegister(NULL); - - if (currentTargetVirtual->is64BitReg()) - { - targetRegister->setState(TR::RealRegister::Unlatched); - targetRegister->setAssignedRegister(NULL); - } } else { @@ -3622,11 +3338,9 @@ OMR::Z::Machine::coerceRegisterAssignment(TR::Instruction spareReg->setState(TR::RealRegister::Assigned); spareReg->setAssignedRegister(currentTargetVirtual); - if (currentTargetVirtual->is64BitReg()) - { - targetRegister->setState(TR::RealRegister::Unlatched); - targetRegister->setAssignedRegister(NULL); - } + targetRegister->setState(TR::RealRegister::Unlatched); + targetRegister->setAssignedRegister(NULL); + currentTargetVirtual->setAssignedRegister(spareReg); self()->cg()->recordRegisterAssignment(spareReg,currentTargetVirtual); } diff --git a/compiler/z/codegen/OMRMachine.hpp b/compiler/z/codegen/OMRMachine.hpp index 619bd92d916..1f5a6c3679e 100644 --- a/compiler/z/codegen/OMRMachine.hpp +++ b/compiler/z/codegen/OMRMachine.hpp @@ -319,11 +319,6 @@ class OMR_EXTENSIBLE Machine : public OMR::Machine TR::Register * toFreeReg, uint64_t availRegMask); - - void freeRealRegister(TR::Instruction *currentInstruction, - TR::RealRegister *targetReal, - bool is64BitReg); - void spillRegister(TR::Instruction *currentInstruction, TR::Register *virtReg); TR::RealRegister *reverseSpillState(TR::Instruction *currentInstruction, diff --git a/compiler/z/codegen/OMRTreeEvaluator.cpp b/compiler/z/codegen/OMRTreeEvaluator.cpp index dda4366241a..bc08bb539ca 100644 --- a/compiler/z/codegen/OMRTreeEvaluator.cpp +++ b/compiler/z/codegen/OMRTreeEvaluator.cpp @@ -11959,22 +11959,14 @@ OMR::Z::TreeEvaluator::iRegLoadEvaluator(TR::Node * node, TR::CodeGenerator * cg if (globalReg == NULL) { - if (node->getDataType() == TR::Aggregate && - node->getSymbol()->getSize()==8) - { - globalReg = cg->allocateRegister(); - } - else if (cg->getExtendedToInt64GlobalRegisters().ValueAt(node->getGlobalRegisterNumber())) + globalReg = cg->allocateRegister(); + + if (cg->getExtendedToInt64GlobalRegisters().ValueAt(node->getGlobalRegisterNumber())) { // getExtendedToInt64GlobalRegisters is set by TR_LoadExtensions and it means a larger larger virtual register must be used here // so any instructions generated by local RA are the correct size to preserve the upper bits (e.g. use LGR vs LR) - globalReg = cg->allocateRegister(); globalReg->setIs64BitReg(); } - else - { - globalReg = cg->allocateRegister(); - } node->setRegister(globalReg); } From d7f633154d25ed2271131e5b7b29c72c79a2016e Mon Sep 17 00:00:00 2001 From: Filip Jeremic Date: Tue, 12 Mar 2019 10:28:55 -0400 Subject: [PATCH 23/23] Remove GRA linkage register restriction and update copyrights Signed-off-by: Filip Jeremic --- compiler/codegen/OMRMachine.hpp | 2 +- compiler/codegen/RegisterPressureSimulatorInner.hpp | 2 +- compiler/optimizer/RegisterCandidate.cpp | 2 +- compiler/z/CMakeLists.txt | 1 - compiler/z/codegen/OMRCodeGenerator.cpp | 1 - compiler/z/codegen/OMRInstOpCode.hpp | 2 +- compiler/z/codegen/PseudoRegisterEnum.hpp | 2 +- compiler/z/codegen/RealRegisterEnum.hpp | 2 +- compiler/z/codegen/RealRegisterMaskEnum.hpp | 2 +- fvtest/compilertest/build/IWYU_Mappings.imp | 2 +- fvtest/compilertest/build/files/target/z.mk | 2 +- fvtest/compilertest/env/FrontEnd.cpp | 2 +- jitbuilder/build/files/target/z.mk | 1 - 13 files changed, 10 insertions(+), 13 deletions(-) diff --git a/compiler/codegen/OMRMachine.hpp b/compiler/codegen/OMRMachine.hpp index 0fdc63b3611..6803f87c3d2 100644 --- a/compiler/codegen/OMRMachine.hpp +++ b/compiler/codegen/OMRMachine.hpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corp. and others + * Copyright (c) 2000, 2019 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 diff --git a/compiler/codegen/RegisterPressureSimulatorInner.hpp b/compiler/codegen/RegisterPressureSimulatorInner.hpp index 295052e9a8d..8bd70d70eb9 100644 --- a/compiler/codegen/RegisterPressureSimulatorInner.hpp +++ b/compiler/codegen/RegisterPressureSimulatorInner.hpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corp. and others + * Copyright (c) 2000, 2019 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 diff --git a/compiler/optimizer/RegisterCandidate.cpp b/compiler/optimizer/RegisterCandidate.cpp index 70b4808c444..80e2bf1f69f 100644 --- a/compiler/optimizer/RegisterCandidate.cpp +++ b/compiler/optimizer/RegisterCandidate.cpp @@ -3731,7 +3731,7 @@ TR_RegisterCandidates::computeAvailableRegisters(TR_RegisterCandidate *rc, int32 while (bvi.hasMoreElements()) { int32_t reg = bvi.getNextElement(); - if (reg != parmReg && (reg >= comp()->cg()->getFirstGlobalGPR() && reg <= comp()->cg()->getLastGlobalGPR())) + if (reg != parmReg) _liveOnEntryConflicts[reg].set(entryBlockNumber); } } diff --git a/compiler/z/CMakeLists.txt b/compiler/z/CMakeLists.txt index a09444cf973..1b170b5f1bc 100644 --- a/compiler/z/CMakeLists.txt +++ b/compiler/z/CMakeLists.txt @@ -50,7 +50,6 @@ compiler_library(z ${CMAKE_CURRENT_LIST_DIR}/codegen/InstOpCode.cpp ${CMAKE_CURRENT_LIST_DIR}/codegen/OMRRegister.cpp ${CMAKE_CURRENT_LIST_DIR}/codegen/OMRRealRegister.cpp - ${CMAKE_CURRENT_LIST_DIR}/codegen/OMRRegisterPair.cpp ${CMAKE_CURRENT_LIST_DIR}/codegen/OMRCodeGenPhase.cpp ${CMAKE_CURRENT_LIST_DIR}/codegen/OMRCodeGenerator.cpp ${CMAKE_CURRENT_LIST_DIR}/env/OMRDebugEnv.cpp diff --git a/compiler/z/codegen/OMRCodeGenerator.cpp b/compiler/z/codegen/OMRCodeGenerator.cpp index 6c2a0ea6888..eb4ec2c4da6 100644 --- a/compiler/z/codegen/OMRCodeGenerator.cpp +++ b/compiler/z/codegen/OMRCodeGenerator.cpp @@ -3317,7 +3317,6 @@ OMR::Z::CodeGenerator::gprClobberEvaluate(TR::Node * node, bool force_copy, bool return srcRegister; } - /** * Different from evaluate in that it returns a clobberable register */ diff --git a/compiler/z/codegen/OMRInstOpCode.hpp b/compiler/z/codegen/OMRInstOpCode.hpp index 22a79d9d7fd..ff52862b7e0 100644 --- a/compiler/z/codegen/OMRInstOpCode.hpp +++ b/compiler/z/codegen/OMRInstOpCode.hpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corp. and others + * Copyright (c) 2000, 2019 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 diff --git a/compiler/z/codegen/PseudoRegisterEnum.hpp b/compiler/z/codegen/PseudoRegisterEnum.hpp index 708c510986b..7c06700315f 100644 --- a/compiler/z/codegen/PseudoRegisterEnum.hpp +++ b/compiler/z/codegen/PseudoRegisterEnum.hpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018, 2018 IBM Corp. and others + * Copyright (c) 2018, 2019 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 diff --git a/compiler/z/codegen/RealRegisterEnum.hpp b/compiler/z/codegen/RealRegisterEnum.hpp index 8165ef0e634..516040819f3 100644 --- a/compiler/z/codegen/RealRegisterEnum.hpp +++ b/compiler/z/codegen/RealRegisterEnum.hpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corp. and others + * Copyright (c) 2000, 2019 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 diff --git a/compiler/z/codegen/RealRegisterMaskEnum.hpp b/compiler/z/codegen/RealRegisterMaskEnum.hpp index 9b96ff2b363..6bbf8ebf4a4 100644 --- a/compiler/z/codegen/RealRegisterMaskEnum.hpp +++ b/compiler/z/codegen/RealRegisterMaskEnum.hpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corp. and others + * Copyright (c) 2000, 2019 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 diff --git a/fvtest/compilertest/build/IWYU_Mappings.imp b/fvtest/compilertest/build/IWYU_Mappings.imp index 859e7d92a51..6c70d120800 100644 --- a/fvtest/compilertest/build/IWYU_Mappings.imp +++ b/fvtest/compilertest/build/IWYU_Mappings.imp @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2016, 2018 IBM Corp. and others +# Copyright (c) 2016, 2019 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 diff --git a/fvtest/compilertest/build/files/target/z.mk b/fvtest/compilertest/build/files/target/z.mk index 3c1d58ffcf0..eb855793a55 100644 --- a/fvtest/compilertest/build/files/target/z.mk +++ b/fvtest/compilertest/build/files/target/z.mk @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2016, 2018 IBM Corp. and others +# Copyright (c) 2016, 2019 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 diff --git a/fvtest/compilertest/env/FrontEnd.cpp b/fvtest/compilertest/env/FrontEnd.cpp index e4897bef203..0219715d210 100644 --- a/fvtest/compilertest/env/FrontEnd.cpp +++ b/fvtest/compilertest/env/FrontEnd.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corp. and others + * Copyright (c) 2000, 2019 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 diff --git a/jitbuilder/build/files/target/z.mk b/jitbuilder/build/files/target/z.mk index 147db850a20..43202a3e7e1 100644 --- a/jitbuilder/build/files/target/z.mk +++ b/jitbuilder/build/files/target/z.mk @@ -51,7 +51,6 @@ JIT_PRODUCT_BACKEND_SOURCES+=\ $(JIT_OMR_DIRTY_DIR)/z/codegen/InstOpCode.cpp \ $(JIT_OMR_DIRTY_DIR)/z/codegen/OMRRegister.cpp \ $(JIT_OMR_DIRTY_DIR)/z/codegen/OMRRealRegister.cpp \ - $(JIT_OMR_DIRTY_DIR)/z/codegen/OMRRegisterPair.cpp \ $(JIT_OMR_DIRTY_DIR)/z/codegen/OMRCodeGenerator.cpp \ $(JIT_OMR_DIRTY_DIR)/z/codegen/OMRCodeGenPhase.cpp \ $(JIT_OMR_DIRTY_DIR)/z/env/OMRDebugEnv.cpp \