From 88017f6ea6934e5d229271b21dfd8399e5505a03 Mon Sep 17 00:00:00 2001 From: Akira Saitoh Date: Tue, 30 Aug 2022 15:48:21 +0900 Subject: [PATCH] AArch64: Inline Math.min and max Implement the inlined version of java/lang/Math.min and max. Signed-off-by: Akira Saitoh --- .../aarch64/codegen/J9CodeGenerator.cpp | 7 ++- .../aarch64/codegen/J9TreeEvaluator.cpp | 49 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/runtime/compiler/aarch64/codegen/J9CodeGenerator.cpp b/runtime/compiler/aarch64/codegen/J9CodeGenerator.cpp index 6fb9ddcd52d..e897becbf68 100644 --- a/runtime/compiler/aarch64/codegen/J9CodeGenerator.cpp +++ b/runtime/compiler/aarch64/codegen/J9CodeGenerator.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2021 IBM Corp. and others + * Copyright (c) 2019, 2022 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 @@ -215,5 +215,10 @@ J9::ARM64::CodeGenerator::supportsInliningOfIsInstance() bool J9::ARM64::CodeGenerator::suppressInliningOfRecognizedMethod(TR::RecognizedMethod method) { + if (method == TR::java_lang_Math_min_F || + method == TR::java_lang_Math_max_F) + { + return true; + } return false; } diff --git a/runtime/compiler/aarch64/codegen/J9TreeEvaluator.cpp b/runtime/compiler/aarch64/codegen/J9TreeEvaluator.cpp index 2aee375f1e3..0a090448b70 100644 --- a/runtime/compiler/aarch64/codegen/J9TreeEvaluator.cpp +++ b/runtime/compiler/aarch64/codegen/J9TreeEvaluator.cpp @@ -5094,6 +5094,34 @@ static TR::Register *VMinlineCompareAndSwapObject(TR::Node *node, TR::CodeGenera return resultReg; } +/** + * @brief Generates instruction sequence for java/lang/Math.min and max + * + * @param[in] node: node + * @param[in] isMax: true if operation is max + * @param[in] isDouble: true if type is double + * @param[in] cg: CodeGenerator + * @return the result register + */ +static TR::Register * +VMinlineMathMinMax(TR::Node *node, bool isMax, bool isDouble, TR::CodeGenerator *cg) + { + TR::Node *firstChild = node->getFirstChild(); + TR::Node *secondChild = node->getSecondChild(); + TR::Register *lhsReg = cg->evaluate(firstChild); + TR::Register *rhsReg = cg->evaluate(secondChild); + TR::Register *resReg = cg->allocateRegister(TR_FPR); + TR::InstOpCode::Mnemonic op = isMax ? (isDouble ? TR::InstOpCode::fmaxd : TR::InstOpCode::fmaxs) : + (isDouble ? TR::InstOpCode::fmind : TR::InstOpCode::fmins); + generateTrg1Src2Instruction(cg, op, node, resReg, lhsReg, rhsReg); + + node->setRegister(resReg); + cg->decReferenceCount(firstChild); + cg->decReferenceCount(secondChild); + + return resReg; + } + bool J9::ARM64::CodeGenerator::inlineDirectCall(TR::Node *node, TR::Register *&resultReg) { @@ -5135,6 +5163,27 @@ J9::ARM64::CodeGenerator::inlineDirectCall(TR::Node *node, TR::Register *&result return true; } + case TR::java_lang_Math_max_D: + { + resultReg = VMinlineMathMinMax(node, true, true, cg); + return true; + } + case TR::java_lang_Math_max_F: + { + resultReg = VMinlineMathMinMax(node, true, false, cg); + return true; + } + case TR::java_lang_Math_min_D: + { + resultReg = VMinlineMathMinMax(node, false, true, cg); + return true; + } + case TR::java_lang_Math_min_F: + { + resultReg = VMinlineMathMinMax(node, false, false, cg); + return true; + } + case TR::sun_misc_Unsafe_compareAndSwapInt_jlObjectJII_Z: { // In Java9 and newer this can be either the jdk.internal JNI method or the sun.misc Java wrapper.