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
This commit is contained in:
verwaest@chromium.org 2013-06-03 16:57:36 +00:00
parent 99dfe8753a
commit 179ac2cd0c
4 changed files with 35 additions and 106 deletions

View File

@ -124,20 +124,9 @@ void HValue::UpdateRepresentation(Representation new_rep,
const char* reason) { const char* reason) {
Representation r = representation(); Representation r = representation();
if (new_rep.is_more_general_than(r)) { if (new_rep.is_more_general_than(r)) {
// When an HConstant is marked "not convertible to integer", then if (FLAG_trace_representation) {
// never try to represent it as an integer. PrintF("Changing #%d %s representation %s -> %s based on %s\n",
if (new_rep.IsInteger32() && !IsConvertibleToInteger()) { id(), Mnemonic(), r.Mnemonic(), new_rep.Mnemonic(), reason);
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);
}
} }
ChangeRepresentation(new_rep); ChangeRepresentation(new_rep);
AddDependantsToWorklist(h_infer); AddDependantsToWorklist(h_infer);
@ -1926,7 +1915,6 @@ void HPhi::PrintTo(StringStream* stream) {
int32_non_phi_uses() + int32_indirect_uses(), int32_non_phi_uses() + int32_indirect_uses(),
double_non_phi_uses() + double_indirect_uses(), double_non_phi_uses() + double_indirect_uses(),
tagged_non_phi_uses() + tagged_indirect_uses()); tagged_non_phi_uses() + tagged_indirect_uses());
if (!IsConvertibleToInteger()) stream->Add("_ncti");
PrintRangeTo(stream); PrintRangeTo(stream);
PrintTypeTo(stream); PrintTypeTo(stream);
stream->Add("]"); stream->Add("]");
@ -3565,48 +3553,11 @@ void HPhi::InferRepresentation(HInferRepresentation* h_infer) {
Representation HPhi::RepresentationFromInputs() { Representation HPhi::RepresentationFromInputs() {
bool double_occurred = false; Representation r = Representation::None();
bool int32_occurred = false;
bool smi_occurred = false;
for (int i = 0; i < OperandCount(); ++i) { for (int i = 0; i < OperandCount(); ++i) {
HValue* value = OperandAt(i); r = r.generalize(OperandAt(i)->KnownOptimalRepresentation());
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();
}
}
}
} }
return r;
if (double_occurred) return Representation::Double();
if (int32_occurred) return Representation::Integer32();
if (smi_occurred) return Representation::Smi();
return Representation::None();
} }

View File

@ -885,7 +885,17 @@ class HValue: public ZoneObject {
} }
virtual void AssumeRepresentation(Representation r); 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_; } HType type() const { return type_; }
void set_type(HType new_type) { void set_type(HType new_type) {
@ -2449,7 +2459,7 @@ class HMapEnumLength: public HUnaryOperation {
public: public:
explicit HMapEnumLength(HValue* value) : HUnaryOperation(value) { explicit HMapEnumLength(HValue* value) : HUnaryOperation(value) {
set_type(HType::Smi()); set_type(HType::Smi());
set_representation(Representation::Tagged()); set_representation(Representation::Smi());
SetFlag(kUseGVN); SetFlag(kUseGVN);
SetGVNFlag(kDependsOnMaps); SetGVNFlag(kDependsOnMaps);
} }
@ -2940,8 +2950,7 @@ class HPhi: public HValue {
HPhi(int merged_index, Zone* zone) HPhi(int merged_index, Zone* zone)
: inputs_(2, zone), : inputs_(2, zone),
merged_index_(merged_index), merged_index_(merged_index),
phi_id_(-1), phi_id_(-1) {
is_convertible_to_integer_(true) {
for (int i = 0; i < Representation::kNumRepresentations; i++) { for (int i = 0; i < Representation::kNumRepresentations; i++) {
non_phi_uses_[i] = 0; non_phi_uses_[i] = 0;
indirect_uses_[i] = 0; indirect_uses_[i] = 0;
@ -2959,6 +2968,9 @@ class HPhi: public HValue {
virtual Representation RequiredInputRepresentation(int index) { virtual Representation RequiredInputRepresentation(int index) {
return representation(); return representation();
} }
virtual Representation KnownOptimalRepresentation() {
return representation();
}
virtual HType CalculateInferredType(); virtual HType CalculateInferredType();
virtual int OperandCount() { return inputs_.length(); } virtual int OperandCount() { return inputs_.length(); }
virtual HValue* OperandAt(int index) const { return inputs_[index]; } 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 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(); void SimplifyConstantInputs();
// TODO(titzer): we can't eliminate the receiver for generating backtraces // 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 non_phi_uses_[Representation::kNumRepresentations];
int indirect_uses_[Representation::kNumRepresentations]; int indirect_uses_[Representation::kNumRepresentations];
int phi_id_; int phi_id_;
bool is_convertible_to_integer_;
}; };
@ -3196,8 +3185,11 @@ class HConstant: public HTemplateInstruction<0> {
return Representation::None(); return Representation::None();
} }
virtual bool IsConvertibleToInteger() const { virtual Representation KnownOptimalRepresentation() {
return has_int32_value_; if (HasSmiValue()) return Representation::Smi();
if (HasInteger32Value()) return Representation::Integer32();
if (HasNumberValue()) return Representation::Double();
return Representation::Tagged();
} }
virtual bool EmitAtUses() { return !representation().IsDouble(); } virtual bool EmitAtUses() { return !representation().IsDouble(); }
@ -3211,9 +3203,7 @@ class HConstant: public HTemplateInstruction<0> {
ASSERT(HasInteger32Value()); ASSERT(HasInteger32Value());
return int32_value_; return int32_value_;
} }
bool HasSmiValue() const { bool HasSmiValue() const { return has_smi_value_; }
return has_smi_value_;
}
bool HasDoubleValue() const { return has_double_value_; } bool HasDoubleValue() const { return has_double_value_; }
double DoubleValue() const { double DoubleValue() const {
ASSERT(HasDoubleValue()); ASSERT(HasDoubleValue());
@ -4716,6 +4706,11 @@ class HUnknownOSRValue: public HTemplateInstruction<0> {
return incoming_value_; return incoming_value_;
} }
virtual Representation KnownOptimalRepresentation() {
if (incoming_value_ == NULL) return Representation::None();
return incoming_value_->KnownOptimalRepresentation();
}
DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue) DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
private: private:

View File

@ -2879,23 +2879,6 @@ void HInferRepresentation::Analyze() {
phi_list->at(i)->SimplifyConstantInputs(); 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 // Use the phi reachability information from step 2 to
// sum up the non-phi use counts of all connected phis. // sum up the non-phi use counts of all connected phis.
for (int i = 0; i < phi_count; ++i) { for (int i = 0; i < phi_count; ++i) {

View File

@ -1057,7 +1057,7 @@ void LAllocator::ResolvePhis(HBasicBlock* block) {
LInstruction* branch = LInstruction* branch =
InstructionAt(cur_block->last_instruction_index()); InstructionAt(cur_block->last_instruction_index());
if (branch->HasPointerMap()) { if (branch->HasPointerMap()) {
if (phi->representation().IsSmiOrTagged()) { if (phi->representation().IsTagged() && !phi->type().IsSmi()) {
branch->pointer_map()->RecordPointer(phi_operand, zone()); branch->pointer_map()->RecordPointer(phi_operand, zone());
} else if (!phi->representation().IsDouble()) { } else if (!phi->representation().IsDouble()) {
branch->pointer_map()->RecordUntagged(phi_operand, zone()); branch->pointer_map()->RecordUntagged(phi_operand, zone());
@ -1640,7 +1640,7 @@ void LAllocator::TraceAlloc(const char* msg, ...) {
bool LAllocator::HasTaggedValue(int virtual_register) const { bool LAllocator::HasTaggedValue(int virtual_register) const {
HValue* value = graph_->LookupValue(virtual_register); HValue* value = graph_->LookupValue(virtual_register);
if (value == NULL) return false; if (value == NULL) return false;
return value->representation().IsSmiOrTagged(); return value->representation().IsTagged() && !value->type().IsSmi();
} }