From a33823a11d455198cba75da7060383937783fc54 Mon Sep 17 00:00:00 2001 From: Akira Saitoh Date: Thu, 8 Jul 2021 14:39:13 +0900 Subject: [PATCH] AArch64: Reuse src registers in `generateMaddOrSub` if possible This commit changes `generateMaddOrMsub` to reuse one of source registers if the source node's reference count is 1. Signed-off-by: Akira Saitoh --- compiler/aarch64/codegen/BinaryEvaluator.cpp | 48 ++++++++++++++++++-- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/compiler/aarch64/codegen/BinaryEvaluator.cpp b/compiler/aarch64/codegen/BinaryEvaluator.cpp index e887995c345..be06585033a 100644 --- a/compiler/aarch64/codegen/BinaryEvaluator.cpp +++ b/compiler/aarch64/codegen/BinaryEvaluator.cpp @@ -159,16 +159,54 @@ generateMaddOrMsub(TR::Node *node, TR::Node *mulNode, TR::Node *anotherNode, TR: mulNode->getReferenceCount() == 1 && mulNode->getRegister() == NULL) { - TR::Register *trgReg = cg->allocateRegister(); - TR::Register *mulSrc1Reg = cg->evaluate(mulNode->getFirstChild()); - TR::Register *mulSrc2Reg = cg->evaluate(mulNode->getSecondChild()); + TR::Register *trgReg; + TR::Node *mulFirstChild = mulNode->getFirstChild(); + TR::Node *mulSecondChild = mulNode->getSecondChild(); + TR::Register *mulSrc1Reg = cg->evaluate(mulFirstChild); + TR::Register *mulSrc2Reg = cg->evaluate(mulSecondChild); TR::Register *src3Reg = cg->evaluate(anotherNode); + if (node->getOpCodeValue() != TR::aladd) + { + if (mulFirstChild->getReferenceCount() == 1) + { + trgReg = mulSrc1Reg; + } + else if (mulSecondChild->getReferenceCount() == 1) + { + trgReg = mulSrc2Reg; + } + else if (anotherNode->getReferenceCount() == 1) + { + trgReg = src3Reg; + } + else + { + trgReg = cg->allocateRegister(); + } + } + else + { + /* + * Because trgReg can contain an internal pointer, we cannot use the same virtual register + * for trgReg and sources for aladd except for the case + * where src1Reg also contains an internal pointer and has the same pinning array as the node. + */ + if ((1 == mulFirstChild->getReferenceCount()) && node->isInternalPointer() && mulSrc1Reg->containsInternalPointer() && + (node->getPinningArrayPointer() == mulSrc1Reg->getPinningArrayPointer())) + { + trgReg = mulSrc1Reg; + } + else + { + trgReg = cg->allocateRegister(); + } + } generateTrg1Src3Instruction(cg, op, node, trgReg, mulSrc1Reg, mulSrc2Reg, src3Reg); node->setRegister(trgReg); - cg->decReferenceCount(mulNode->getFirstChild()); - cg->decReferenceCount(mulNode->getSecondChild()); + cg->decReferenceCount(mulFirstChild); + cg->decReferenceCount(mulSecondChild); cg->decReferenceCount(mulNode); cg->decReferenceCount(anotherNode); return trgReg;