From 9a6d5feb58f806f382c385c7895b7d854a44e3bc Mon Sep 17 00:00:00 2001 From: Gita Koblents Date: Fri, 17 May 2024 22:04:06 -0400 Subject: [PATCH] Move out-of-line instructions to warm cache - during code cache disclaim, it's beneficial to move OOL code into warm code cache --- compiler/x/codegen/OMRCodeGenerator.cpp | 62 +++++++++++++++++++++++++ compiler/x/codegen/OMRCodeGenerator.hpp | 6 +++ 2 files changed, 68 insertions(+) diff --git a/compiler/x/codegen/OMRCodeGenerator.cpp b/compiler/x/codegen/OMRCodeGenerator.cpp index 76edcbe0a7d..76d7479a2d3 100644 --- a/compiler/x/codegen/OMRCodeGenerator.cpp +++ b/compiler/x/codegen/OMRCodeGenerator.cpp @@ -1867,6 +1867,9 @@ void OMR::X86::CodeGenerator::doRegisterAssignment(TR_RegisterKinds kindsToAssig self()->doBackwardsRegisterAssignment(kindsToAssign, self()->getAppendInstruction()); } + + if (TR::Options::getCmdLineOptions()->getOption(TR_EnableCodeCacheDisclaiming)) + moveOutOfLineInstructionsToWarm(); } bool OMR::X86::CodeGenerator::isReturnInstruction(TR::Instruction *instr) @@ -3500,3 +3503,62 @@ OMR::X86::CodeGenerator::getOutOfLineCodeSize() return totalSize; } + +void +OMR::X86::CodeGenerator::moveOutOfLineInstructionsToWarm() + { + // OOL instructions are already attached at the end of the IL (after cold instructions) + // and register allocated. + // Move them to immediately after the last warm instruction, unless they already happend to be + // there (e.g. there are no cold instructions) + // + if (self()->comp()->getOption(TR_TraceCG)) + traceMsg(self()->comp(), "Moving OutOfLine instructions\n"); + + auto oiIterator = self()->getOutlinedInstructionsList().begin(); + + while (oiIterator != self()->getOutlinedInstructionsList().end()) + { + TR::Instruction *firstInstruction = (*oiIterator)->getFirstInstruction(); + TR::Instruction *lastInstruction = (*oiIterator)->getAppendInstruction(); + + TR_ASSERT_FATAL(firstInstruction, "VFPRestore instruciton should preceeed any OOL section\n"); + TR_ASSERT_FATAL(self()->getLastWarmInstruction() != self()->getAppendInstruction(), + "Last warm instruction can't be append instruction since OOL code was attached already\n"); + + if (self()->getLastWarmInstruction() && + self()->getLastWarmInstruction() != firstInstruction->getPrev()) + { + TR::Instruction *appendInstruction; + + // remove from prrevious location + if (firstInstruction->getPrev()) + firstInstruction->getPrev()->setNext(lastInstruction->getNext()); + + if (lastInstruction->getNext()) + lastInstruction->getNext()->setPrev(firstInstruction->getPrev()); + + // update codegen append instruction + if (lastInstruction == self()->getAppendInstruction()) + self()->setAppendInstruction(firstInstruction->getPrev()); + + // insert after last warm instruction + appendInstruction = self()->getLastWarmInstruction(); + appendInstruction->setLastWarmInstruction(false); + lastInstruction->setLastWarmInstruction(true); + self()->setLastWarmInstruction(lastInstruction); + + TR::Instruction *followInstruction = appendInstruction->getNext(); + + appendInstruction->setNext(firstInstruction); + firstInstruction->setPrev(appendInstruction); + + lastInstruction->setNext(followInstruction); + + if (followInstruction) + followInstruction->setPrev(lastInstruction); + } + + ++oiIterator; + } + } diff --git a/compiler/x/codegen/OMRCodeGenerator.hpp b/compiler/x/codegen/OMRCodeGenerator.hpp index 29bbe6b002c..b815c0fc906 100644 --- a/compiler/x/codegen/OMRCodeGenerator.hpp +++ b/compiler/x/codegen/OMRCodeGenerator.hpp @@ -654,6 +654,12 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator bool considerTypeForGRA(TR::DataType dt); bool considerTypeForGRA(TR::SymbolReference *symRef); + /* + * \brief move out-of-line instructions from cold code to warm + * + */ + void moveOutOfLineInstructionsToWarm(); + uint32_t getOutOfLineCodeSize(); /*