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

Unified Diff: runtime/vm/intermediate_language_dbc.cc

Issue 2120703002: DBC: Enables unboxed doubles (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Rename BoxDouble -> WriteIntoDouble Created 4 years, 5 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
« no previous file with comments | « runtime/vm/flow_graph_compiler_dbc.cc ('k') | runtime/vm/simulator_dbc.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language_dbc.cc
diff --git a/runtime/vm/intermediate_language_dbc.cc b/runtime/vm/intermediate_language_dbc.cc
index 7ada86f52d5e67ebf605a604f2210bab2ba2de24..eabc1bc8730c7cd8fd95352b32714f1bee2b3889 100644
--- a/runtime/vm/intermediate_language_dbc.cc
+++ b/runtime/vm/intermediate_language_dbc.cc
@@ -34,30 +34,43 @@ DECLARE_FLAG(int, optimization_counter_threshold);
M(LoadUntagged) \
M(AllocateUninitializedContext) \
M(BinaryInt32Op) \
- M(UnaryDoubleOp) \
- M(SmiToDouble) \
M(Int32ToDouble) \
- M(MintToDouble) \
M(DoubleToInteger) \
M(DoubleToSmi) \
M(DoubleToDouble) \
M(DoubleToFloat) \
M(FloatToDouble) \
M(UnboxedConstant) \
- M(BinaryDoubleOp) \
M(MathUnary) \
M(MathMinMax) \
- M(Box) \
- M(Unbox) \
M(BoxInt64) \
- M(BinaryMintOp) \
- M(ShiftMintOp) \
- M(UnaryMintOp) \
M(InvokeMathCFunction) \
M(MergedMath) \
M(GuardFieldClass) \
M(GuardFieldLength) \
M(IfThenElse) \
+ M(ExtractNthOutput) \
+ M(BinaryUint32Op) \
+ M(ShiftUint32Op) \
+ M(UnaryUint32Op) \
+ M(UnboxedIntConverter) \
+ M(BoxInteger32) \
+ M(UnboxInteger32) \
+
+// List of instructions that are not used by DBC.
+// Things we aren't planning to implement for DBC:
+// - Unboxed SIMD,
+// - Unboxed Mint,
+// - Optimized RegExps,
+// - Precompilation.
+#define FOR_EACH_UNREACHABLE_INSTRUCTION(M) \
+ M(CaseInsensitiveCompareUC16) \
+ M(GrowRegExpStack) \
+ M(IndirectGoto) \
+ M(MintToDouble) \
+ M(BinaryMintOp) \
+ M(ShiftMintOp) \
+ M(UnaryMintOp) \
M(BinaryFloat32x4Op) \
M(Simd32x4Shuffle) \
M(Simd32x4ShuffleMix) \
@@ -89,21 +102,8 @@ DECLARE_FLAG(int, optimization_counter_threshold);
M(Simd64x2Shuffle) \
M(Float64x2ZeroArg) \
M(Float64x2OneArg) \
- M(ExtractNthOutput) \
- M(BinaryUint32Op) \
- M(ShiftUint32Op) \
- M(UnaryUint32Op) \
- M(UnboxedIntConverter) \
- M(BoxInteger32) \
- M(UnboxInteger32) \
M(CheckedSmiOp) \
-
-// List of instructions that are not used by DBC.
-#define FOR_EACH_UNREACHABLE_INSTRUCTION(M) \
- M(CaseInsensitiveCompareUC16) \
M(GenericCheckBound) \
- M(GrowRegExpStack) \
- M(IndirectGoto)
// Location summaries actually are not used by the unoptimizing DBC compiler
// because we don't allocate any registers.
@@ -1081,22 +1081,9 @@ EMIT_NATIVE_CODE(CheckSmi, 1) {
EMIT_NATIVE_CODE(CheckEitherNonSmi, 2) {
- intptr_t left_cid = left()->Type()->ToCid();
- intptr_t right_cid = right()->Type()->ToCid();
const Register left = locs()->in(0).reg();
const Register right = locs()->in(1).reg();
- if (this->left()->definition() == this->right()->definition()) {
- __ CheckSmi(left);
- } else if (left_cid == kSmiCid) {
- __ CheckSmi(right);
- } else if (right_cid == kSmiCid) {
- __ CheckSmi(left);
- } else {
- __ CheckSmi(left);
- compiler->EmitDeopt(deopt_id(), ICData::kDeoptBinaryDoubleOp,
- licm_hoisted_ ? ICData::kHoisted : 0);
- __ CheckSmi(right);
- }
+ __ CheckEitherNonSmi(left, right);
compiler->EmitDeopt(deopt_id(), ICData::kDeoptBinaryDoubleOp,
licm_hoisted_ ? ICData::kHoisted : 0);
}
@@ -1222,10 +1209,76 @@ EMIT_NATIVE_CODE(UnarySmiOp, 1, Location::RequiresRegister()) {
break;
default:
UNREACHABLE();
+ break;
}
}
+EMIT_NATIVE_CODE(Box, 1, Location::RequiresRegister(), LocationSummary::kCall) {
+ ASSERT(from_representation() == kUnboxedDouble);
+ const Register value = locs()->in(0).reg();
+ const Register out = locs()->out(0).reg();
+ const intptr_t kidx = __ AddConstant(compiler->double_class());
+ __ Allocate(kidx);
+ compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
+ Thread::kNoDeoptId,
+ token_pos());
+ compiler->RecordSafepoint(locs());
+ // __ Allocate puts the box at the top of the stack.
+ __ WriteIntoDouble(out, value);
+}
+
+
+EMIT_NATIVE_CODE(Unbox, 1, Location::RequiresRegister()) {
+ ASSERT(representation() == kUnboxedDouble);
+ const intptr_t value_cid = value()->Type()->ToCid();
+ const intptr_t box_cid = BoxCid();
+ const Register box = locs()->in(0).reg();
+ const Register result = locs()->out(0).reg();
+ if (value_cid == box_cid) {
+ __ UnboxDouble(result, box);
+ } else if (CanConvertSmi() && (value_cid == kSmiCid)) {
+ __ SmiToDouble(result, box);
+ } else if ((value()->Type()->ToNullableCid() == box_cid) &&
+ value()->Type()->is_nullable()) {
+ __ IfEqNull(box);
+ compiler->EmitDeopt(GetDeoptId(), ICData::kDeoptCheckClass);
+ __ UnboxDouble(result, box);
+ } else {
+ __ CheckedUnboxDouble(result, box);
+ compiler->EmitDeopt(GetDeoptId(), ICData::kDeoptCheckClass);
+ }
+}
+
+
+EMIT_NATIVE_CODE(SmiToDouble, 1, Location::RequiresRegister()) {
+ const Register value = locs()->in(0).reg();
+ const Register result = locs()->out(0).reg();
+ __ SmiToDouble(result, value);
+}
+
+
+EMIT_NATIVE_CODE(BinaryDoubleOp, 2, Location::RequiresRegister()) {
+ const Register left = locs()->in(0).reg();
+ const Register right = locs()->in(1).reg();
+ const Register result = locs()->out(0).reg();
+ switch (op_kind()) {
+ case Token::kADD: __ DAdd(result, left, right); break;
+ case Token::kSUB: __ DSub(result, left, right); break;
+ case Token::kMUL: __ DMul(result, left, right); break;
+ case Token::kDIV: __ DDiv(result, left, right); break;
+ default: UNREACHABLE();
+ }
+}
+
+
+EMIT_NATIVE_CODE(UnaryDoubleOp, 1, Location::RequiresRegister()) {
+ const Register value = locs()->in(0).reg();
+ const Register result = locs()->out(0).reg();
+ __ DNeg(result, value);
+}
+
+
static Token::Kind FlipCondition(Token::Kind kind) {
switch (kind) {
case Token::kEQ: return Token::kNE;
@@ -1241,7 +1294,7 @@ static Token::Kind FlipCondition(Token::Kind kind) {
}
-static Bytecode::Opcode OpcodeForCondition(Token::Kind kind) {
+static Bytecode::Opcode OpcodeForSmiCondition(Token::Kind kind) {
switch (kind) {
case Token::kEQ: return Bytecode::kIfEqStrict;
case Token::kNE: return Bytecode::kIfNeStrict;
@@ -1256,6 +1309,21 @@ static Bytecode::Opcode OpcodeForCondition(Token::Kind kind) {
}
+static Bytecode::Opcode OpcodeForDoubleCondition(Token::Kind kind) {
+ switch (kind) {
+ case Token::kEQ: return Bytecode::kIfDEq;
+ case Token::kNE: return Bytecode::kIfDNe;
+ case Token::kLT: return Bytecode::kIfDLt;
+ case Token::kGT: return Bytecode::kIfDGt;
+ case Token::kLTE: return Bytecode::kIfDLe;
+ case Token::kGTE: return Bytecode::kIfDGe;
+ default:
+ UNREACHABLE();
+ return Bytecode::kTrap;
+ }
+}
+
+
static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler,
LocationSummary* locs,
Token::Kind kind,
@@ -1272,7 +1340,28 @@ static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler,
condition = NEXT_IS_FALSE;
comparison = FlipCondition(kind);
}
- __ Emit(Bytecode::Encode(OpcodeForCondition(comparison), left, right));
+ __ Emit(Bytecode::Encode(OpcodeForSmiCondition(comparison), left, right));
+ return condition;
+}
+
+
+static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
+ LocationSummary* locs,
+ Token::Kind kind,
+ BranchLabels labels) {
+ const Register left = locs->in(0).reg();
+ const Register right = locs->in(1).reg();
+ Token::Kind comparison = kind;
+ Condition condition = NEXT_IS_TRUE;
+ if (labels.fall_through != labels.false_label) {
+ // If we aren't falling through to the false label, we can save a Jump
+ // instruction in the case that the true case is the fall through by
+ // flipping the sense of the test such that the instruction following the
+ // test is the Jump to the false label.
+ condition = NEXT_IS_FALSE;
+ comparison = FlipCondition(kind);
+ }
+ __ Emit(Bytecode::Encode(OpcodeForDoubleCondition(comparison), left, right));
return condition;
}
@@ -1283,9 +1372,7 @@ Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
return EmitSmiComparisonOp(compiler, locs(), kind(), labels);
} else {
ASSERT(operation_cid() == kDoubleCid);
- Unsupported(compiler);
- UNREACHABLE();
- return NEXT_IS_FALSE;
+ return EmitDoubleComparisonOp(compiler, locs(), kind(), labels);
}
}
@@ -1321,9 +1408,7 @@ Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
return EmitSmiComparisonOp(compiler, locs(), kind(), labels);
} else {
ASSERT(operation_cid() == kDoubleCid);
- Unsupported(compiler);
- UNREACHABLE();
- return NEXT_IS_FALSE;
+ return EmitDoubleComparisonOp(compiler, locs(), kind(), labels);
}
}
« no previous file with comments | « runtime/vm/flow_graph_compiler_dbc.cc ('k') | runtime/vm/simulator_dbc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698