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

Unified Diff: runtime/vm/intermediate_language.cc

Issue 670263007: IR refactoring: consolidate all boxing and unboxing instructions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 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 7a800233acfb0e9099b434284e344994f9850cc6..5fe6075347b6478378c6445a34a5b135baced3fa 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -390,12 +390,12 @@ UnboxedConstantInstr::UnboxedConstantInstr(const Object& value,
bool Value::BindsTo32BitMaskConstant() const {
- if (!definition()->IsUnboxInteger() || !definition()->IsUnboxUint32()) {
+ if (!definition()->IsUnboxInt64() || !definition()->IsUnboxUint32()) {
return false;
}
- // Two cases to consider: UnboxInteger and UnboxUint32.
- if (definition()->IsUnboxInteger()) {
- UnboxIntegerInstr* instr = definition()->AsUnboxInteger();
+ // Two cases to consider: UnboxInt64 and UnboxUint32.
+ if (definition()->IsUnboxInt64()) {
+ UnboxInt64Instr* instr = definition()->AsUnboxInt64();
if (!instr->value()->BindsToConstant()) {
return false;
}
@@ -1262,9 +1262,9 @@ bool BinaryIntegerOpInstr::RightIsPowerOfTwoConstant() const {
static bool ToIntegerConstant(Value* value, int64_t* result) {
if (!value->BindsToConstant()) {
- if (value->definition()->IsUnboxDouble()) {
- return ToIntegerConstant(value->definition()->AsUnboxDouble()->value(),
- result);
+ UnboxInstr* unbox = value->definition()->AsUnbox();
+ if ((unbox != NULL) && (unbox->representation() == kUnboxedDouble)) {
+ return ToIntegerConstant(unbox->value(), result);
}
return false;
}
@@ -1904,29 +1904,32 @@ static bool HasTryBlockUse(Value* use_list) {
}
-Definition* BoxDoubleInstr::Canonicalize(FlowGraph* flow_graph) {
+Definition* BoxInstr::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();
}
- // Fold away BoxDouble(UnboxDouble(v)) if value is known to be double.
- UnboxDoubleInstr* defn = value()->definition()->AsUnboxDouble();
- if ((defn != NULL) && (defn->value()->Type()->ToCid() == kDoubleCid)) {
- return defn->value()->definition();
+ // Fold away Box<rep>(Unbox<rep>(v)) if value is known to be of the
+ // right class.
+ UnboxInstr* unbox_defn = value()->definition()->AsUnbox();
+ if ((unbox_defn != NULL) &&
+ (unbox_defn->representation() == from_representation()) &&
+ (unbox_defn->value()->Type()->ToCid() == Type()->ToCid())) {
+ return unbox_defn->value()->definition();
}
return this;
}
-bool BoxIntNInstr::ValueFitsSmi() const {
+bool BoxIntegerInstr::ValueFitsSmi() const {
Range* range = value()->definition()->range();
return RangeUtils::Fits(range, RangeBoundary::kRangeBoundarySmi);
}
-Definition* BoxIntNInstr::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();
@@ -1936,11 +1939,72 @@ Definition* BoxIntNInstr::Canonicalize(FlowGraph* flow_graph) {
}
-Definition* UnboxIntNInstr::Canonicalize(FlowGraph* flow_graph) {
+Definition* BoxInt64Instr::Canonicalize(FlowGraph* flow_graph) {
+ Definition* replacement = BoxIntegerInstr::Canonicalize(flow_graph);
+ if (replacement != this) {
+ return replacement;
+ }
+
+ 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* UnboxInstr::Canonicalize(FlowGraph* flow_graph) {
if (!HasUses()) return NULL;
- // Fold away UnboxInt<N>Instr(BoxInt<N>Instr(v)).
- BoxIntNInstr* box_defn = value()->definition()->AsBoxIntN();
+ // Fold away Unbox<rep>(Box<rep>(v)).
+ BoxInstr* box_defn = value()->definition()->AsBox();
+ if ((box_defn != NULL) &&
+ (box_defn->from_representation() == representation())) {
+ return box_defn->value()->definition();
+ }
+
+ if (representation() == kUnboxedDouble) {
+ ConstantInstr* c = value()->definition()->AsConstant();
+ if ((c != NULL) && c->value().IsDouble()) {
+ UnboxedConstantInstr* uc =
+ new UnboxedConstantInstr(c->value(), kUnboxedDouble);
+ flow_graph->InsertBefore(this, uc, NULL, FlowGraph::kValue);
+ return uc;
+ }
+ }
+
+ return this;
+}
+
+
+Definition* UnboxIntegerInstr::Canonicalize(FlowGraph* flow_graph) {
+ if (!HasUses()) return NULL;
+
+ // Fold away UnboxInteger<rep_to>(BoxInteger<rep_from>(v)).
+ BoxIntegerInstr* box_defn = value()->definition()->AsBoxInteger();
if (box_defn != NULL) {
if (box_defn->value()->definition()->representation() == representation()) {
return box_defn->value()->definition();
@@ -1963,6 +2027,33 @@ Definition* UnboxIntNInstr::Canonicalize(FlowGraph* flow_graph) {
}
+Definition* UnboxInt32Instr::Canonicalize(FlowGraph* flow_graph) {
+ Definition* replacement = UnboxIntegerInstr::Canonicalize(flow_graph);
+ if (replacement != this) {
+ return replacement;
+ }
+
+ ConstantInstr* c = value()->definition()->AsConstant();
+ if ((c != NULL) && c->value().IsSmi()) {
+ if (!is_truncating() && (kSmiBits > 32)) {
+ // Check that constant fits into 32-bit integer.
+ const int64_t value =
+ static_cast<int64_t>(Smi::Cast(c->value()).Value());
+ if (!Utils::IsInt(32, value)) {
+ return this;
+ }
+ }
+
+ UnboxedConstantInstr* uc =
+ new UnboxedConstantInstr(c->value(), kUnboxedInt32);
+ flow_graph->InsertBefore(this, uc, NULL, FlowGraph::kValue);
+ return uc;
+ }
+
+ return this;
+}
+
+
Definition* UnboxedIntConverterInstr::Canonicalize(FlowGraph* flow_graph) {
if (!HasUses()) return NULL;
@@ -1985,7 +2076,7 @@ Definition* UnboxedIntConverterInstr::Canonicalize(FlowGraph* flow_graph) {
return converter;
}
- UnboxIntegerInstr* unbox_defn = value()->definition()->AsUnboxInteger();
+ UnboxInt64Instr* unbox_defn = value()->definition()->AsUnboxInt64();
if (unbox_defn != NULL &&
(from() == kUnboxedMint) &&
(to() == kUnboxedInt32) &&
@@ -2009,166 +2100,6 @@ Definition* UnboxedIntConverterInstr::Canonicalize(FlowGraph* flow_graph) {
}
-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()) {
- if (!is_truncating() && (kSmiBits > 32)) {
- // Check that constant fits into 32-bit integer.
- const int64_t value =
- static_cast<int64_t>(Smi::Cast(c->value()).Value());
- if (!Utils::IsInt(32, value)) {
- return this;
- }
- }
-
- 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)).
- BoxDoubleInstr* box_defn = value()->definition()->AsBoxDouble();
- if (box_defn != NULL) {
- return box_defn->value()->definition();
- }
-
- ConstantInstr* c = value()->definition()->AsConstant();
- if ((c != NULL) && c->value().IsDouble()) {
- UnboxedConstantInstr* uc =
- new UnboxedConstantInstr(c->value(), kUnboxedDouble);
- flow_graph->InsertBefore(this, uc, NULL, FlowGraph::kValue);
- return uc;
- }
-
- return this;
-}
-
-
-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.
- return value()->definition();
- }
-
- // Fold away BoxFloat32x4(UnboxFloat32x4(v)).
- UnboxFloat32x4Instr* defn = value()->definition()->AsUnboxFloat32x4();
- if ((defn != NULL) && (defn->value()->Type()->ToCid() == kFloat32x4Cid)) {
- return defn->value()->definition();
- }
-
- return this;
-}
-
-
-Definition* UnboxFloat32x4Instr::Canonicalize(FlowGraph* flow_graph) {
- // Fold away UnboxFloat32x4(BoxFloat32x4(v)).
- BoxFloat32x4Instr* defn = value()->definition()->AsBoxFloat32x4();
- return (defn != NULL) ? defn->value()->definition() : this;
-}
-
-
-Definition* BoxFloat64x2Instr::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();
- }
-
- // Fold away BoxFloat64x2(UnboxFloat64x2(v)).
- UnboxFloat64x2Instr* defn = value()->definition()->AsUnboxFloat64x2();
- if ((defn != NULL) && (defn->value()->Type()->ToCid() == kFloat64x2Cid)) {
- return defn->value()->definition();
- }
-
- return this;
-}
-
-
-Definition* UnboxFloat64x2Instr::Canonicalize(FlowGraph* flow_graph) {
- // Fold away UnboxFloat64x2(BoxFloat64x2(v)).
- BoxFloat64x2Instr* defn = value()->definition()->AsBoxFloat64x2();
- return (defn != NULL) ? defn->value()->definition() : this;
-}
-
-
-
-Definition* BoxInt32x4Instr::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();
- }
-
- // Fold away BoxInt32x4(UnboxInt32x4(v)).
- UnboxInt32x4Instr* defn = value()->definition()->AsUnboxInt32x4();
- if ((defn != NULL) && (defn->value()->Type()->ToCid() == kInt32x4Cid)) {
- return defn->value()->definition();
- }
-
- return this;
-}
-
-
-Definition* UnboxInt32x4Instr::Canonicalize(FlowGraph* flow_graph) {
- // Fold away UnboxInt32x4(BoxInt32x4(v)).
- BoxInt32x4Instr* defn = value()->definition()->AsBoxInt32x4();
- return (defn != NULL) ? defn->value()->definition() : this;
-}
-
-
Definition* BooleanNegateInstr::Canonicalize(FlowGraph* flow_graph) {
Definition* defn = value()->definition();
if (defn->IsComparison() && defn->HasOnlyUse(value())) {
@@ -2460,6 +2391,93 @@ Instruction* CheckEitherNonSmiInstr::Canonicalize(FlowGraph* flow_graph) {
}
+BoxInstr* BoxInstr::Create(Representation from, Value* value) {
+ switch (from) {
+ case kUnboxedInt32:
+ return new BoxInt32Instr(value);
+
+ case kUnboxedUint32:
+ return new BoxUint32Instr(value);
+
+ case kUnboxedMint:
+ return new BoxInt64Instr(value);
+
+ case kUnboxedDouble:
+ case kUnboxedFloat32x4:
+ case kUnboxedFloat64x2:
+ case kUnboxedInt32x4:
+ return new BoxInstr(from, value);
+
+ default:
+ UNREACHABLE();
+ return NULL;
+ }
+}
+
+
+UnboxInstr* UnboxInstr::Create(Representation to,
+ Value* value,
+ intptr_t deopt_id) {
+ switch (to) {
+ case kUnboxedInt32:
+ return new UnboxInt32Instr(value, deopt_id);
+
+ case kUnboxedUint32:
+ return new UnboxUint32Instr(value, deopt_id);
+
+ case kUnboxedMint:
+ return new UnboxInt64Instr(value, deopt_id);
+
+ case kUnboxedDouble:
+ case kUnboxedFloat32x4:
+ case kUnboxedFloat64x2:
+ case kUnboxedInt32x4:
+ return new UnboxInstr(to, value, deopt_id);
+
+ default:
+ UNREACHABLE();
+ return NULL;
+ }
+}
+
+
+bool UnboxInstr::CanConvertSmi() const {
+ switch (representation()) {
+ case kUnboxedDouble:
+ case kUnboxedMint:
+ return true;
+
+ case kUnboxedFloat32x4:
+ case kUnboxedFloat64x2:
+ case kUnboxedInt32x4:
+ return false;
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+
+intptr_t UnboxInstr::BoxCid() const {
+ switch (representation()) {
+ case kUnboxedMint:
+ return kMintCid;
+ case kUnboxedDouble:
+ return kDoubleCid;
+ case kUnboxedFloat32x4:
+ return kFloat32x4Cid;
+ case kUnboxedFloat64x2:
+ return kFloat64x2Cid;
+ case kUnboxedInt32x4:
+ return kInt32x4Cid;
+ default:
+ UNREACHABLE();
+ return kIllegalCid;
+ }
+}
+
+
// Shared code generation methods (EmitNativeCode and
// MakeLocationSummary). Only assembly code that can be shared across all
// architectures can be used. Machine specific register allocation and code

Powered by Google App Engine
This is Rietveld 408576698