Commit 70d83fbd authored by bbudge's avatar bbudge Committed by Commit bot

[Turbofan] Make operand canonicalization distinguish between FP types.

Review-Url: https://codereview.chromium.org/2054343002
Cr-Commit-Position: refs/heads/master@{#37013}
parent 2dedf215
...@@ -75,7 +75,7 @@ void GapResolver::PerformMove(ParallelMove* moves, MoveOperands* move) const { ...@@ -75,7 +75,7 @@ void GapResolver::PerformMove(ParallelMove* moves, MoveOperands* move) const {
// This move's source may have changed due to swaps to resolve cycles and so // This move's source may have changed due to swaps to resolve cycles and so
// it may now be the last move in the cycle. If so remove it. // it may now be the last move in the cycle. If so remove it.
InstructionOperand source = move->source(); InstructionOperand source = move->source();
if (source.EqualsCanonicalized(destination)) { if (source.InterferesWith(destination)) {
move->Eliminate(); move->Eliminate();
return; return;
} }
......
...@@ -59,6 +59,11 @@ FlagsCondition CommuteFlagsCondition(FlagsCondition condition) { ...@@ -59,6 +59,11 @@ FlagsCondition CommuteFlagsCondition(FlagsCondition condition) {
return condition; return condition;
} }
bool InstructionOperand::InterferesWith(const InstructionOperand& that) const {
if (!IsFPRegister() || !that.IsFPRegister()) return EqualsCanonicalized(that);
return LocationOperand::cast(this)->register_code() ==
LocationOperand::cast(that).register_code();
}
void InstructionOperand::Print(const RegisterConfiguration* config) const { void InstructionOperand::Print(const RegisterConfiguration* config) const {
OFStream os(stdout); OFStream os(stdout);
...@@ -75,7 +80,6 @@ void InstructionOperand::Print() const { ...@@ -75,7 +80,6 @@ void InstructionOperand::Print() const {
Print(config); Print(config);
} }
std::ostream& operator<<(std::ostream& os, std::ostream& operator<<(std::ostream& os,
const PrintableInstructionOperand& printable) { const PrintableInstructionOperand& printable) {
const InstructionOperand& op = printable.op_; const InstructionOperand& op = printable.op_;
...@@ -181,7 +185,6 @@ std::ostream& operator<<(std::ostream& os, ...@@ -181,7 +185,6 @@ std::ostream& operator<<(std::ostream& os,
return os; return os;
} }
void MoveOperands::Print(const RegisterConfiguration* config) const { void MoveOperands::Print(const RegisterConfiguration* config) const {
OFStream os(stdout); OFStream os(stdout);
PrintableInstructionOperand wrapper; PrintableInstructionOperand wrapper;
......
...@@ -103,6 +103,8 @@ class InstructionOperand { ...@@ -103,6 +103,8 @@ class InstructionOperand {
return this->GetCanonicalizedValue() < that.GetCanonicalizedValue(); return this->GetCanonicalizedValue() < that.GetCanonicalizedValue();
} }
bool InterferesWith(const InstructionOperand& that) const;
void Print(const RegisterConfiguration* config) const; void Print(const RegisterConfiguration* config) const;
void Print() const; void Print() const;
...@@ -602,14 +604,13 @@ bool InstructionOperand::IsSimd128StackSlot() const { ...@@ -602,14 +604,13 @@ bool InstructionOperand::IsSimd128StackSlot() const {
uint64_t InstructionOperand::GetCanonicalizedValue() const { uint64_t InstructionOperand::GetCanonicalizedValue() const {
if (IsAllocated() || IsExplicit()) { if (IsAllocated() || IsExplicit()) {
// TODO(dcarney): put machine type last and mask. MachineRepresentation rep = LocationOperand::cast(this)->representation();
MachineRepresentation canonicalized_representation = // Preserve FP representation so we can check for interference on
IsFloatingPoint(LocationOperand::cast(this)->representation()) // architectures with complex register aliasing.
? MachineRepresentation::kFloat64 MachineRepresentation canonical =
: MachineRepresentation::kNone; IsFPRegister() ? rep : MachineRepresentation::kNone;
return InstructionOperand::KindField::update( return InstructionOperand::KindField::update(
LocationOperand::RepresentationField::update( LocationOperand::RepresentationField::update(this->value_, canonical),
this->value_, canonicalized_representation),
LocationOperand::EXPLICIT); LocationOperand::EXPLICIT);
} }
return this->value_; return this->value_;
...@@ -650,9 +651,9 @@ class MoveOperands final : public ZoneObject { ...@@ -650,9 +651,9 @@ class MoveOperands final : public ZoneObject {
} }
void SetPending() { destination_ = InstructionOperand(); } void SetPending() { destination_ = InstructionOperand(); }
// True if this move a move into the given destination operand. // True if this move is a move into the given destination operand.
bool Blocks(const InstructionOperand& operand) const { bool Blocks(const InstructionOperand& destination) const {
return !IsEliminated() && source().EqualsCanonicalized(operand); return !IsEliminated() && source().InterferesWith(destination);
} }
// A move is redundant if it's been eliminated or if its source and // A move is redundant if it's been eliminated or if its source and
......
...@@ -27,6 +27,22 @@ struct MoveKeyCompare { ...@@ -27,6 +27,22 @@ struct MoveKeyCompare {
typedef ZoneMap<MoveKey, unsigned, MoveKeyCompare> MoveMap; typedef ZoneMap<MoveKey, unsigned, MoveKeyCompare> MoveMap;
typedef ZoneSet<InstructionOperand, CompareOperandModuloType> OperandSet; typedef ZoneSet<InstructionOperand, CompareOperandModuloType> OperandSet;
bool Blocks(const OperandSet& set, const InstructionOperand& operand) {
if (!operand.IsFPRegister()) return set.find(operand) != set.end();
const LocationOperand& loc = LocationOperand::cast(operand);
if (loc.representation() == MachineRepresentation::kFloat64) {
return set.find(operand) != set.end() ||
set.find(LocationOperand(loc.kind(), loc.location_kind(),
MachineRepresentation::kFloat32,
loc.register_code())) != set.end();
}
DCHECK_EQ(MachineRepresentation::kFloat32, loc.representation());
return set.find(operand) != set.end() ||
set.find(LocationOperand(loc.kind(), loc.location_kind(),
MachineRepresentation::kFloat64,
loc.register_code())) != set.end();
}
int FindFirstNonEmptySlot(const Instruction* instr) { int FindFirstNonEmptySlot(const Instruction* instr) {
int i = Instruction::FIRST_GAP_POSITION; int i = Instruction::FIRST_GAP_POSITION;
...@@ -165,7 +181,7 @@ void MoveOptimizer::MigrateMoves(Instruction* to, Instruction* from) { ...@@ -165,7 +181,7 @@ void MoveOptimizer::MigrateMoves(Instruction* to, Instruction* from) {
// destination operands are eligible for being moved down. // destination operands are eligible for being moved down.
for (MoveOperands* move : *from_moves) { for (MoveOperands* move : *from_moves) {
if (move->IsRedundant()) continue; if (move->IsRedundant()) continue;
if (dst_cant_be.find(move->destination()) == dst_cant_be.end()) { if (!Blocks(dst_cant_be, move->destination())) {
MoveKey key = {move->source(), move->destination()}; MoveKey key = {move->source(), move->destination()};
move_candidates.insert(key); move_candidates.insert(key);
} }
...@@ -180,7 +196,7 @@ void MoveOptimizer::MigrateMoves(Instruction* to, Instruction* from) { ...@@ -180,7 +196,7 @@ void MoveOptimizer::MigrateMoves(Instruction* to, Instruction* from) {
auto current = iter; auto current = iter;
++iter; ++iter;
InstructionOperand src = current->source; InstructionOperand src = current->source;
if (src_cant_be.find(src) != src_cant_be.end()) { if (Blocks(src_cant_be, src)) {
src_cant_be.insert(current->destination); src_cant_be.insert(current->destination);
move_candidates.erase(current); move_candidates.erase(current);
changed = true; changed = true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment