From d003e7530ed0b00df5504cf57f0dd6479629c67a Mon Sep 17 00:00:00 2001 From: Santiago Aboy Solanes Date: Fri, 10 Mar 2023 15:58:17 +0000 Subject: Add optimization to simplify Select+Binary/Unary ops We can simplify a Select + Binary/Unary Op if: * Both inputs to the Select instruction are constant, and * The Select instruction is not used in another instruction to avoid duplicating Selects. * In the case of Binary ops, both inputs can't be Select. Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b Change-Id: Ic716155e9a8515126c2867bb1d54593fa63011ae --- compiler/optimizing/nodes.cc | 72 ++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 32 deletions(-) (limited to 'compiler/optimizing/nodes.cc') diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 2b7e384f34..5795ea7ca9 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -1816,10 +1816,12 @@ void HGraphVisitor::VisitBasicBlock(HBasicBlock* block) { } } -HConstant* HTypeConversion::TryStaticEvaluation() const { - HGraph* graph = GetBlock()->GetGraph(); - if (GetInput()->IsIntConstant()) { - int32_t value = GetInput()->AsIntConstant()->GetValue(); +HConstant* HTypeConversion::TryStaticEvaluation() const { return TryStaticEvaluation(GetInput()); } + +HConstant* HTypeConversion::TryStaticEvaluation(HInstruction* input) const { + HGraph* graph = input->GetBlock()->GetGraph(); + if (input->IsIntConstant()) { + int32_t value = input->AsIntConstant()->GetValue(); switch (GetResultType()) { case DataType::Type::kInt8: return graph->GetIntConstant(static_cast(value), GetDexPc()); @@ -1838,8 +1840,8 @@ HConstant* HTypeConversion::TryStaticEvaluation() const { default: return nullptr; } - } else if (GetInput()->IsLongConstant()) { - int64_t value = GetInput()->AsLongConstant()->GetValue(); + } else if (input->IsLongConstant()) { + int64_t value = input->AsLongConstant()->GetValue(); switch (GetResultType()) { case DataType::Type::kInt8: return graph->GetIntConstant(static_cast(value), GetDexPc()); @@ -1858,8 +1860,8 @@ HConstant* HTypeConversion::TryStaticEvaluation() const { default: return nullptr; } - } else if (GetInput()->IsFloatConstant()) { - float value = GetInput()->AsFloatConstant()->GetValue(); + } else if (input->IsFloatConstant()) { + float value = input->AsFloatConstant()->GetValue(); switch (GetResultType()) { case DataType::Type::kInt32: if (std::isnan(value)) @@ -1882,8 +1884,8 @@ HConstant* HTypeConversion::TryStaticEvaluation() const { default: return nullptr; } - } else if (GetInput()->IsDoubleConstant()) { - double value = GetInput()->AsDoubleConstant()->GetValue(); + } else if (input->IsDoubleConstant()) { + double value = input->AsDoubleConstant()->GetValue(); switch (GetResultType()) { case DataType::Type::kInt32: if (std::isnan(value)) @@ -1910,41 +1912,47 @@ HConstant* HTypeConversion::TryStaticEvaluation() const { return nullptr; } -HConstant* HUnaryOperation::TryStaticEvaluation() const { - if (GetInput()->IsIntConstant()) { - return Evaluate(GetInput()->AsIntConstant()); - } else if (GetInput()->IsLongConstant()) { - return Evaluate(GetInput()->AsLongConstant()); +HConstant* HUnaryOperation::TryStaticEvaluation() const { return TryStaticEvaluation(GetInput()); } + +HConstant* HUnaryOperation::TryStaticEvaluation(HInstruction* input) const { + if (input->IsIntConstant()) { + return Evaluate(input->AsIntConstant()); + } else if (input->IsLongConstant()) { + return Evaluate(input->AsLongConstant()); } else if (kEnableFloatingPointStaticEvaluation) { - if (GetInput()->IsFloatConstant()) { - return Evaluate(GetInput()->AsFloatConstant()); - } else if (GetInput()->IsDoubleConstant()) { - return Evaluate(GetInput()->AsDoubleConstant()); + if (input->IsFloatConstant()) { + return Evaluate(input->AsFloatConstant()); + } else if (input->IsDoubleConstant()) { + return Evaluate(input->AsDoubleConstant()); } } return nullptr; } HConstant* HBinaryOperation::TryStaticEvaluation() const { - if (GetLeft()->IsIntConstant() && GetRight()->IsIntConstant()) { - return Evaluate(GetLeft()->AsIntConstant(), GetRight()->AsIntConstant()); - } else if (GetLeft()->IsLongConstant()) { - if (GetRight()->IsIntConstant()) { + return TryStaticEvaluation(GetLeft(), GetRight()); +} + +HConstant* HBinaryOperation::TryStaticEvaluation(HInstruction* left, HInstruction* right) const { + if (left->IsIntConstant() && right->IsIntConstant()) { + return Evaluate(left->AsIntConstant(), right->AsIntConstant()); + } else if (left->IsLongConstant()) { + if (right->IsIntConstant()) { // The binop(long, int) case is only valid for shifts and rotations. DCHECK(IsShl() || IsShr() || IsUShr() || IsRor()) << DebugName(); - return Evaluate(GetLeft()->AsLongConstant(), GetRight()->AsIntConstant()); - } else if (GetRight()->IsLongConstant()) { - return Evaluate(GetLeft()->AsLongConstant(), GetRight()->AsLongConstant()); + return Evaluate(left->AsLongConstant(), right->AsIntConstant()); + } else if (right->IsLongConstant()) { + return Evaluate(left->AsLongConstant(), right->AsLongConstant()); } - } else if (GetLeft()->IsNullConstant() && GetRight()->IsNullConstant()) { + } else if (left->IsNullConstant() && right->IsNullConstant()) { // The binop(null, null) case is only valid for equal and not-equal conditions. DCHECK(IsEqual() || IsNotEqual()) << DebugName(); - return Evaluate(GetLeft()->AsNullConstant(), GetRight()->AsNullConstant()); + return Evaluate(left->AsNullConstant(), right->AsNullConstant()); } else if (kEnableFloatingPointStaticEvaluation) { - if (GetLeft()->IsFloatConstant() && GetRight()->IsFloatConstant()) { - return Evaluate(GetLeft()->AsFloatConstant(), GetRight()->AsFloatConstant()); - } else if (GetLeft()->IsDoubleConstant() && GetRight()->IsDoubleConstant()) { - return Evaluate(GetLeft()->AsDoubleConstant(), GetRight()->AsDoubleConstant()); + if (left->IsFloatConstant() && right->IsFloatConstant()) { + return Evaluate(left->AsFloatConstant(), right->AsFloatConstant()); + } else if (left->IsDoubleConstant() && right->IsDoubleConstant()) { + return Evaluate(left->AsDoubleConstant(), right->AsDoubleConstant()); } } return nullptr; -- cgit v1.2.3-59-g8ed1b