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,21 +124,10 @@ 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);
}
}
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;
r = r.generalize(OperandAt(i)->KnownOptimalRepresentation());
}
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();
}
}
}
}
if (double_occurred) return Representation::Double();
if (int32_occurred) return Representation::Integer32();
if (smi_occurred) return Representation::Smi();
return Representation::None();
return r;
}

View File

@ -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:

View File

@ -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) {

View File

@ -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();
}