Chromium Code Reviews| Index: src/compiler/move-optimizer.cc |
| diff --git a/src/compiler/move-optimizer.cc b/src/compiler/move-optimizer.cc |
| index 50516c123989f63bdd6e42e639b09f0e85bae64c..30703e5c75536a52f44c6239fc7966ca3d6ebdbb 100644 |
| --- a/src/compiler/move-optimizer.cc |
| +++ b/src/compiler/move-optimizer.cc |
| @@ -27,32 +27,53 @@ struct MoveKeyCompare { |
| typedef ZoneMap<MoveKey, unsigned, MoveKeyCompare> MoveMap; |
| typedef ZoneSet<InstructionOperand, CompareOperandModuloType> OperandSet; |
| +bool Contains(const OperandSet& set, const LocationOperand& loc, |
| + MachineRepresentation rep, int reg_code) { |
| + return set.find(LocationOperand(loc.kind(), loc.location_kind(), rep, |
| + reg_code)) != set.end(); |
| +} |
| + |
| bool Blocks(const OperandSet& set, const InstructionOperand& operand) { |
| if (set.find(operand) != set.end()) return true; |
| - // Only FP registers alias. |
| + // General registers don't alias. |
| if (!operand.IsFPRegister()) return false; |
| + // Check operand against operands of other FP types for interference. |
| const LocationOperand& loc = LocationOperand::cast(operand); |
| MachineRepresentation rep = loc.representation(); |
| - MachineRepresentation other_fp_rep = rep == MachineRepresentation::kFloat64 |
| - ? MachineRepresentation::kFloat32 |
| - : MachineRepresentation::kFloat64; |
| + MachineRepresentation other_rep1, other_rep2; |
| + switch (rep) { |
| + case MachineRepresentation::kFloat32: |
| + other_rep1 = MachineRepresentation::kFloat64; |
| + other_rep2 = MachineRepresentation::kSimd128; |
| + break; |
| + case MachineRepresentation::kFloat64: |
| + other_rep1 = MachineRepresentation::kFloat32; |
| + other_rep2 = MachineRepresentation::kSimd128; |
| + break; |
| + case MachineRepresentation::kSimd128: |
| + other_rep1 = MachineRepresentation::kFloat32; |
| + other_rep2 = MachineRepresentation::kFloat64; |
| + break; |
| + default: |
| + UNREACHABLE(); |
| + break; |
| + } |
| const RegisterConfiguration* config = RegisterConfiguration::Turbofan(); |
| if (config->fp_aliasing_kind() != RegisterConfiguration::COMBINE) { |
| // Overlap aliasing case. |
| - return set.find(LocationOperand(loc.kind(), loc.location_kind(), |
| - other_fp_rep, loc.register_code())) != |
| - set.end(); |
| + return Contains(set, loc, other_rep1, loc.register_code()) || |
| + Contains(set, loc, other_rep2, loc.register_code()); |
| } |
| // Combine aliasing case. |
| - int alias_base_index = -1; |
| - int aliases = config->GetAliases(rep, loc.register_code(), other_fp_rep, |
| - &alias_base_index); |
| + int base = -1; |
| + int aliases = config->GetAliases(rep, loc.register_code(), other_rep1, &base); |
|
Mircea Trofin
2016/06/27 20:32:26
Is base expected to be positive after this?
bbudge
2016/06/27 20:43:21
It is left unchanged if the return value is 0 (no
Mircea Trofin
2016/06/27 20:49:20
Should we have the DCHECK right after the call to
bbudge
2016/06/27 21:08:01
Good idea, I've added a DCHECK at all GetAliases c
|
| + while (aliases--) { |
| + if (Contains(set, loc, other_rep1, base + aliases)) return true; |
| + } |
| + aliases = config->GetAliases(rep, loc.register_code(), other_rep2, &base); |
| while (aliases--) { |
| - int aliased_reg = alias_base_index + aliases; |
| - if (set.find(LocationOperand(loc.kind(), loc.location_kind(), other_fp_rep, |
| - aliased_reg)) != set.end()) |
| - return true; |
| + if (Contains(set, loc, other_rep2, base + aliases)) return true; |
| } |
| return false; |
| } |