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:
parent
99dfe8753a
commit
179ac2cd0c
@ -124,21 +124,10 @@ 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
|
|
||||||
// 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) {
|
if (FLAG_trace_representation) {
|
||||||
PrintF("Changing #%d %s representation %s -> %s based on %s\n",
|
PrintF("Changing #%d %s representation %s -> %s based on %s\n",
|
||||||
id(), Mnemonic(), r.Mnemonic(), new_rep.Mnemonic(), reason);
|
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;
|
return r;
|
||||||
}
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (double_occurred) return Representation::Double();
|
|
||||||
if (int32_occurred) return Representation::Integer32();
|
|
||||||
if (smi_occurred) return Representation::Smi();
|
|
||||||
|
|
||||||
return Representation::None();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
@ -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) {
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user