representation_ = r;
}
+ virtual bool IsConvertibleToInteger() const { return true; }
+
HType type() const { return type_; }
void set_type(HType type) {
ASSERT(HasNoUses());
: inputs_(2),
merged_index_(merged_index),
phi_id_(-1),
- is_live_(false) {
+ is_live_(false),
+ is_convertible_to_integer_(true) {
for (int i = 0; i < Representation::kNumRepresentations; i++) {
non_phi_uses_[i] = 0;
indirect_uses_[i] = 0;
}
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;
+ }
+
protected:
virtual void DeleteFromGraph();
virtual void InternalSetOperandAt(int index, HValue* value) {
int indirect_uses_[Representation::kNumRepresentations];
int phi_id_;
bool is_live_;
+ bool is_convertible_to_integer_;
};
return Representation::None();
}
+ virtual bool IsConvertibleToInteger() const {
+ if (handle_->IsSmi()) return true;
+ if (handle_->IsHeapNumber() &&
+ (HeapNumber::cast(*handle_)->value() ==
+ static_cast<double>(NumberToInt32(*handle_)))) return true;
+ return false;
+ }
+
virtual bool EmitAtUses() { return !representation().IsDouble(); }
virtual void PrintDataTo(StringStream* stream);
virtual HType CalculateInferredType();
}
if (non_tagged_count >= tagged_count) {
- // More untagged than tagged.
- if (double_count > 0) {
- // There is at least one usage that is a double => guess that the
- // correct representation is double.
- return Representation::Double();
- } else if (int32_count > 0) {
- return Representation::Integer32();
+ if (int32_count > 0) {
+ if (!value->IsPhi() || value->IsConvertibleToInteger()) {
+ return Representation::Integer32();
+ }
}
+ if (double_count > 0) return Representation::Double();
}
return Representation::None();
}
// bit-vector of length <number of phis>.
const ZoneList<HPhi*>* phi_list = graph_->phi_list();
int phi_count = phi_list->length();
- ScopedVector<BitVector*> connected_phis(phi_count);
+ ZoneList<BitVector*> connected_phis(phi_count);
for (int i = 0; i < phi_count; ++i) {
phi_list->at(i)->InitRealUses(i);
- connected_phis[i] = new(zone()) BitVector(phi_count);
- connected_phis[i]->Add(i);
+ BitVector* connected_set = new(zone()) BitVector(phi_count);
+ connected_set->Add(i);
+ connected_phis.Add(connected_set);
}
// (2) Do a fixed point iteration to find the set of connected phis. A
}
}
+ // (4) Compute phis that definitely can't be converted to integer
+ // without deoptimization and mark them to avoid unnecessary deoptimization.
+ change = true;
+ while (change) {
+ change = false;
+ for (int i = 0; i < phi_count; ++i) {
+ HPhi* phi = phi_list->at(i);
+ for (int j = 0; j < phi->OperandCount(); ++j) {
+ if (phi->IsConvertibleToInteger() &&
+ !phi->OperandAt(j)->IsConvertibleToInteger()) {
+ phi->set_is_convertible_to_integer(false);
+ change = true;
+ break;
+ }
+ }
+ }
+ }
+
+
for (int i = 0; i < graph_->blocks()->length(); ++i) {
HBasicBlock* block = graph_->blocks()->at(i);
const ZoneList<HPhi*>* phis = block->phis();