Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(338)

Unified Diff: runtime/vm/intermediate_language.cc

Issue 504143003: Support Int32 representation for selected binary operations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/intermediate_language.cc
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index fa9a5eda03d338f8a79dce05f1fd3e2c7043a454..ed4036a5a46496334e6e3874079d3ee9f2389df7 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -312,6 +312,15 @@ bool BinarySmiOpInstr::AttributesEqual(Instruction* other) const {
}
+bool BinaryInt32OpInstr::AttributesEqual(Instruction* other) const {
+ BinaryInt32OpInstr* other_op = other->AsBinaryInt32Op();
+ ASSERT(other_op != NULL);
+ return (op_kind() == other_op->op_kind()) &&
+ (overflow_ == other_op->overflow_) &&
+ (is_truncating_ == other_op->is_truncating_);
+}
+
+
EffectSet LoadFieldInstr::Dependencies() const {
return immutable_ ? EffectSet::None() : EffectSet::All();
}
@@ -388,12 +397,16 @@ bool ConstantInstr::AttributesEqual(Instruction* other) const {
}
-UnboxedConstantInstr::UnboxedConstantInstr(const Object& value)
- : ConstantInstr(value), constant_address_(0) {
- // Only doubles supported for now.
- ASSERT(value.IsDouble());
- constant_address_ =
- FlowGraphBuilder::FindDoubleConstant(Double::Cast(value).value());
+UnboxedConstantInstr::UnboxedConstantInstr(const Object& value,
+ Representation representation)
+ : ConstantInstr(value),
+ representation_(representation),
+ constant_address_(0) {
+ if (representation_ == kUnboxedDouble) {
+ ASSERT(value.IsDouble());
+ constant_address_ =
+ FlowGraphBuilder::FindDoubleConstant(Double::Cast(value).value());
+ }
}
@@ -678,7 +691,9 @@ void Value::RemoveFromUseList() {
// True if the definition has a single input use and is used only in
// environments at the same instruction as that input use.
bool Definition::HasOnlyUse(Value* use) const {
- if ((input_use_list() != use) || (use->next_use() != NULL)) return false;
+ if (!HasOnlyInputUse(use)) {
+ return false;
+ }
Instruction* target = use->instruction();
for (Value::Iterator it(env_use_list()); !it.Done(); it.Advance()) {
@@ -688,6 +703,11 @@ bool Definition::HasOnlyUse(Value* use) const {
}
+bool Definition::HasOnlyInputUse(Value* use) const {
+ return (input_use_list() == use) && (use->next_use() == NULL);
+}
+
+
void Definition::ReplaceUsesWith(Definition* other) {
ASSERT(other != NULL);
ASSERT(this != other);
@@ -1149,6 +1169,49 @@ void Instruction::Goto(JoinEntryInstr* entry) {
}
+bool UnboxedIntConverterInstr::CanDeoptimize() const {
+ return (to() == kUnboxedInt32) &&
+ !Range::Fits(value()->definition()->range(),
+ RangeBoundary::kRangeBoundaryInt32);
+}
+
+
+bool UnboxInt32Instr::CanDeoptimize() const {
+ const intptr_t value_cid = value()->Type()->ToCid();
+ if (value_cid == kSmiCid) {
+ return false;
+ } else if (value_cid == kMintCid) {
+ return !Range::Fits(value()->definition()->range(),
+ RangeBoundary::kRangeBoundaryInt32);
+ } else {
+ return true;
+ }
+}
+
+
+bool BinaryInt32OpInstr::CanDeoptimize() const {
+ switch (op_kind()) {
+ case Token::kBIT_AND:
+ case Token::kBIT_OR:
+ case Token::kBIT_XOR:
+ return false;
+
+ case Token::kSHR:
+ return false;
+
+ case Token::kSHL:
+ return true;
+
+ case Token::kMOD: {
+ UNREACHABLE();
+ }
+
+ default:
+ return overflow_;
+ }
+}
+
+
bool BinarySmiOpInstr::CanDeoptimize() const {
if (FLAG_throw_on_javascript_int_overflow && (Smi::kBits > 32)) {
// If Smi's are bigger than 32-bits, then the instruction could deoptimize
@@ -1425,6 +1488,29 @@ Definition* BinaryUint32OpInstr::Canonicalize(FlowGraph* flow_graph) {
}
+Definition* BinaryInt32OpInstr::Canonicalize(FlowGraph* flow_graph) {
+ Definition* result = NULL;
+
+ result = CanonicalizeCommutativeArithmetic(op_kind(),
+ kSmiCid,
+ left(),
+ right());
+ if (result != NULL) {
+ return result;
+ }
+
+ result = CanonicalizeCommutativeArithmetic(op_kind(),
+ kSmiCid,
+ right(),
+ left());
+ if (result != NULL) {
+ return result;
+ }
+
+ return this;
+}
+
+
// Optimizations that eliminate or simplify individual instructions.
Instruction* Instruction::Canonicalize(FlowGraph* flow_graph) {
return this;
@@ -1623,6 +1709,103 @@ Definition* BoxDoubleInstr::Canonicalize(FlowGraph* flow_graph) {
}
+bool BoxIntNInstr::ValueFitsSmi() const {
+ Range* range = value()->definition()->range();
+ return Range::Fits(range, RangeBoundary::kRangeBoundarySmi);
+}
+
+
+Definition* BoxIntNInstr::Canonicalize(FlowGraph* flow_graph) {
+ if ((input_use_list() == NULL) && !HasTryBlockUse(env_use_list())) {
+ // Environments can accomodate any representation. No need to box.
+ return value()->definition();
+ }
+
+ return this;
+}
+
+
+Definition* UnboxIntNInstr::Canonicalize(FlowGraph* flow_graph) {
+ if (!HasUses()) return NULL;
+
+ // Fold away UnboxInt<N>Instr(BoxInt<N>Instr(v)).
+ BoxIntNInstr* box_defn = value()->definition()->AsBoxIntN();
+ if (box_defn != NULL) {
+ if (box_defn->value()->definition()->representation() == representation()) {
+ return box_defn->value()->definition();
+ } else {
+ UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr(
+ box_defn->value()->definition()->representation(),
+ representation(),
+ box_defn->value()->CopyWithType(),
+ representation() == kUnboxedInt32 ? deopt_id_ : Isolate::kNoDeoptId);
+ flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue);
+ return converter;
+ }
+ }
+
+ return this;
+}
+
+
+Definition* UnboxedIntConverterInstr::Canonicalize(FlowGraph* flow_graph) {
+ if (!HasUses()) return NULL;
+
+ UnboxedIntConverterInstr* box_defn =
+ value()->definition()->AsUnboxedIntConverter();
+ if ((box_defn != NULL) && (box_defn->representation() == from())) {
+ if (box_defn->from() == to()) {
+ return box_defn->value()->definition();
+ }
+
+ UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr(
+ box_defn->from(),
+ representation(),
+ box_defn->value()->CopyWithType(),
+ to() == kUnboxedInt32 ? deopt_id_ : NULL);
+ flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue);
+ return converter;
+ }
+
+ UnboxIntegerInstr* unbox_defn = value()->definition()->AsUnboxInteger();
+ if (unbox_defn != NULL &&
+ (from() == kUnboxedMint) &&
+ (to() == kUnboxedInt32) &&
+ unbox_defn->HasOnlyInputUse(value())) {
+ // TODO(vegorov): there is a duplication of code between UnboxedIntCoverter
+ // and code path that unboxes Mint into Int32. We should just schedule
+ // these instructions close to each other instead of fusing them.
+ Definition* replacement =
+ new UnboxInt32Instr(unbox_defn->value()->CopyWithType(), deopt_id_);
+ flow_graph->InsertBefore(this,
+ replacement,
+ env(),
+ FlowGraph::kValue);
+ return replacement;
+ }
+
+ return this;
+}
+
+
+Definition* UnboxInt32Instr::Canonicalize(FlowGraph* flow_graph) {
+ Definition* replacement = UnboxIntNInstr::Canonicalize(flow_graph);
+ if (replacement != this) {
+ return replacement;
+ }
+
+ ConstantInstr* c = value()->definition()->AsConstant();
+ if ((c != NULL) && c->value().IsSmi()) {
+ UnboxedConstantInstr* uc =
+ new UnboxedConstantInstr(c->value(), kUnboxedInt32);
+ flow_graph->InsertBefore(this, uc, NULL, FlowGraph::kValue);
+ return uc;
+ }
+
+ return this;
+}
+
+
Definition* UnboxDoubleInstr::Canonicalize(FlowGraph* flow_graph) {
if (!HasUses()) return NULL;
// Fold away UnboxDouble(BoxDouble(v)).
@@ -1633,7 +1816,8 @@ Definition* UnboxDoubleInstr::Canonicalize(FlowGraph* flow_graph) {
ConstantInstr* c = value()->definition()->AsConstant();
if ((c != NULL) && c->value().IsDouble()) {
- UnboxedConstantInstr* uc = new UnboxedConstantInstr(c->value());
+ UnboxedConstantInstr* uc =
+ new UnboxedConstantInstr(c->value(), kUnboxedDouble);
flow_graph->InsertBefore(this, uc, NULL, FlowGraph::kValue);
return uc;
}
@@ -1642,6 +1826,49 @@ Definition* UnboxDoubleInstr::Canonicalize(FlowGraph* flow_graph) {
}
+Definition* BoxIntegerInstr::Canonicalize(FlowGraph* flow_graph) {
+ if ((input_use_list() == NULL) && !HasTryBlockUse(env_use_list())) {
+ // Environments can accomodate any representation. No need to box.
+ return value()->definition();
+ }
+
+ UnboxedIntConverterInstr* conv =
+ value()->definition()->AsUnboxedIntConverter();
+ if (conv != NULL) {
+ Definition* replacement = this;
+
+ switch (conv->from()) {
+ case kUnboxedInt32:
+ replacement = new BoxInt32Instr(conv->value()->CopyWithType());
+ break;
+ case kUnboxedUint32:
+ replacement = new BoxUint32Instr(conv->value()->CopyWithType());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ if (replacement != this) {
+ flow_graph->InsertBefore(this,
+ replacement,
+ NULL,
+ FlowGraph::kValue);
+ }
+
+ return replacement;
+ }
+
+ return this;
+}
+
+
+Definition* UnboxIntegerInstr::Canonicalize(FlowGraph* flow_graph) {
+ if (!HasUses()) return NULL;
+ return this;
+}
+
+
Definition* BoxFloat32x4Instr::Canonicalize(FlowGraph* flow_graph) {
if ((input_use_list() == NULL) && !HasTryBlockUse(env_use_list())) {
// Environments can accomodate any representation. No need to box.

Powered by Google App Engine
This is Rietveld 408576698