Commit 4b76dc85 authored by bbudge's avatar bbudge Committed by Commit bot

[Turbofan] Simplify operand canonicalization on archs with simple FP aliasing.

- Changes InstructionOperand canonicalization to map all FP operands to kFloat64 on Intel and other platforms with simple aliasing.
- Bypass expensive interference calculations and fixed FP live range processing for platforms with simple aliasing.

LOG=N
BUG=v8:4124

Review-Url: https://codereview.chromium.org/2101653003
Cr-Commit-Position: refs/heads/master@{#37388}
parent c4588df1
...@@ -61,16 +61,14 @@ FlagsCondition CommuteFlagsCondition(FlagsCondition condition) { ...@@ -61,16 +61,14 @@ FlagsCondition CommuteFlagsCondition(FlagsCondition condition) {
} }
bool InstructionOperand::InterferesWith(const InstructionOperand& that) const { bool InstructionOperand::InterferesWith(const InstructionOperand& that) const {
if (!IsFPRegister() || !that.IsFPRegister()) return EqualsCanonicalized(that); if (!IsFPRegister() || !that.IsFPRegister() || kSimpleFPAliasing)
return EqualsCanonicalized(that);
// Both operands are fp registers and aliasing is non-simple.
const LocationOperand& loc1 = *LocationOperand::cast(this); const LocationOperand& loc1 = *LocationOperand::cast(this);
const LocationOperand& loc2 = LocationOperand::cast(that); const LocationOperand& loc2 = LocationOperand::cast(that);
const RegisterConfiguration* config = GetRegConfig(); return GetRegConfig()->AreAliases(loc1.representation(), loc1.register_code(),
if (config->fp_aliasing_kind() != RegisterConfiguration::COMBINE) loc2.representation(),
return loc1.register_code() == loc2.register_code(); loc2.register_code());
return config->AreAliases(loc1.representation(), loc1.register_code(),
loc2.representation(), loc2.register_code());
} }
void InstructionOperand::Print(const RegisterConfiguration* config) const { void InstructionOperand::Print(const RegisterConfiguration* config) const {
......
...@@ -606,10 +606,17 @@ bool InstructionOperand::IsSimd128StackSlot() const { ...@@ -606,10 +606,17 @@ bool InstructionOperand::IsSimd128StackSlot() const {
uint64_t InstructionOperand::GetCanonicalizedValue() const { uint64_t InstructionOperand::GetCanonicalizedValue() const {
if (IsAllocated() || IsExplicit()) { if (IsAllocated() || IsExplicit()) {
MachineRepresentation rep = LocationOperand::cast(this)->representation(); MachineRepresentation rep = LocationOperand::cast(this)->representation();
// Preserve FP representation so we can check for interference on MachineRepresentation canonical = MachineRepresentation::kNone;
// architectures with complex register aliasing. if (IsFloatingPoint(rep)) {
MachineRepresentation canonical = if (kSimpleFPAliasing) {
IsFPRegister() ? rep : MachineRepresentation::kNone; // Archs with simple aliasing can treat all FP operands the same.
canonical = MachineRepresentation::kFloat64;
} else {
// We need to distinguish FP operands of different reps when FP
// aliasing is not simple (e.g. ARM).
canonical = rep;
}
}
return InstructionOperand::KindField::update( return InstructionOperand::KindField::update(
LocationOperand::RepresentationField::update(this->value_, canonical), LocationOperand::RepresentationField::update(this->value_, canonical),
LocationOperand::EXPLICIT); LocationOperand::EXPLICIT);
...@@ -617,7 +624,6 @@ uint64_t InstructionOperand::GetCanonicalizedValue() const { ...@@ -617,7 +624,6 @@ uint64_t InstructionOperand::GetCanonicalizedValue() const {
return this->value_; return this->value_;
} }
// Required for maps that don't care about machine type. // Required for maps that don't care about machine type.
struct CompareOperandModuloType { struct CompareOperandModuloType {
bool operator()(const InstructionOperand& a, bool operator()(const InstructionOperand& a,
......
...@@ -29,8 +29,8 @@ typedef ZoneSet<InstructionOperand, CompareOperandModuloType> OperandSet; ...@@ -29,8 +29,8 @@ typedef ZoneSet<InstructionOperand, CompareOperandModuloType> OperandSet;
bool Blocks(const OperandSet& set, const InstructionOperand& operand) { bool Blocks(const OperandSet& set, const InstructionOperand& operand) {
if (set.find(operand) != set.end()) return true; if (set.find(operand) != set.end()) return true;
// Only FP registers alias. // Only FP registers on archs with non-simple aliasing need extra checks.
if (!operand.IsFPRegister()) return false; if (!operand.IsFPRegister() || kSimpleFPAliasing) return false;
const LocationOperand& loc = LocationOperand::cast(operand); const LocationOperand& loc = LocationOperand::cast(operand);
MachineRepresentation rep = loc.representation(); MachineRepresentation rep = loc.representation();
......
...@@ -2070,14 +2070,17 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block, ...@@ -2070,14 +2070,17 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block,
allocation_zone()); allocation_zone());
} }
} }
for (int i = 0; i < config()->num_allocatable_float_registers(); ++i) { // Preserve fixed float registers on archs with non-simple aliasing.
int code = config()->GetAllocatableFloatCode(i); if (!kSimpleFPAliasing) {
if (!IsOutputFPRegisterOf(instr, MachineRepresentation::kFloat32, for (int i = 0; i < config()->num_allocatable_float_registers(); ++i) {
code)) { int code = config()->GetAllocatableFloatCode(i);
TopLevelLiveRange* range = if (!IsOutputFPRegisterOf(instr, MachineRepresentation::kFloat32,
FixedFPLiveRangeFor(code, MachineRepresentation::kFloat32); code)) {
range->AddUseInterval(curr_position, curr_position.End(), TopLevelLiveRange* range =
allocation_zone()); FixedFPLiveRangeFor(code, MachineRepresentation::kFloat32);
range->AddUseInterval(curr_position, curr_position.End(),
allocation_zone());
}
} }
} }
} }
......
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