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 {
// 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.
InstructionOperand source = move->source();
if (source.EqualsCanonicalized(destination)) {
if (source.InterferesWith(destination)) {
move->Eliminate();
return;
}
......
......@@ -59,6 +59,11 @@ FlagsCondition CommuteFlagsCondition(FlagsCondition 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 {
OFStream os(stdout);
......@@ -75,7 +80,6 @@ void InstructionOperand::Print() const {
Print(config);
}
std::ostream& operator<<(std::ostream& os,
const PrintableInstructionOperand& printable) {
const InstructionOperand& op = printable.op_;
......@@ -181,7 +185,6 @@ std::ostream& operator<<(std::ostream& os,
return os;
}
void MoveOperands::Print(const RegisterConfiguration* config) const {
OFStream os(stdout);
PrintableInstructionOperand wrapper;
......
......@@ -103,6 +103,8 @@ class InstructionOperand {
return this->GetCanonicalizedValue() < that.GetCanonicalizedValue();
}
bool InterferesWith(const InstructionOperand& that) const;
void Print(const RegisterConfiguration* config) const;
void Print() const;
......@@ -602,14 +604,13 @@ bool InstructionOperand::IsSimd128StackSlot() const {
uint64_t InstructionOperand::GetCanonicalizedValue() const {
if (IsAllocated() || IsExplicit()) {
// TODO(dcarney): put machine type last and mask.
MachineRepresentation canonicalized_representation =
IsFloatingPoint(LocationOperand::cast(this)->representation())
? MachineRepresentation::kFloat64
: MachineRepresentation::kNone;
MachineRepresentation rep = LocationOperand::cast(this)->representation();
// Preserve FP representation so we can check for interference on
// architectures with complex register aliasing.
MachineRepresentation canonical =
IsFPRegister() ? rep : MachineRepresentation::kNone;
return InstructionOperand::KindField::update(
LocationOperand::RepresentationField::update(
this->value_, canonicalized_representation),
LocationOperand::RepresentationField::update(this->value_, canonical),
LocationOperand::EXPLICIT);
}
return this->value_;
......@@ -650,9 +651,9 @@ class MoveOperands final : public ZoneObject {
}
void SetPending() { destination_ = InstructionOperand(); }
// True if this move a move into the given destination operand.
bool Blocks(const InstructionOperand& operand) const {
return !IsEliminated() && source().EqualsCanonicalized(operand);
// True if this move is a move into the given destination operand.
bool Blocks(const InstructionOperand& destination) const {
return !IsEliminated() && source().InterferesWith(destination);
}
// A move is redundant if it's been eliminated or if its source and
......
......@@ -27,6 +27,22 @@ struct MoveKeyCompare {
typedef ZoneMap<MoveKey, unsigned, MoveKeyCompare> MoveMap;
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 i = Instruction::FIRST_GAP_POSITION;
......@@ -165,7 +181,7 @@ void MoveOptimizer::MigrateMoves(Instruction* to, Instruction* from) {
// destination operands are eligible for being moved down.
for (MoveOperands* move : *from_moves) {
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()};
move_candidates.insert(key);
}
......@@ -180,7 +196,7 @@ void MoveOptimizer::MigrateMoves(Instruction* to, Instruction* from) {
auto current = iter;
++iter;
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);
move_candidates.erase(current);
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