summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing/code_generator_arm64.cc
diff options
context:
space:
mode:
authorSerban Constantinescu <serban.constantinescu@arm.com>2015-02-22 22:08:01 +0000
committerSerban Constantinescu <serban.constantinescu@arm.com>2015-03-11 17:45:09 +0000
commit758c2f65805564e0c51cccaacf8307e52a9e312b (patch)
treeec8bbbe69fa3f263dd91763fe1bef81cf090f468 /compiler/optimizing/code_generator_arm64.cc
parent637455782147a41fbde2e284c49ca5e02d3444c2 (diff)
downloadart-758c2f65805564e0c51cccaacf8307e52a9e312b.tar.gz
art-758c2f65805564e0c51cccaacf8307e52a9e312b.tar.bz2
art-758c2f65805564e0c51cccaacf8307e52a9e312b.zip
Opt Compiler: Materialise constants that cannot be encoded
The VIXL MacroAssembler deals gracefully with any immediate. However when the constant has multiple uses and cannot be encoded in the instruction's immediate field we are better off using a register for the constant and thus sharing the constant generation between multiple uses. Eg: var += #Const; // #Const cannot be encoded. var += #Const; Before: After: mov wip0, #Const mov w4, #Const add w0, w0, wip0 add w0, w0, w4 mov wip0, #Const add w0, w0, w4 add w0, w0, wip0 Change-Id: I8d1f620872d1241cf582fb4f3b45b5091b790146 Signed-off-by: Serban Constantinescu <serban.constantinescu@arm.com>
Diffstat (limited to 'compiler/optimizing/code_generator_arm64.cc')
-rw-r--r--compiler/optimizing/code_generator_arm64.cc9
1 files changed, 5 insertions, 4 deletions
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index c21084a6fe..6b4c2f0656 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -63,6 +63,7 @@ using helpers::StackOperandFrom;
using helpers::VIXLRegCodeFromART;
using helpers::WRegisterFrom;
using helpers::XRegisterFrom;
+using helpers::ARM64EncodableConstantOrRegister;
static constexpr size_t kHeapRefSize = sizeof(mirror::HeapReference<mirror::Object>);
static constexpr int kCurrentMethodStackOffset = 0;
@@ -1104,7 +1105,7 @@ void LocationsBuilderARM64::HandleBinaryOp(HBinaryOperation* instr) {
case Primitive::kPrimInt:
case Primitive::kPrimLong:
locations->SetInAt(0, Location::RequiresRegister());
- locations->SetInAt(1, Location::RegisterOrConstant(instr->InputAt(1)));
+ locations->SetInAt(1, ARM64EncodableConstantOrRegister(instr->InputAt(1), instr));
locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
break;
@@ -1395,7 +1396,7 @@ void LocationsBuilderARM64::VisitCompare(HCompare* compare) {
switch (in_type) {
case Primitive::kPrimLong: {
locations->SetInAt(0, Location::RequiresRegister());
- locations->SetInAt(1, Location::RegisterOrConstant(compare->InputAt(1)));
+ locations->SetInAt(1, ARM64EncodableConstantOrRegister(compare->InputAt(1), compare));
locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
break;
}
@@ -1465,7 +1466,7 @@ void InstructionCodeGeneratorARM64::VisitCompare(HCompare* compare) {
void LocationsBuilderARM64::VisitCondition(HCondition* instruction) {
LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction);
locations->SetInAt(0, Location::RequiresRegister());
- locations->SetInAt(1, Location::RegisterOrConstant(instruction->InputAt(1)));
+ locations->SetInAt(1, ARM64EncodableConstantOrRegister(instruction->InputAt(1), instruction));
if (instruction->NeedsMaterialization()) {
locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
}
@@ -2116,7 +2117,7 @@ void LocationsBuilderARM64::VisitNeg(HNeg* neg) {
switch (neg->GetResultType()) {
case Primitive::kPrimInt:
case Primitive::kPrimLong:
- locations->SetInAt(0, Location::RegisterOrConstant(neg->InputAt(0)));
+ locations->SetInAt(0, ARM64EncodableConstantOrRegister(neg->InputAt(0), neg));
locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
break;