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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 1670113004: VM: Optimized calls to asin, acos, tan. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 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 | « no previous file | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_optimizer.cc
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index e92721a45d743d3f5429e02922286ca778c44fb7..5ff17358784cc36a4ca298e59a8007eb87b4d650 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -4497,134 +4497,157 @@ void FlowGraphOptimizer::VisitStaticCall(StaticCallInstr* call) {
if (unary_kind != MathUnaryInstr::kIllegal) {
if (FLAG_precompilation) {
// TODO(srdjan): Adapt MathUnaryInstr to allow tagged inputs as well.
- } else {
- MathUnaryInstr* math_unary =
- new(Z) MathUnaryInstr(unary_kind,
- new(Z) Value(call->ArgumentAt(0)),
- call->deopt_id());
- ReplaceCall(call, math_unary);
- }
- } else if ((recognized_kind == MethodRecognizer::kFloat32x4Zero) ||
- (recognized_kind == MethodRecognizer::kFloat32x4Splat) ||
- (recognized_kind == MethodRecognizer::kFloat32x4Constructor) ||
- (recognized_kind == MethodRecognizer::kFloat32x4FromFloat64x2)) {
- TryInlineFloat32x4Constructor(call, recognized_kind);
- } else if ((recognized_kind == MethodRecognizer::kFloat64x2Constructor) ||
- (recognized_kind == MethodRecognizer::kFloat64x2Zero) ||
- (recognized_kind == MethodRecognizer::kFloat64x2Splat) ||
- (recognized_kind == MethodRecognizer::kFloat64x2FromFloat32x4)) {
- TryInlineFloat64x2Constructor(call, recognized_kind);
- } else if ((recognized_kind == MethodRecognizer::kInt32x4BoolConstructor) ||
- (recognized_kind == MethodRecognizer::kInt32x4Constructor)) {
- TryInlineInt32x4Constructor(call, recognized_kind);
- } else if (recognized_kind == MethodRecognizer::kObjectConstructor) {
- // Remove the original push arguments.
- for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
- PushArgumentInstr* push = call->PushArgumentAt(i);
- push->ReplaceUsesWith(push->value()->definition());
- push->RemoveFromGraph();
- }
- // Manually replace call with global null constant. ReplaceCall can't
- // be used for definitions that are already in the graph.
- call->ReplaceUsesWith(flow_graph_->constant_null());
- ASSERT(current_iterator()->Current() == call);
- current_iterator()->RemoveCurrentFromGraph();;
- } else if ((recognized_kind == MethodRecognizer::kMathMin) ||
- (recognized_kind == MethodRecognizer::kMathMax)) {
- // We can handle only monomorphic min/max call sites with both arguments
- // being either doubles or smis.
- if (call->HasICData() && (call->ic_data()->NumberOfChecks() == 1)) {
- const ICData& ic_data = *call->ic_data();
- intptr_t result_cid = kIllegalCid;
- if (ICDataHasReceiverArgumentClassIds(ic_data, kDoubleCid, kDoubleCid)) {
- result_cid = kDoubleCid;
- } else if (ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid)) {
- result_cid = kSmiCid;
- }
- if (result_cid != kIllegalCid) {
- MathMinMaxInstr* min_max = new(Z) MathMinMaxInstr(
- recognized_kind,
- new(Z) Value(call->ArgumentAt(0)),
- new(Z) Value(call->ArgumentAt(1)),
- call->deopt_id(),
- result_cid);
- const ICData& unary_checks =
- ICData::ZoneHandle(Z, ic_data.AsUnaryClassChecks());
- AddCheckClass(min_max->left()->definition(),
- unary_checks,
- call->deopt_id(),
- call->env(),
- call);
- AddCheckClass(min_max->right()->definition(),
- unary_checks,
- call->deopt_id(),
- call->env(),
- call);
- ReplaceCall(call, min_max);
- }
- }
- } else if ((recognized_kind == MethodRecognizer::kMathDoublePow) ||
- (recognized_kind == MethodRecognizer::kMathAtan) ||
- (recognized_kind == MethodRecognizer::kMathAtan2)) {
- if (FLAG_precompilation) {
- // No UnboxDouble instructons allowed.
return;
}
- // InvokeMathCFunctionInstr requires unboxed doubles. UnboxDouble
- // instructions contain type checks and conversions to double.
- ZoneGrowableArray<Value*>* args =
- new(Z) ZoneGrowableArray<Value*>(call->ArgumentCount());
- for (intptr_t i = 0; i < call->ArgumentCount(); i++) {
- args->Add(new(Z) Value(call->ArgumentAt(i)));
- }
- InvokeMathCFunctionInstr* invoke =
- new(Z) InvokeMathCFunctionInstr(args,
- call->deopt_id(),
- recognized_kind,
- call->token_pos());
- ReplaceCall(call, invoke);
- } else if (recognized_kind == MethodRecognizer::kDoubleFromInteger) {
- if (call->HasICData() && (call->ic_data()->NumberOfChecks() == 1)) {
- const ICData& ic_data = *call->ic_data();
- if (CanUnboxDouble()) {
- if (ArgIsAlways(kSmiCid, ic_data, 1)) {
- Definition* arg = call->ArgumentAt(1);
- AddCheckSmi(arg, call->deopt_id(), call->env(), call);
- ReplaceCall(call,
- new(Z) SmiToDoubleInstr(new(Z) Value(arg),
- call->token_pos()));
- } else if (ArgIsAlways(kMintCid, ic_data, 1) &&
- CanConvertUnboxedMintToDouble()) {
- Definition* arg = call->ArgumentAt(1);
- ReplaceCall(call,
- new(Z) MintToDoubleInstr(new(Z) Value(arg),
- call->deopt_id()));
+ MathUnaryInstr* math_unary =
+ new(Z) MathUnaryInstr(unary_kind,
+ new(Z) Value(call->ArgumentAt(0)),
+ call->deopt_id());
+ ReplaceCall(call, math_unary);
+ return;
+ }
+ switch (recognized_kind) {
+ case MethodRecognizer::kFloat32x4Zero:
+ case MethodRecognizer::kFloat32x4Splat:
+ case MethodRecognizer::kFloat32x4Constructor:
+ case MethodRecognizer::kFloat32x4FromFloat64x2:
+ TryInlineFloat32x4Constructor(call, recognized_kind);
+ break;
+ case MethodRecognizer::kFloat64x2Constructor:
+ case MethodRecognizer::kFloat64x2Zero:
+ case MethodRecognizer::kFloat64x2Splat:
+ case MethodRecognizer::kFloat64x2FromFloat32x4:
+ TryInlineFloat64x2Constructor(call, recognized_kind);
+ break;
+ case MethodRecognizer::kInt32x4BoolConstructor:
+ case MethodRecognizer::kInt32x4Constructor:
+ TryInlineInt32x4Constructor(call, recognized_kind);
+ break;
+ case MethodRecognizer::kObjectConstructor: {
+ // Remove the original push arguments.
+ for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
+ PushArgumentInstr* push = call->PushArgumentAt(i);
+ push->ReplaceUsesWith(push->value()->definition());
+ push->RemoveFromGraph();
+ }
+ // Manually replace call with global null constant. ReplaceCall can't
+ // be used for definitions that are already in the graph.
+ call->ReplaceUsesWith(flow_graph_->constant_null());
+ ASSERT(current_iterator()->Current() == call);
+ current_iterator()->RemoveCurrentFromGraph();
+ break;
+ }
+ case MethodRecognizer::kMathMin:
+ case MethodRecognizer::kMathMax: {
+ // We can handle only monomorphic min/max call sites with both arguments
+ // being either doubles or smis.
+ if (call->HasICData() && (call->ic_data()->NumberOfChecks() == 1)) {
+ const ICData& ic_data = *call->ic_data();
+ intptr_t result_cid = kIllegalCid;
+ if (ICDataHasReceiverArgumentClassIds(ic_data,
+ kDoubleCid, kDoubleCid)) {
+ result_cid = kDoubleCid;
+ } else if (ICDataHasReceiverArgumentClassIds(ic_data,
+ kSmiCid, kSmiCid)) {
+ result_cid = kSmiCid;
+ }
+ if (result_cid != kIllegalCid) {
+ MathMinMaxInstr* min_max = new(Z) MathMinMaxInstr(
+ recognized_kind,
+ new(Z) Value(call->ArgumentAt(0)),
+ new(Z) Value(call->ArgumentAt(1)),
+ call->deopt_id(),
+ result_cid);
+ const ICData& unary_checks =
+ ICData::ZoneHandle(Z, ic_data.AsUnaryClassChecks());
+ AddCheckClass(min_max->left()->definition(),
+ unary_checks,
+ call->deopt_id(),
+ call->env(),
+ call);
+ AddCheckClass(min_max->right()->definition(),
+ unary_checks,
+ call->deopt_id(),
+ call->env(),
+ call);
+ ReplaceCall(call, min_max);
}
}
+ break;
+ }
+ case MethodRecognizer::kMathDoublePow:
+ case MethodRecognizer::kMathTan:
+ case MethodRecognizer::kMathAsin:
+ case MethodRecognizer::kMathAcos:
+ case MethodRecognizer::kMathAtan:
+ case MethodRecognizer::kMathAtan2: {
+ if (FLAG_precompilation) {
+ // No UnboxDouble instructons allowed.
+ return;
+ }
+ // InvokeMathCFunctionInstr requires unboxed doubles. UnboxDouble
+ // instructions contain type checks and conversions to double.
+ ZoneGrowableArray<Value*>* args =
+ new(Z) ZoneGrowableArray<Value*>(call->ArgumentCount());
+ for (intptr_t i = 0; i < call->ArgumentCount(); i++) {
+ args->Add(new(Z) Value(call->ArgumentAt(i)));
+ }
+ InvokeMathCFunctionInstr* invoke =
+ new(Z) InvokeMathCFunctionInstr(args,
+ call->deopt_id(),
+ recognized_kind,
+ call->token_pos());
+ ReplaceCall(call, invoke);
+ break;
}
- } else if (call->function().IsFactory()) {
- const Class& function_class =
- Class::Handle(Z, call->function().Owner());
- if ((function_class.library() == Library::CoreLibrary()) ||
- (function_class.library() == Library::TypedDataLibrary())) {
- intptr_t cid = FactoryRecognizer::ResultCid(call->function());
- switch (cid) {
- case kArrayCid: {
- Value* type = new(Z) Value(call->ArgumentAt(0));
- Value* num_elements = new(Z) Value(call->ArgumentAt(1));
- if (num_elements->BindsToConstant() &&
- num_elements->BoundConstant().IsSmi()) {
- intptr_t length = Smi::Cast(num_elements->BoundConstant()).Value();
- if (length >= 0 && length <= Array::kMaxElements) {
- CreateArrayInstr* create_array =
- new(Z) CreateArrayInstr(
- call->token_pos(), type, num_elements);
- ReplaceCall(call, create_array);
+ case MethodRecognizer::kDoubleFromInteger: {
+ if (call->HasICData() && (call->ic_data()->NumberOfChecks() == 1)) {
+ const ICData& ic_data = *call->ic_data();
+ if (CanUnboxDouble()) {
+ if (ArgIsAlways(kSmiCid, ic_data, 1)) {
+ Definition* arg = call->ArgumentAt(1);
+ AddCheckSmi(arg, call->deopt_id(), call->env(), call);
+ ReplaceCall(call,
+ new(Z) SmiToDoubleInstr(new(Z) Value(arg),
+ call->token_pos()));
+ } else if (ArgIsAlways(kMintCid, ic_data, 1) &&
+ CanConvertUnboxedMintToDouble()) {
+ Definition* arg = call->ArgumentAt(1);
+ ReplaceCall(call,
+ new(Z) MintToDoubleInstr(new(Z) Value(arg),
+ call->deopt_id()));
+ }
+ }
+ }
+ break;
+ }
+ default: {
+ if (call->function().IsFactory()) {
+ const Class& function_class =
+ Class::Handle(Z, call->function().Owner());
+ if ((function_class.library() == Library::CoreLibrary()) ||
+ (function_class.library() == Library::TypedDataLibrary())) {
+ intptr_t cid = FactoryRecognizer::ResultCid(call->function());
+ switch (cid) {
+ case kArrayCid: {
+ Value* type = new(Z) Value(call->ArgumentAt(0));
+ Value* num_elements = new(Z) Value(call->ArgumentAt(1));
+ if (num_elements->BindsToConstant() &&
+ num_elements->BoundConstant().IsSmi()) {
+ intptr_t length =
+ Smi::Cast(num_elements->BoundConstant()).Value();
+ if (length >= 0 && length <= Array::kMaxElements) {
+ CreateArrayInstr* create_array =
+ new(Z) CreateArrayInstr(
+ call->token_pos(), type, num_elements);
+ ReplaceCall(call, create_array);
+ }
+ }
}
+ default:
+ break;
}
}
- default:
- break;
}
}
}
« no previous file with comments | « no previous file | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698