diff options
author | Calin Juravle <calin@google.com> | 2014-11-26 19:01:09 +0000 |
---|---|---|
committer | Calin Juravle <calin@google.com> | 2014-11-26 19:01:09 +0000 |
commit | 91debbc3da3e3376416e4394155d9f9e355255cb (patch) | |
tree | fd2181a2d4b8e7e8d26101a9a87b4f0c34fa990f /compiler/optimizing | |
parent | fd861249f31ab360c12dd1ffb131d50f02b0bfc6 (diff) | |
download | art-91debbc3da3e3376416e4394155d9f9e355255cb.tar.gz art-91debbc3da3e3376416e4394155d9f9e355255cb.tar.bz2 art-91debbc3da3e3376416e4394155d9f9e355255cb.zip |
Revert "[optimizing compiler] Add CMP{L,G}_{FLOAT,DOUBLE}"
Fails on arm due to missing vmrs op after vcmp. I revert this instead of pushing the fix because I don't understand yet why it compiles with run-test but not with dex2oat.
This reverts commit fd861249f31ab360c12dd1ffb131d50f02b0bfc6.
Change-Id: Idc2d30f6a0f39ddd3596aa18a532ae90f8aaf62f
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/builder.cc | 31 | ||||
-rw-r--r-- | compiler/optimizing/builder.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 71 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 68 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 60 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 27 |
6 files changed, 65 insertions, 194 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index 1be6e0093..b26146069 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -313,15 +313,6 @@ void HGraphBuilder::Binop_23x_shift(const Instruction& instruction, UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); } -void HGraphBuilder::Binop_23x_cmp(const Instruction& instruction, - Primitive::Type type, - HCompare::Bias bias) { - HInstruction* first = LoadLocal(instruction.VRegB(), type); - HInstruction* second = LoadLocal(instruction.VRegC(), type); - current_block_->AddInstruction(new (arena_) HCompare(type, first, second, bias)); - UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); -} - template<typename T> void HGraphBuilder::Binop_12x(const Instruction& instruction, Primitive::Type type) { HInstruction* first = LoadLocal(instruction.VRegA(), type); @@ -1501,27 +1492,7 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 break; case Instruction::CMP_LONG: { - Binop_23x_cmp(instruction, Primitive::kPrimLong, HCompare::kNoBias); - break; - } - - case Instruction::CMPG_FLOAT: { - Binop_23x_cmp(instruction, Primitive::kPrimFloat, HCompare::kGtBias); - break; - } - - case Instruction::CMPG_DOUBLE: { - Binop_23x_cmp(instruction, Primitive::kPrimDouble, HCompare::kGtBias); - break; - } - - case Instruction::CMPL_FLOAT: { - Binop_23x_cmp(instruction, Primitive::kPrimFloat, HCompare::kLtBias); - break; - } - - case Instruction::CMPL_DOUBLE: { - Binop_23x_cmp(instruction, Primitive::kPrimDouble, HCompare::kLtBias); + Binop_23x<HCompare>(instruction, Primitive::kPrimLong); break; } diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h index 25781b08f..204005daa 100644 --- a/compiler/optimizing/builder.h +++ b/compiler/optimizing/builder.h @@ -107,8 +107,6 @@ class HGraphBuilder : public ValueObject { template<typename T> void Binop_23x_shift(const Instruction& instruction, Primitive::Type type); - void Binop_23x_cmp(const Instruction& instruction, Primitive::Type type, HCompare::Bias bias); - template<typename T> void Binop_12x(const Instruction& instruction, Primitive::Type type); diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index df65ff054..890cfdd0e 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -2292,71 +2292,44 @@ void InstructionCodeGeneratorARM::VisitNot(HNot* not_) { void LocationsBuilderARM::VisitCompare(HCompare* compare) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(compare, LocationSummary::kNoCall); - switch (compare->InputAt(0)->GetType()) { - case Primitive::kPrimLong: { - locations->SetInAt(0, Location::RequiresRegister()); - locations->SetInAt(1, Location::RequiresRegister()); - locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); - break; - } - case Primitive::kPrimFloat: - case Primitive::kPrimDouble: { - locations->SetInAt(0, Location::RequiresFpuRegister()); - locations->SetInAt(1, Location::RequiresFpuRegister()); - locations->SetOut(Location::RequiresRegister()); - break; - } - default: - LOG(FATAL) << "Unexpected type for compare operation " << compare->InputAt(0)->GetType(); - } + locations->SetInAt(0, Location::RequiresRegister()); + locations->SetInAt(1, Location::RequiresRegister()); + locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); } void InstructionCodeGeneratorARM::VisitCompare(HCompare* compare) { LocationSummary* locations = compare->GetLocations(); - Register out = locations->Out().As<Register>(); - Location left = locations->InAt(0); - Location right = locations->InAt(1); - - Label less, greater, done; switch (compare->InputAt(0)->GetType()) { case Primitive::kPrimLong: { + Register output = locations->Out().As<Register>(); + Location left = locations->InAt(0); + Location right = locations->InAt(1); + Label less, greater, done; __ cmp(left.AsRegisterPairHigh<Register>(), ShifterOperand(right.AsRegisterPairHigh<Register>())); // Signed compare. __ b(&less, LT); __ b(&greater, GT); - // Do LoadImmediate before any `cmp`, as LoadImmediate might affect the status flags. - __ LoadImmediate(out, 0); + // Do LoadImmediate before any `cmp`, as LoadImmediate might affect + // the status flags. + __ LoadImmediate(output, 0); __ cmp(left.AsRegisterPairLow<Register>(), ShifterOperand(right.AsRegisterPairLow<Register>())); // Unsigned compare. - break; - } - case Primitive::kPrimFloat: { - __ LoadImmediate(out, 0); - __ vcmps(left.As<SRegister>(), right.As<SRegister>()); - __ b(compare->IsGtBias() ? &greater : &less, VS); // VS for unordered - break; - } - case Primitive::kPrimDouble: { - __ LoadImmediate(out, 0); - __ vcmpd(FromLowSToD(left.AsFpuRegisterPairLow<SRegister>()), - FromLowSToD(right.AsFpuRegisterPairLow<SRegister>())); - __ b(compare->IsGtBias() ? &greater : &less, VS); + __ b(&done, EQ); + __ b(&less, CC); + + __ Bind(&greater); + __ LoadImmediate(output, 1); + __ b(&done); + + __ Bind(&less); + __ LoadImmediate(output, -1); + + __ Bind(&done); break; } default: - LOG(FATAL) << "Unexpected compare type " << compare->InputAt(0)->GetType(); + LOG(FATAL) << "Unimplemented compare type " << compare->InputAt(0)->GetType(); } - __ b(&done, EQ); - __ b(&less, CC); // CC is for both: unsigned compare for longs and 'less than' for floats. - - __ Bind(&greater); - __ LoadImmediate(out, 1); - __ b(&done); - - __ Bind(&less); - __ LoadImmediate(out, -1); - - __ Bind(&done); } void LocationsBuilderARM::VisitPhi(HPhi* instruction) { diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 537e5e10d..368945223 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -2355,36 +2355,20 @@ void InstructionCodeGeneratorX86::VisitNot(HNot* not_) { void LocationsBuilderX86::VisitCompare(HCompare* compare) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(compare, LocationSummary::kNoCall); - switch (compare->InputAt(0)->GetType()) { - case Primitive::kPrimLong: { - locations->SetInAt(0, Location::RequiresRegister()); - // TODO: we set any here but we don't handle constants - locations->SetInAt(1, Location::Any()); - locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); - break; - } - case Primitive::kPrimFloat: - case Primitive::kPrimDouble: { - locations->SetInAt(0, Location::RequiresFpuRegister()); - locations->SetInAt(1, Location::RequiresFpuRegister()); - locations->SetOut(Location::RequiresRegister()); - break; - } - default: - LOG(FATAL) << "Unexpected type for compare operation " << compare->InputAt(0)->GetType(); - } + locations->SetInAt(0, Location::RequiresRegister()); + locations->SetInAt(1, Location::Any()); + locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); } void InstructionCodeGeneratorX86::VisitCompare(HCompare* compare) { LocationSummary* locations = compare->GetLocations(); - Register out = locations->Out().As<Register>(); - Location left = locations->InAt(0); - Location right = locations->InAt(1); - - Label less, greater, done; switch (compare->InputAt(0)->GetType()) { case Primitive::kPrimLong: { - if (right.IsRegisterPair()) { + Label less, greater, done; + Register output = locations->Out().As<Register>(); + Location left = locations->InAt(0); + Location right = locations->InAt(1); + if (right.IsRegister()) { __ cmpl(left.AsRegisterPairHigh<Register>(), right.AsRegisterPairHigh<Register>()); } else { DCHECK(right.IsDoubleStackSlot()); @@ -2399,33 +2383,23 @@ void InstructionCodeGeneratorX86::VisitCompare(HCompare* compare) { DCHECK(right.IsDoubleStackSlot()); __ cmpl(left.AsRegisterPairLow<Register>(), Address(ESP, right.GetStackIndex())); } - break; - } - case Primitive::kPrimFloat: { - __ ucomiss(left.As<XmmRegister>(), right.As<XmmRegister>()); - __ j(kUnordered, compare->IsGtBias() ? &greater : &less); - break; - } - case Primitive::kPrimDouble: { - __ ucomisd(left.As<XmmRegister>(), right.As<XmmRegister>()); - __ j(kUnordered, compare->IsGtBias() ? &greater : &less); + __ movl(output, Immediate(0)); + __ j(kEqual, &done); + __ j(kBelow, &less); // Unsigned compare. + + __ Bind(&greater); + __ movl(output, Immediate(1)); + __ jmp(&done); + + __ Bind(&less); + __ movl(output, Immediate(-1)); + + __ Bind(&done); break; } default: - LOG(FATAL) << "Unexpected type for compare operation " << compare->InputAt(0)->GetType(); + LOG(FATAL) << "Unimplemented compare type " << compare->InputAt(0)->GetType(); } - __ movl(out, Immediate(0)); - __ j(kEqual, &done); - __ j(kBelow, &less); // kBelow is for CF (unsigned & floats). - - __ Bind(&greater); - __ movl(out, Immediate(1)); - __ jmp(&done); - - __ Bind(&less); - __ movl(out, Immediate(-1)); - - __ Bind(&done); } void LocationsBuilderX86::VisitPhi(HPhi* instruction) { diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index a39b238d5..34fa1e7a3 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -899,61 +899,33 @@ void InstructionCodeGeneratorX86_64::VisitGreaterThanOrEqual(HGreaterThanOrEqual void LocationsBuilderX86_64::VisitCompare(HCompare* compare) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(compare, LocationSummary::kNoCall); - switch (compare->InputAt(0)->GetType()) { - case Primitive::kPrimLong: { - locations->SetInAt(0, Location::RequiresRegister()); - locations->SetInAt(1, Location::RequiresRegister()); - locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); - break; - } - case Primitive::kPrimFloat: - case Primitive::kPrimDouble: { - locations->SetInAt(0, Location::RequiresFpuRegister()); - locations->SetInAt(1, Location::RequiresFpuRegister()); - locations->SetOut(Location::RequiresRegister()); - break; - } - default: - LOG(FATAL) << "Unexpected type for compare operation " << compare->InputAt(0)->GetType(); - } + locations->SetInAt(0, Location::RequiresRegister()); + locations->SetInAt(1, Location::RequiresRegister()); + locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); } void InstructionCodeGeneratorX86_64::VisitCompare(HCompare* compare) { + Label greater, done; LocationSummary* locations = compare->GetLocations(); - CpuRegister out = locations->Out().As<CpuRegister>(); - Location left = locations->InAt(0); - Location right = locations->InAt(1); - - Label less, greater, done; - Primitive::Type type = compare->InputAt(0)->GetType(); - switch (type) { - case Primitive::kPrimLong: { - __ cmpq(left.As<CpuRegister>(), right.As<CpuRegister>()); - break; - } - case Primitive::kPrimFloat: { - __ ucomiss(left.As<XmmRegister>(), right.As<XmmRegister>()); - __ j(kUnordered, compare->IsGtBias() ? &greater : &less); - break; - } - case Primitive::kPrimDouble: { - __ ucomisd(left.As<XmmRegister>(), right.As<XmmRegister>()); - __ j(kUnordered, compare->IsGtBias() ? &greater : &less); + switch (compare->InputAt(0)->GetType()) { + case Primitive::kPrimLong: + __ cmpq(locations->InAt(0).As<CpuRegister>(), + locations->InAt(1).As<CpuRegister>()); break; - } default: - LOG(FATAL) << "Unexpected compare type " << type; + LOG(FATAL) << "Unimplemented compare type " << compare->InputAt(0)->GetType(); } - __ movl(out, Immediate(0)); + + CpuRegister output = locations->Out().As<CpuRegister>(); + __ movl(output, Immediate(0)); __ j(kEqual, &done); - __ j(type == Primitive::kPrimLong ? kLess : kBelow, &less); // ucomis{s,d} sets CF (kBelow) + __ j(kGreater, &greater); - __ Bind(&greater); - __ movl(out, Immediate(1)); + __ movl(output, Immediate(-1)); __ jmp(&done); - __ Bind(&less); - __ movl(out, Immediate(-1)); + __ Bind(&greater); + __ movl(output, Immediate(1)); __ Bind(&done); } diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 28496e4ad..f562113e6 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -777,7 +777,7 @@ class HInstruction : public ArenaObject<kArenaAllocMisc> { } // Returns whether two instructions are equal, that is: - // 1) They have the same type and contain the same data (InstructionDataEquals). + // 1) They have the same type and contain the same data, // 2) Their inputs are identical. bool Equals(HInstruction* other) const; @@ -1363,45 +1363,28 @@ class HGreaterThanOrEqual : public HCondition { // Result is 0 if input0 == input1, 1 if input0 > input1, or -1 if input0 < input1. class HCompare : public HBinaryOperation { public: - // The bias applies for floating point operations and indicates how NaN - // comparisons are treated: - enum Bias { - kNoBias, // bias is not applicable (i.e. for long operation) - kGtBias, // return 1 for NaN comparisons - kLtBias, // return -1 for NaN comparisons - }; - - HCompare(Primitive::Type type, HInstruction* first, HInstruction* second, Bias bias) - : HBinaryOperation(Primitive::kPrimInt, first, second), bias_(bias) { + HCompare(Primitive::Type type, HInstruction* first, HInstruction* second) + : HBinaryOperation(Primitive::kPrimInt, first, second) { DCHECK_EQ(type, first->GetType()); DCHECK_EQ(type, second->GetType()); } - int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE { + virtual int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE { return x == y ? 0 : x > y ? 1 : -1; } - - int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE { + virtual int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE { return x == y ? 0 : x > y ? 1 : -1; } - bool InstructionDataEquals(HInstruction* other) const OVERRIDE { - return bias_ == other->AsCompare()->bias_; - } - - bool IsGtBias() { return bias_ == kGtBias; } - DECLARE_INSTRUCTION(Compare); private: - const Bias bias_; - DISALLOW_COPY_AND_ASSIGN(HCompare); }; |