diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/code_generator_arm64.cc | 24 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm_vixl.cc | 87 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm_vixl.h | 8 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_riscv64.cc | 22 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 56 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 62 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/graph_checker.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 19 | ||||
-rw-r--r-- | compiler/optimizing/instruction_simplifier_arm.cc | 6 | ||||
-rw-r--r-- | compiler/optimizing/instruction_simplifier_arm64.cc | 6 | ||||
-rw-r--r-- | compiler/optimizing/instruction_simplifier_shared.cc | 19 | ||||
-rw-r--r-- | compiler/optimizing/instruction_simplifier_shared.h | 8 | ||||
-rw-r--r-- | compiler/optimizing/instruction_simplifier_x86.cc | 31 | ||||
-rw-r--r-- | compiler/optimizing/nodes.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 26 |
17 files changed, 66 insertions, 318 deletions
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 42d955ef9e..6ffd1aa686 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -2430,22 +2430,6 @@ void InstructionCodeGeneratorARM64::HandleBinaryOp(HBinaryOperation* instr) { __ Orr(dst, lhs, rhs); } else if (instr->IsSub()) { __ Sub(dst, lhs, rhs); - } else if (instr->IsRol()) { - if (rhs.IsImmediate()) { - uint32_t shift = (-rhs.GetImmediate()) & (lhs.GetSizeInBits() - 1); - __ Ror(dst, lhs, shift); - } else { - UseScratchRegisterScope temps(GetVIXLAssembler()); - - // Ensure shift distance is in the same size register as the result. If - // we are rotating a long and the shift comes in a w register originally, - // we don't need to sxtw for use as an x since the shift distances are - // all & reg_bits - 1. - Register right = RegisterFrom(instr->GetLocations()->InAt(1), type); - Register negated = (type == DataType::Type::kInt32) ? temps.AcquireW() : temps.AcquireX(); - __ Neg(negated, right); - __ Ror(dst, lhs, negated); - } } else if (instr->IsRor()) { if (rhs.IsImmediate()) { uint32_t shift = rhs.GetImmediate() & (lhs.GetSizeInBits() - 1); @@ -6427,14 +6411,6 @@ void InstructionCodeGeneratorARM64::VisitReturnVoid([[maybe_unused]] HReturnVoid codegen_->GenerateFrameExit(); } -void LocationsBuilderARM64::VisitRol(HRol* rol) { - HandleBinaryOp(rol); -} - -void InstructionCodeGeneratorARM64::VisitRol(HRol* rol) { - HandleBinaryOp(rol); -} - void LocationsBuilderARM64::VisitRor(HRor* ror) { HandleBinaryOp(ror); } diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index fb8f8c0153..1afca6b8d6 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -5280,22 +5280,17 @@ void InstructionCodeGeneratorARMVIXL::VisitDivZeroCheck(HDivZeroCheck* instructi } } -void InstructionCodeGeneratorARMVIXL::HandleIntegerRotate(HBinaryOperation* rotate) { - LocationSummary* locations = rotate->GetLocations(); - vixl32::Register in = InputRegisterAt(rotate, 0); +void InstructionCodeGeneratorARMVIXL::HandleIntegerRotate(HRor* ror) { + LocationSummary* locations = ror->GetLocations(); + vixl32::Register in = InputRegisterAt(ror, 0); Location rhs = locations->InAt(1); - vixl32::Register out = OutputRegister(rotate); + vixl32::Register out = OutputRegister(ror); if (rhs.IsConstant()) { // Arm32 and Thumb2 assemblers require a rotation on the interval [1,31], // so map all rotations to a +ve. equivalent in that range. // (e.g. left *or* right by -2 bits == 30 bits in the same direction.) uint32_t rot = CodeGenerator::GetInt32ValueOf(rhs.GetConstant()) & 0x1F; - - if (rotate->IsRol()) { - rot = -rot; - } - if (rot) { // Rotate, mapping left rotations to right equivalents if necessary. // (e.g. left by 2 bits == right by 30.) @@ -5304,16 +5299,7 @@ void InstructionCodeGeneratorARMVIXL::HandleIntegerRotate(HBinaryOperation* rota __ Mov(out, in); } } else { - if (rotate->IsRol()) { - UseScratchRegisterScope temps(GetVIXLAssembler()); - - vixl32::Register negated = temps.Acquire(); - __ Rsb(negated, RegisterFrom(rhs), 0); - __ Ror(out, in, negated); - } else { - DCHECK(rotate->IsRor()); - __ Ror(out, in, RegisterFrom(rhs)); - } + __ Ror(out, in, RegisterFrom(rhs)); } } @@ -5321,8 +5307,8 @@ void InstructionCodeGeneratorARMVIXL::HandleIntegerRotate(HBinaryOperation* rota // rotates by swapping input regs (effectively rotating by the first 32-bits of // a larger rotation) or flipping direction (thus treating larger right/left // rotations as sub-word sized rotations in the other direction) as appropriate. -void InstructionCodeGeneratorARMVIXL::HandleLongRotate(HBinaryOperation* rotate) { - LocationSummary* locations = rotate->GetLocations(); +void InstructionCodeGeneratorARMVIXL::HandleLongRotate(HRor* ror) { + LocationSummary* locations = ror->GetLocations(); vixl32::Register in_reg_lo = LowRegisterFrom(locations->InAt(0)); vixl32::Register in_reg_hi = HighRegisterFrom(locations->InAt(0)); Location rhs = locations->InAt(1); @@ -5331,11 +5317,6 @@ void InstructionCodeGeneratorARMVIXL::HandleLongRotate(HBinaryOperation* rotate) if (rhs.IsConstant()) { uint64_t rot = CodeGenerator::GetInt64ValueOf(rhs.GetConstant()); - - if (rotate->IsRol()) { - rot = -rot; - } - // Map all rotations to +ve. equivalents on the interval [0,63]. rot &= kMaxLongShiftDistance; // For rotates over a word in size, 'pre-rotate' by 32-bits to keep rotate @@ -5360,17 +5341,7 @@ void InstructionCodeGeneratorARMVIXL::HandleLongRotate(HBinaryOperation* rotate) vixl32::Register shift_left = RegisterFrom(locations->GetTemp(1)); vixl32::Label end; vixl32::Label shift_by_32_plus_shift_right; - vixl32::Label* final_label = codegen_->GetFinalLabel(rotate, &end); - - // Negate rhs, taken from VisitNeg - if (rotate->IsRol()) { - Location negated = locations->GetTemp(2); - Location in = rhs; - - __ Rsb(RegisterFrom(negated), RegisterFrom(in), 0); - - rhs = negated; - } + vixl32::Label* final_label = codegen_->GetFinalLabel(ror, &end); __ And(shift_right, RegisterFrom(rhs), 0x1F); __ Lsrs(shift_left, RegisterFrom(rhs), 6); @@ -5403,11 +5374,11 @@ void InstructionCodeGeneratorARMVIXL::HandleLongRotate(HBinaryOperation* rotate) } } -void LocationsBuilderARMVIXL::HandleRotate(HBinaryOperation* rotate) { +void LocationsBuilderARMVIXL::VisitRor(HRor* ror) { LocationSummary* locations = - new (GetGraph()->GetAllocator()) LocationSummary(rotate, LocationSummary::kNoCall); - HInstruction* shift = rotate->InputAt(1); - switch (rotate->GetResultType()) { + new (GetGraph()->GetAllocator()) LocationSummary(ror, LocationSummary::kNoCall); + HInstruction* shift = ror->InputAt(1); + switch (ror->GetResultType()) { case DataType::Type::kInt32: { locations->SetInAt(0, Location::RequiresRegister()); locations->SetInAt(1, Location::RegisterOrConstant(shift)); @@ -5420,39 +5391,25 @@ void LocationsBuilderARMVIXL::HandleRotate(HBinaryOperation* rotate) { locations->SetInAt(1, Location::ConstantLocation(shift)); } else { locations->SetInAt(1, Location::RequiresRegister()); - - if (rotate->IsRor()) { - locations->AddRegisterTemps(2); - } else { - DCHECK(rotate->IsRol()); - locations->AddRegisterTemps(3); - } + locations->AddRegisterTemps(2); } locations->SetOut(Location::RequiresRegister(), Location::kOutputOverlap); break; } default: - LOG(FATAL) << "Unexpected operation type " << rotate->GetResultType(); + LOG(FATAL) << "Unexpected operation type " << ror->GetResultType(); } } -void LocationsBuilderARMVIXL::VisitRol(HRol* rol) { - HandleRotate(rol); -} - -void LocationsBuilderARMVIXL::VisitRor(HRor* ror) { - HandleRotate(ror); -} - -void InstructionCodeGeneratorARMVIXL::HandleRotate(HBinaryOperation* rotate) { - DataType::Type type = rotate->GetResultType(); +void InstructionCodeGeneratorARMVIXL::VisitRor(HRor* ror) { + DataType::Type type = ror->GetResultType(); switch (type) { case DataType::Type::kInt32: { - HandleIntegerRotate(rotate); + HandleIntegerRotate(ror); break; } case DataType::Type::kInt64: { - HandleLongRotate(rotate); + HandleLongRotate(ror); break; } default: @@ -5461,14 +5418,6 @@ void InstructionCodeGeneratorARMVIXL::HandleRotate(HBinaryOperation* rotate) { } } -void InstructionCodeGeneratorARMVIXL::VisitRol(HRol* rol) { - HandleRotate(rol); -} - -void InstructionCodeGeneratorARMVIXL::VisitRor(HRor* ror) { - HandleRotate(ror); -} - void LocationsBuilderARMVIXL::HandleShift(HBinaryOperation* op) { DCHECK(op->IsShl() || op->IsShr() || op->IsUShr()); diff --git a/compiler/optimizing/code_generator_arm_vixl.h b/compiler/optimizing/code_generator_arm_vixl.h index 00b5a69b1d..0c2e79c134 100644 --- a/compiler/optimizing/code_generator_arm_vixl.h +++ b/compiler/optimizing/code_generator_arm_vixl.h @@ -390,12 +390,13 @@ class LocationsBuilderARMVIXL : public HGraphVisitor { void HandleInvoke(HInvoke* invoke); void HandleBitwiseOperation(HBinaryOperation* operation, Opcode opcode); void HandleCondition(HCondition* condition); + void HandleIntegerRotate(LocationSummary* locations); + void HandleLongRotate(LocationSummary* locations); void HandleShift(HBinaryOperation* operation); void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info, WriteBarrierKind write_barrier_kind); void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info); - void HandleRotate(HBinaryOperation* rotate); Location ArithmeticZeroOrFpuRegister(HInstruction* input); Location ArmEncodableConstantOrRegister(HInstruction* constant, Opcode opcode); @@ -445,9 +446,8 @@ class InstructionCodeGeneratorARMVIXL : public InstructionCodeGenerator { void GenerateAddLongConst(Location out, Location first, uint64_t value); void HandleBitwiseOperation(HBinaryOperation* operation); void HandleCondition(HCondition* condition); - void HandleIntegerRotate(HBinaryOperation* rotate); - void HandleLongRotate(HBinaryOperation* rotate); - void HandleRotate(HBinaryOperation* rotate); + void HandleIntegerRotate(HRor* ror); + void HandleLongRotate(HRor* ror); void HandleShift(HBinaryOperation* operation); void GenerateWideAtomicStore(vixl::aarch32::Register addr, diff --git a/compiler/optimizing/code_generator_riscv64.cc b/compiler/optimizing/code_generator_riscv64.cc index 43f855a915..bfc693f76b 100644 --- a/compiler/optimizing/code_generator_riscv64.cc +++ b/compiler/optimizing/code_generator_riscv64.cc @@ -2331,7 +2331,6 @@ void LocationsBuilderRISCV64::HandleShift(HBinaryOperation* instruction) { DCHECK(instruction->IsShl() || instruction->IsShr() || instruction->IsUShr() || - instruction->IsRol() || instruction->IsRor()); LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(instruction); @@ -2354,9 +2353,7 @@ void InstructionCodeGeneratorRISCV64::HandleShift(HBinaryOperation* instruction) DCHECK(instruction->IsShl() || instruction->IsShr() || instruction->IsUShr() || - instruction->IsRol() || instruction->IsRor()); - LocationSummary* locations = instruction->GetLocations(); DataType::Type type = instruction->GetType(); @@ -2369,9 +2366,6 @@ void InstructionCodeGeneratorRISCV64::HandleShift(HBinaryOperation* instruction) if (rs2_location.IsConstant()) { int64_t imm = CodeGenerator::GetInt64ValueOf(rs2_location.GetConstant()); - if (instruction->IsRol()) { - imm = -imm; - } uint32_t shamt = imm & (type == DataType::Type::kInt32 ? kMaxIntShiftDistance : kMaxLongShiftDistance); @@ -2386,8 +2380,6 @@ void InstructionCodeGeneratorRISCV64::HandleShift(HBinaryOperation* instruction) __ Sraiw(rd, rs1, shamt); } else if (instruction->IsUShr()) { __ Srliw(rd, rs1, shamt); - } else if (instruction->IsRol()) { - __ Roriw(rd, rs1, shamt); } else { DCHECK(instruction->IsRor()); __ Roriw(rd, rs1, shamt); @@ -2399,8 +2391,6 @@ void InstructionCodeGeneratorRISCV64::HandleShift(HBinaryOperation* instruction) __ Srai(rd, rs1, shamt); } else if (instruction->IsUShr()) { __ Srli(rd, rs1, shamt); - } else if (instruction->IsRol()) { - __ Rori(rd, rs1, shamt); } else { DCHECK(instruction->IsRor()); __ Rori(rd, rs1, shamt); @@ -2415,8 +2405,6 @@ void InstructionCodeGeneratorRISCV64::HandleShift(HBinaryOperation* instruction) __ Sraw(rd, rs1, rs2); } else if (instruction->IsUShr()) { __ Srlw(rd, rs1, rs2); - } else if (instruction->IsRol()) { - __ Rolw(rd, rs1, rs2); } else { DCHECK(instruction->IsRor()); __ Rorw(rd, rs1, rs2); @@ -2428,8 +2416,6 @@ void InstructionCodeGeneratorRISCV64::HandleShift(HBinaryOperation* instruction) __ Sra(rd, rs1, rs2); } else if (instruction->IsUShr()) { __ Srl(rd, rs1, rs2); - } else if (instruction->IsRol()) { - __ Rol(rd, rs1, rs2); } else { DCHECK(instruction->IsRor()); __ Ror(rd, rs1, rs2); @@ -5020,14 +5006,6 @@ void InstructionCodeGeneratorRISCV64::VisitReturnVoid([[maybe_unused]] HReturnVo codegen_->GenerateFrameExit(); } -void LocationsBuilderRISCV64::VisitRol(HRol* instruction) { - HandleShift(instruction); -} - -void InstructionCodeGeneratorRISCV64::VisitRol(HRol* instruction) { - HandleShift(instruction); -} - void LocationsBuilderRISCV64::VisitRor(HRor* instruction) { HandleShift(instruction); } diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 7e3c6216eb..5b2d0d4535 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -5052,19 +5052,11 @@ void InstructionCodeGeneratorX86::GenerateUShrLong(const Location& loc, Register __ Bind(&done); } -void LocationsBuilderX86::VisitRol(HRol* rol) { - HandleRotate(rol); -} - void LocationsBuilderX86::VisitRor(HRor* ror) { - HandleRotate(ror); -} - -void LocationsBuilderX86::HandleRotate(HBinaryOperation* rotate) { LocationSummary* locations = - new (GetGraph()->GetAllocator()) LocationSummary(rotate, LocationSummary::kNoCall); + new (GetGraph()->GetAllocator()) LocationSummary(ror, LocationSummary::kNoCall); - switch (rotate->GetResultType()) { + switch (ror->GetResultType()) { case DataType::Type::kInt64: // Add the temporary needed. locations->AddTemp(Location::RequiresRegister()); @@ -5072,62 +5064,39 @@ void LocationsBuilderX86::HandleRotate(HBinaryOperation* rotate) { case DataType::Type::kInt32: locations->SetInAt(0, Location::RequiresRegister()); // The shift count needs to be in CL (unless it is a constant). - locations->SetInAt(1, Location::ByteRegisterOrConstant(ECX, rotate->InputAt(1))); + locations->SetInAt(1, Location::ByteRegisterOrConstant(ECX, ror->InputAt(1))); locations->SetOut(Location::SameAsFirstInput()); break; default: - LOG(FATAL) << "Unexpected operation type " << rotate->GetResultType(); + LOG(FATAL) << "Unexpected operation type " << ror->GetResultType(); UNREACHABLE(); } } -void InstructionCodeGeneratorX86::VisitRol(HRol* rol) { - HandleRotate(rol); -} - void InstructionCodeGeneratorX86::VisitRor(HRor* ror) { - HandleRotate(ror); -} - -void InstructionCodeGeneratorX86::HandleRotate(HBinaryOperation* rotate) { - LocationSummary* locations = rotate->GetLocations(); + LocationSummary* locations = ror->GetLocations(); Location first = locations->InAt(0); Location second = locations->InAt(1); - if (rotate->GetResultType() == DataType::Type::kInt32) { + if (ror->GetResultType() == DataType::Type::kInt32) { Register first_reg = first.AsRegister<Register>(); if (second.IsRegister()) { Register second_reg = second.AsRegister<Register>(); - if (rotate->IsRol()) { - __ roll(first_reg, second_reg); - } else { - DCHECK(rotate->IsRor()); - __ rorl(first_reg, second_reg); - } + __ rorl(first_reg, second_reg); } else { Immediate imm(second.GetConstant()->AsIntConstant()->GetValue() & kMaxIntShiftDistance); - if (rotate->IsRol()) { - __ roll(first_reg, imm); - } else { - DCHECK(rotate->IsRor()); - __ rorl(first_reg, imm); - } + __ rorl(first_reg, imm); } return; } - DCHECK_EQ(rotate->GetResultType(), DataType::Type::kInt64); + DCHECK_EQ(ror->GetResultType(), DataType::Type::kInt64); Register first_reg_lo = first.AsRegisterPairLow<Register>(); Register first_reg_hi = first.AsRegisterPairHigh<Register>(); Register temp_reg = locations->GetTemp(0).AsRegister<Register>(); if (second.IsRegister()) { Register second_reg = second.AsRegister<Register>(); DCHECK_EQ(second_reg, ECX); - - if (rotate->IsRol()) { - __ negl(second_reg); - } - __ movl(temp_reg, first_reg_hi); __ shrd(first_reg_hi, first_reg_lo, second_reg); __ shrd(first_reg_lo, temp_reg, second_reg); @@ -5136,12 +5105,7 @@ void InstructionCodeGeneratorX86::HandleRotate(HBinaryOperation* rotate) { __ cmovl(kNotEqual, first_reg_hi, first_reg_lo); __ cmovl(kNotEqual, first_reg_lo, temp_reg); } else { - int32_t value = second.GetConstant()->AsIntConstant()->GetValue(); - if (rotate->IsRol()) { - value = -value; - } - int32_t shift_amt = value & kMaxLongShiftDistance; - + int32_t shift_amt = second.GetConstant()->AsIntConstant()->GetValue() & kMaxLongShiftDistance; if (shift_amt == 0) { // Already fine. return; diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h index 321ee92e2e..bb6fa2a298 100644 --- a/compiler/optimizing/code_generator_x86.h +++ b/compiler/optimizing/code_generator_x86.h @@ -249,7 +249,6 @@ class LocationsBuilderX86 : public HGraphVisitor { void HandleBitwiseOperation(HBinaryOperation* instruction); void HandleInvoke(HInvoke* invoke); void HandleCondition(HCondition* condition); - void HandleRotate(HBinaryOperation* rotate); void HandleShift(HBinaryOperation* instruction); void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info, @@ -340,7 +339,6 @@ class InstructionCodeGeneratorX86 : public InstructionCodeGenerator { bool value_can_be_null, WriteBarrierKind write_barrier_kind); void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info); - void HandleRotate(HBinaryOperation* rotate); // Generate a heap reference load using one register `out`: // diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 51ded684c6..6a7f9b1264 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -5035,91 +5035,55 @@ void InstructionCodeGeneratorX86_64::HandleShift(HBinaryOperation* op) { } } -void LocationsBuilderX86_64::HandleRotate(HBinaryOperation* rotate) { +void LocationsBuilderX86_64::VisitRor(HRor* ror) { LocationSummary* locations = - new (GetGraph()->GetAllocator()) LocationSummary(rotate, LocationSummary::kNoCall); + new (GetGraph()->GetAllocator()) LocationSummary(ror, LocationSummary::kNoCall); - switch (rotate->GetResultType()) { + switch (ror->GetResultType()) { case DataType::Type::kInt32: case DataType::Type::kInt64: { locations->SetInAt(0, Location::RequiresRegister()); // The shift count needs to be in CL (unless it is a constant). - locations->SetInAt(1, Location::ByteRegisterOrConstant(RCX, rotate->InputAt(1))); + locations->SetInAt(1, Location::ByteRegisterOrConstant(RCX, ror->InputAt(1))); locations->SetOut(Location::SameAsFirstInput()); break; } default: - LOG(FATAL) << "Unexpected operation type " << rotate->GetResultType(); + LOG(FATAL) << "Unexpected operation type " << ror->GetResultType(); UNREACHABLE(); } } -void InstructionCodeGeneratorX86_64::HandleRotate(HBinaryOperation* rotate) { - LocationSummary* locations = rotate->GetLocations(); +void InstructionCodeGeneratorX86_64::VisitRor(HRor* ror) { + LocationSummary* locations = ror->GetLocations(); CpuRegister first_reg = locations->InAt(0).AsRegister<CpuRegister>(); Location second = locations->InAt(1); - switch (rotate->GetResultType()) { + switch (ror->GetResultType()) { case DataType::Type::kInt32: if (second.IsRegister()) { CpuRegister second_reg = second.AsRegister<CpuRegister>(); - if (rotate->IsRor()) { - __ rorl(first_reg, second_reg); - } else { - DCHECK(rotate->IsRol()); - __ roll(first_reg, second_reg); - } + __ rorl(first_reg, second_reg); } else { Immediate imm(second.GetConstant()->AsIntConstant()->GetValue() & kMaxIntShiftDistance); - if (rotate->IsRor()) { - __ rorl(first_reg, imm); - } else { - DCHECK(rotate->IsRol()); - __ roll(first_reg, imm); - } + __ rorl(first_reg, imm); } break; case DataType::Type::kInt64: if (second.IsRegister()) { CpuRegister second_reg = second.AsRegister<CpuRegister>(); - if (rotate->IsRor()) { - __ rorq(first_reg, second_reg); - } else { - DCHECK(rotate->IsRol()); - __ rolq(first_reg, second_reg); - } + __ rorq(first_reg, second_reg); } else { Immediate imm(second.GetConstant()->AsIntConstant()->GetValue() & kMaxLongShiftDistance); - if (rotate->IsRor()) { - __ rorq(first_reg, imm); - } else { - DCHECK(rotate->IsRol()); - __ rolq(first_reg, imm); - } + __ rorq(first_reg, imm); } break; default: - LOG(FATAL) << "Unexpected operation type " << rotate->GetResultType(); + LOG(FATAL) << "Unexpected operation type " << ror->GetResultType(); UNREACHABLE(); } } -void InstructionCodeGeneratorX86_64::VisitRor(HRor* ror) { - HandleRotate(ror); -} - -void LocationsBuilderX86_64::VisitRol(HRol* rol) { - HandleRotate(rol); -} - -void LocationsBuilderX86_64::VisitRor(HRor* ror) { - HandleRotate(ror); -} - -void InstructionCodeGeneratorX86_64::VisitRol(HRol* rol) { - HandleRotate(rol); -} - void LocationsBuilderX86_64::VisitShl(HShl* shl) { HandleShift(shl); } diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h index b3eb1a0373..03b73abd62 100644 --- a/compiler/optimizing/code_generator_x86_64.h +++ b/compiler/optimizing/code_generator_x86_64.h @@ -247,7 +247,6 @@ class LocationsBuilderX86_64 : public HGraphVisitor { void HandleBitwiseOperation(HBinaryOperation* operation); void HandleCondition(HCondition* condition); void HandleShift(HBinaryOperation* operation); - void HandleRotate(HBinaryOperation* rotate); void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info, WriteBarrierKind write_barrier_kind); @@ -321,7 +320,6 @@ class InstructionCodeGeneratorX86_64 : public InstructionCodeGenerator { void GenerateDivRemIntegral(HBinaryOperation* instruction); void HandleCondition(HCondition* condition); void HandleShift(HBinaryOperation* operation); - void HandleRotate(HBinaryOperation* rotate); void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info, diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc index 82f98ed5ea..ad0d0fb2ca 100644 --- a/compiler/optimizing/graph_checker.cc +++ b/compiler/optimizing/graph_checker.cc @@ -1404,7 +1404,7 @@ void GraphChecker::VisitBinaryOperation(HBinaryOperation* op) { DataType::Type result_type = op->GetType(); // Type consistency between inputs. - if (op->IsUShr() || op->IsShr() || op->IsShl() || op->IsRol() || op->IsRor()) { + if (op->IsUShr() || op->IsShr() || op->IsShl() || op->IsRor()) { if (DataType::Kind(rhs_type) != DataType::Type::kInt32) { AddError(StringPrintf("Shift/rotate operation %s %d has a non-int kind second input: " "%s of type %s.", @@ -1428,7 +1428,7 @@ void GraphChecker::VisitBinaryOperation(HBinaryOperation* op) { op->GetId(), DataType::PrettyDescriptor(result_type))); } - } else if (op->IsUShr() || op->IsShr() || op->IsShl() || op->IsRol() || op->IsRor()) { + } else if (op->IsUShr() || op->IsShr() || op->IsShl() || op->IsRor()) { // Only check the first input (value), as the second one (distance) // must invariably be of kind `int`. if (result_type != DataType::Kind(lhs_type)) { diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 55e3267427..f3676bbc02 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -1953,16 +1953,14 @@ bool HInstructionBuilder::BuildSimpleIntrinsic(ArtMethod* method, ReceiverArg receiver_arg = method->IsStatic() ? ReceiverArg::kNone : ReceiverArg::kNullCheckedArg; HInstruction* instruction = nullptr; switch (intrinsic) { - case Intrinsics::kIntegerRotateLeft: - instruction = new (allocator_) HRol(kInt32, /*value=*/ nullptr, /*distance=*/ nullptr); - break; case Intrinsics::kIntegerRotateRight: + case Intrinsics::kIntegerRotateLeft: + // For rotate left, we negate the distance below. instruction = new (allocator_) HRor(kInt32, /*value=*/ nullptr, /*distance=*/ nullptr); break; - case Intrinsics::kLongRotateLeft: - instruction = new (allocator_) HRol(kInt64, /*value=*/ nullptr, /*distance=*/ nullptr); - break; case Intrinsics::kLongRotateRight: + case Intrinsics::kLongRotateLeft: + // For rotate left, we negate the distance below. instruction = new (allocator_) HRor(kInt64, /*value=*/ nullptr, /*distance=*/ nullptr); break; case Intrinsics::kIntegerCompare: @@ -2081,6 +2079,15 @@ bool HInstructionBuilder::BuildSimpleIntrinsic(ArtMethod* method, } switch (intrinsic) { + case Intrinsics::kIntegerRotateLeft: + case Intrinsics::kLongRotateLeft: { + // Negate the distance value for rotate left. + DCHECK(instruction->IsRor()); + HNeg* neg = new (allocator_) HNeg(kInt32, instruction->InputAt(1u)); + AppendInstruction(neg); + instruction->SetRawInputAt(1u, neg); + break; + } case Intrinsics::kFloatIsNaN: case Intrinsics::kDoubleIsNaN: // Set the second input to be the same as first. diff --git a/compiler/optimizing/instruction_simplifier_arm.cc b/compiler/optimizing/instruction_simplifier_arm.cc index 7dccc036b5..a050f86363 100644 --- a/compiler/optimizing/instruction_simplifier_arm.cc +++ b/compiler/optimizing/instruction_simplifier_arm.cc @@ -74,7 +74,6 @@ class InstructionSimplifierArmVisitor final : public HGraphVisitor { void VisitArraySet(HArraySet* instruction) override; void VisitMul(HMul* instruction) override; void VisitOr(HOr* instruction) override; - void VisitRol(HRol* instruction) override; void VisitShl(HShl* instruction) override; void VisitShr(HShr* instruction) override; void VisitSub(HSub* instruction) override; @@ -264,11 +263,6 @@ void InstructionSimplifierArmVisitor::VisitOr(HOr* instruction) { } } -void InstructionSimplifierArmVisitor::VisitRol(HRol* instruction) { - UnfoldRotateLeft(instruction); - RecordSimplification(); -} - void InstructionSimplifierArmVisitor::VisitShl(HShl* instruction) { if (instruction->InputAt(1)->IsConstant()) { TryMergeIntoUsersShifterOperand(instruction); diff --git a/compiler/optimizing/instruction_simplifier_arm64.cc b/compiler/optimizing/instruction_simplifier_arm64.cc index 8dd64e59ee..f57448d70f 100644 --- a/compiler/optimizing/instruction_simplifier_arm64.cc +++ b/compiler/optimizing/instruction_simplifier_arm64.cc @@ -77,7 +77,6 @@ class InstructionSimplifierArm64Visitor final : public HGraphVisitor { void VisitArraySet(HArraySet* instruction) override; void VisitMul(HMul* instruction) override; void VisitOr(HOr* instruction) override; - void VisitRol(HRol* instruction) override; void VisitShl(HShl* instruction) override; void VisitShr(HShr* instruction) override; void VisitSub(HSub* instruction) override; @@ -235,11 +234,6 @@ void InstructionSimplifierArm64Visitor::VisitOr(HOr* instruction) { } } -void InstructionSimplifierArm64Visitor::VisitRol(HRol* rol) { - UnfoldRotateLeft(rol); - RecordSimplification(); -} - void InstructionSimplifierArm64Visitor::VisitShl(HShl* instruction) { if (instruction->InputAt(1)->IsConstant()) { TryMergeIntoUsersShifterOperand(instruction); diff --git a/compiler/optimizing/instruction_simplifier_shared.cc b/compiler/optimizing/instruction_simplifier_shared.cc index 7f575c0348..b7d76da548 100644 --- a/compiler/optimizing/instruction_simplifier_shared.cc +++ b/compiler/optimizing/instruction_simplifier_shared.cc @@ -316,23 +316,4 @@ bool TryReplaceSubSubWithSubAdd(HSub* last_sub) { } } -void UnfoldRotateLeft(HRol* rol) { - HBasicBlock* block = rol->GetBlock(); - HGraph* graph = block->GetGraph(); - ArenaAllocator* allocator = graph->GetAllocator(); - HRor* ror; - - if (rol->GetRight()->IsConstant()) { - int32_t value = rol->GetRight()->AsIntConstant()->GetValue(); - HIntConstant* negated = graph->GetIntConstant(-value); - ror = new (allocator) HRor(rol->GetType(), rol->GetLeft(), negated); - } else { - HNeg* neg = new (allocator) HNeg(DataType::Type::kInt32, rol->GetRight()); - block->InsertInstructionBefore(neg, rol); - ror = new (allocator) HRor(rol->GetType(), rol->GetLeft(), neg); - } - - block->ReplaceAndRemoveInstructionWith(rol, ror); -} - } // namespace art diff --git a/compiler/optimizing/instruction_simplifier_shared.h b/compiler/optimizing/instruction_simplifier_shared.h index 8e61109b0e..de70ec5a8a 100644 --- a/compiler/optimizing/instruction_simplifier_shared.h +++ b/compiler/optimizing/instruction_simplifier_shared.h @@ -77,14 +77,6 @@ bool TryExtractVecArrayAccessAddress(HVecMemoryOperation* access, HInstruction* // Add(c, Sub(b, a)) bool TryReplaceSubSubWithSubAdd(HSub* last_sub); -// ARM does not contain instruction ROL so replace -// ROL dest, a, distance -// with -// NEG neg, distance -// ROR dest, a, neg -// before GVN to give it a chance to deduplicate the instructions, if it's able. -void UnfoldRotateLeft(HRol* rol); - } // namespace art #endif // ART_COMPILER_OPTIMIZING_INSTRUCTION_SIMPLIFIER_SHARED_H_ diff --git a/compiler/optimizing/instruction_simplifier_x86.cc b/compiler/optimizing/instruction_simplifier_x86.cc index e1c783e5b8..5a4345d589 100644 --- a/compiler/optimizing/instruction_simplifier_x86.cc +++ b/compiler/optimizing/instruction_simplifier_x86.cc @@ -48,7 +48,6 @@ class InstructionSimplifierX86Visitor final : public HGraphVisitor { } void VisitAnd(HAnd * instruction) override; - void VisitRol(HRol* instruction) override; void VisitXor(HXor* instruction) override; private: @@ -58,10 +57,6 @@ class InstructionSimplifierX86Visitor final : public HGraphVisitor { void InstructionSimplifierX86Visitor::VisitAnd(HAnd* instruction) { - if (!HasAVX2()) { - return; - } - if (TryCombineAndNot(instruction)) { RecordSimplification(); } else if (instruction->GetResultType() == DataType::Type::kInt32) { @@ -71,26 +66,7 @@ void InstructionSimplifierX86Visitor::VisitAnd(HAnd* instruction) { } } -void InstructionSimplifierX86Visitor::VisitRol(HRol* rol) { - if (rol->GetType() != DataType::Type::kInt64) { - return; - } - - HBasicBlock* block = rol->GetBlock(); - HGraph* graph = block->GetGraph(); - ArenaAllocator* allocator = graph->GetAllocator(); - - HNeg* neg = new (allocator) HNeg(DataType::Type::kInt32, rol->GetRight()); - block->InsertInstructionBefore(neg, rol); - HRor* ror = new (allocator) HRor(rol->GetType(), rol->GetLeft(), neg); - block->ReplaceAndRemoveInstructionWith(rol, ror); -} - void InstructionSimplifierX86Visitor::VisitXor(HXor* instruction) { - if (!HasAVX2()) { - return; - } - if (instruction->GetResultType() == DataType::Type::kInt32) { if (TryGenerateMaskUptoLeastSetBit(instruction)) { RecordSimplification(); @@ -100,8 +76,11 @@ void InstructionSimplifierX86Visitor::VisitXor(HXor* instruction) { bool InstructionSimplifierX86::Run() { InstructionSimplifierX86Visitor visitor(graph_, codegen_, stats_); - visitor.VisitReversePostOrder(); - return true; + if (visitor.HasAVX2()) { + visitor.VisitReversePostOrder(); + return true; + } + return false; } } // namespace x86 diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 32ae89eeea..588f4d7ce2 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -1829,7 +1829,7 @@ HConstant* HBinaryOperation::TryStaticEvaluation(HInstruction* left, HInstructio } else if (left->IsLongConstant()) { if (right->IsIntConstant()) { // The binop(long, int) case is only valid for shifts and rotations. - DCHECK(IsShl() || IsShr() || IsUShr() || IsRol() || IsRor()) << DebugName(); + DCHECK(IsShl() || IsShr() || IsUShr() || IsRor()) << DebugName(); return Evaluate(left->AsLongConstant(), right->AsIntConstant()); } else if (right->IsLongConstant()) { return Evaluate(left->AsLongConstant(), right->AsLongConstant()); diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 2477c9fe51..eb6d9ecad4 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -1593,7 +1593,6 @@ class HLoopInformationOutwardIterator : public ValueObject { M(Rem, BinaryOperation) \ M(Return, Instruction) \ M(ReturnVoid, Instruction) \ - M(Rol, BinaryOperation) \ M(Ror, BinaryOperation) \ M(Shl, BinaryOperation) \ M(Shr, BinaryOperation) \ @@ -5999,31 +5998,6 @@ class HRor final : public HBinaryOperation { DEFAULT_COPY_CONSTRUCTOR(Ror); }; -class HRol final : public HBinaryOperation { - public: - HRol(DataType::Type result_type, HInstruction* value, HInstruction* distance) - : HBinaryOperation(kRol, result_type, value, distance) {} - - template <typename T> - static T Compute(T value, int32_t distance, int32_t max_shift_value) { - return HRor::Compute(value, -distance, max_shift_value); - } - - HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const override { - return GetBlock()->GetGraph()->GetIntConstant( - Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance), GetDexPc()); - } - HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const override { - return GetBlock()->GetGraph()->GetLongConstant( - Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance), GetDexPc()); - } - - DECLARE_INSTRUCTION(Rol); - - protected: - DEFAULT_COPY_CONSTRUCTOR(Rol); -}; - // The value of a parameter in this method. Its location depends on // the calling convention. class HParameterValue final : public HExpression<0> { |