From 179ac2cd0c49fdfc677cd72d4ac1b598b264c2f0 Mon Sep 17 00:00:00 2001 From: "verwaest@chromium.org" Date: Mon, 3 Jun 2013 16:57:36 +0000 Subject: [PATCH] Improve smi support in crankshaft - Recover smi in phis if inputs are smi-typed - Don't record smi-typed values as pointers BUG= R=jkummerow@chromium.org Review URL: https://chromiumcodereview.appspot.com/16240003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14926 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/hydrogen-instructions.cc | 61 ++++-------------------------------- src/hydrogen-instructions.h | 59 ++++++++++++++++------------------ src/hydrogen.cc | 17 ---------- src/lithium-allocator.cc | 4 +-- 4 files changed, 35 insertions(+), 106 deletions(-) diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index d4938e5c38..ef3f1cdce0 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -124,20 +124,9 @@ void HValue::UpdateRepresentation(Representation new_rep, const char* reason) { Representation r = representation(); if (new_rep.is_more_general_than(r)) { - // When an HConstant is marked "not convertible to integer", then - // never try to represent it as an integer. - if (new_rep.IsInteger32() && !IsConvertibleToInteger()) { - new_rep = Representation::Tagged(); - if (FLAG_trace_representation) { - PrintF("Changing #%d %s representation %s -> %s because it's NCTI" - " (%s want i)\n", - id(), Mnemonic(), r.Mnemonic(), new_rep.Mnemonic(), reason); - } - } else { - if (FLAG_trace_representation) { - PrintF("Changing #%d %s representation %s -> %s based on %s\n", - id(), Mnemonic(), r.Mnemonic(), new_rep.Mnemonic(), reason); - } + if (FLAG_trace_representation) { + PrintF("Changing #%d %s representation %s -> %s based on %s\n", + id(), Mnemonic(), r.Mnemonic(), new_rep.Mnemonic(), reason); } ChangeRepresentation(new_rep); AddDependantsToWorklist(h_infer); @@ -1926,7 +1915,6 @@ void HPhi::PrintTo(StringStream* stream) { int32_non_phi_uses() + int32_indirect_uses(), double_non_phi_uses() + double_indirect_uses(), tagged_non_phi_uses() + tagged_indirect_uses()); - if (!IsConvertibleToInteger()) stream->Add("_ncti"); PrintRangeTo(stream); PrintTypeTo(stream); stream->Add("]"); @@ -3565,48 +3553,11 @@ void HPhi::InferRepresentation(HInferRepresentation* h_infer) { Representation HPhi::RepresentationFromInputs() { - bool double_occurred = false; - bool int32_occurred = false; - bool smi_occurred = false; + Representation r = Representation::None(); for (int i = 0; i < OperandCount(); ++i) { - HValue* value = OperandAt(i); - if (value->IsUnknownOSRValue()) { - HPhi* hint_value = HUnknownOSRValue::cast(value)->incoming_value(); - if (hint_value != NULL) { - Representation hint = hint_value->representation(); - if (hint.IsTagged()) return hint; - if (hint.IsDouble()) double_occurred = true; - if (hint.IsInteger32()) int32_occurred = true; - if (hint.IsSmi()) smi_occurred = true; - } - continue; - } - if (value->representation().IsDouble()) double_occurred = true; - if (value->representation().IsInteger32()) int32_occurred = true; - if (value->representation().IsSmi()) smi_occurred = true; - if (value->representation().IsTagged()) { - if (value->IsConstant()) { - HConstant* constant = HConstant::cast(value); - if (constant->IsConvertibleToInteger()) { - int32_occurred = true; - } else if (constant->HasNumberValue()) { - double_occurred = true; - } else { - return Representation::Tagged(); - } - } else { - if (value->IsPhi() && !IsConvertibleToInteger()) { - return Representation::Tagged(); - } - } - } + r = r.generalize(OperandAt(i)->KnownOptimalRepresentation()); } - - if (double_occurred) return Representation::Double(); - if (int32_occurred) return Representation::Integer32(); - if (smi_occurred) return Representation::Smi(); - - return Representation::None(); + return r; } diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index cd5b271206..e464ac45ea 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -885,7 +885,17 @@ class HValue: public ZoneObject { } virtual void AssumeRepresentation(Representation r); - virtual bool IsConvertibleToInteger() const { return true; } + virtual Representation KnownOptimalRepresentation() { + Representation r = representation(); + if (r.IsTagged()) { + HType t = type(); + if (t.IsSmi()) return Representation::Smi(); + if (t.IsHeapNumber()) return Representation::Double(); + if (t.IsHeapObject()) return r; + return Representation::None(); + } + return r; + } HType type() const { return type_; } void set_type(HType new_type) { @@ -2449,7 +2459,7 @@ class HMapEnumLength: public HUnaryOperation { public: explicit HMapEnumLength(HValue* value) : HUnaryOperation(value) { set_type(HType::Smi()); - set_representation(Representation::Tagged()); + set_representation(Representation::Smi()); SetFlag(kUseGVN); SetGVNFlag(kDependsOnMaps); } @@ -2940,8 +2950,7 @@ class HPhi: public HValue { HPhi(int merged_index, Zone* zone) : inputs_(2, zone), merged_index_(merged_index), - phi_id_(-1), - is_convertible_to_integer_(true) { + phi_id_(-1) { for (int i = 0; i < Representation::kNumRepresentations; i++) { non_phi_uses_[i] = 0; indirect_uses_[i] = 0; @@ -2959,6 +2968,9 @@ class HPhi: public HValue { virtual Representation RequiredInputRepresentation(int index) { return representation(); } + virtual Representation KnownOptimalRepresentation() { + return representation(); + } virtual HType CalculateInferredType(); virtual int OperandCount() { return inputs_.length(); } virtual HValue* OperandAt(int index) const { return inputs_[index]; } @@ -3014,28 +3026,6 @@ class HPhi: public HValue { } virtual Opcode opcode() const { return HValue::kPhi; } - virtual bool IsConvertibleToInteger() const { - return is_convertible_to_integer_; - } - - void set_is_convertible_to_integer(bool b) { - is_convertible_to_integer_ = b; - } - - bool AllOperandsConvertibleToInteger() { - for (int i = 0; i < OperandCount(); ++i) { - if (!OperandAt(i)->IsConvertibleToInteger()) { - if (FLAG_trace_representation) { - HValue* input = OperandAt(i); - PrintF("#%d %s: Input #%d %s at %d is NCTI\n", - id(), Mnemonic(), input->id(), input->Mnemonic(), i); - } - return false; - } - } - return true; - } - void SimplifyConstantInputs(); // TODO(titzer): we can't eliminate the receiver for generating backtraces @@ -3059,7 +3049,6 @@ class HPhi: public HValue { int non_phi_uses_[Representation::kNumRepresentations]; int indirect_uses_[Representation::kNumRepresentations]; int phi_id_; - bool is_convertible_to_integer_; }; @@ -3196,8 +3185,11 @@ class HConstant: public HTemplateInstruction<0> { return Representation::None(); } - virtual bool IsConvertibleToInteger() const { - return has_int32_value_; + virtual Representation KnownOptimalRepresentation() { + if (HasSmiValue()) return Representation::Smi(); + if (HasInteger32Value()) return Representation::Integer32(); + if (HasNumberValue()) return Representation::Double(); + return Representation::Tagged(); } virtual bool EmitAtUses() { return !representation().IsDouble(); } @@ -3211,9 +3203,7 @@ class HConstant: public HTemplateInstruction<0> { ASSERT(HasInteger32Value()); return int32_value_; } - bool HasSmiValue() const { - return has_smi_value_; - } + bool HasSmiValue() const { return has_smi_value_; } bool HasDoubleValue() const { return has_double_value_; } double DoubleValue() const { ASSERT(HasDoubleValue()); @@ -4716,6 +4706,11 @@ class HUnknownOSRValue: public HTemplateInstruction<0> { return incoming_value_; } + virtual Representation KnownOptimalRepresentation() { + if (incoming_value_ == NULL) return Representation::None(); + return incoming_value_->KnownOptimalRepresentation(); + } + DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue) private: diff --git a/src/hydrogen.cc b/src/hydrogen.cc index f543d4e690..b166e138c1 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -2879,23 +2879,6 @@ void HInferRepresentation::Analyze() { phi_list->at(i)->SimplifyConstantInputs(); } - // Use the phi reachability information from step 2 to - // push information about values which can't be converted to integer - // without deoptimization through the phi use-def chains, avoiding - // unnecessary deoptimizations later. - for (int i = 0; i < phi_count; ++i) { - HPhi* phi = phi_list->at(i); - bool cti = phi->AllOperandsConvertibleToInteger(); - if (cti) continue; - - for (BitVector::Iterator it(connected_phis.at(i)); - !it.Done(); - it.Advance()) { - HPhi* phi = phi_list->at(it.Current()); - phi->set_is_convertible_to_integer(false); - } - } - // Use the phi reachability information from step 2 to // sum up the non-phi use counts of all connected phis. for (int i = 0; i < phi_count; ++i) { diff --git a/src/lithium-allocator.cc b/src/lithium-allocator.cc index 04113e170d..9defc5e29c 100644 --- a/src/lithium-allocator.cc +++ b/src/lithium-allocator.cc @@ -1057,7 +1057,7 @@ void LAllocator::ResolvePhis(HBasicBlock* block) { LInstruction* branch = InstructionAt(cur_block->last_instruction_index()); if (branch->HasPointerMap()) { - if (phi->representation().IsSmiOrTagged()) { + if (phi->representation().IsTagged() && !phi->type().IsSmi()) { branch->pointer_map()->RecordPointer(phi_operand, zone()); } else if (!phi->representation().IsDouble()) { branch->pointer_map()->RecordUntagged(phi_operand, zone()); @@ -1640,7 +1640,7 @@ void LAllocator::TraceAlloc(const char* msg, ...) { bool LAllocator::HasTaggedValue(int virtual_register) const { HValue* value = graph_->LookupValue(virtual_register); if (value == NULL) return false; - return value->representation().IsSmiOrTagged(); + return value->representation().IsTagged() && !value->type().IsSmi(); }