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

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 10592028: Improve inlining of bit_and operation for Mint and Smi in new compilers. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/flow_graph_builder.h" 7 #include "vm/flow_graph_builder.h"
8 #include "vm/il_printer.h" 8 #include "vm/il_printer.h"
9 #include "vm/object_store.h" 9 #include "vm/object_store.h"
10 10
(...skipping 29 matching lines...) Expand all
40 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { 40 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
41 const intptr_t test_class_id = ic_data.GetReceiverClassIdAt(i); 41 const intptr_t test_class_id = ic_data.GetReceiverClassIdAt(i);
42 if (test_class_id == class_id) { 42 if (test_class_id == class_id) {
43 return true; 43 return true;
44 } 44 }
45 } 45 }
46 return false; 46 return false;
47 } 47 }
48 48
49 49
50 static bool ICDataHasReceiverArgumentClasses(const ICData& ic_data, 50 static bool ICDataHasReceiverArgumentClassIds(const ICData& ic_data,
51 intptr_t receiver_class_id, 51 intptr_t receiver_class_id,
52 intptr_t argument_class_id) { 52 intptr_t argument_class_id) {
53 ASSERT(receiver_class_id != kIllegalObjectKind); 53 ASSERT(receiver_class_id != kIllegalObjectKind);
54 ASSERT(argument_class_id != kIllegalObjectKind); 54 ASSERT(argument_class_id != kIllegalObjectKind);
55 if (ic_data.num_args_tested() != 2) return false; 55 if (ic_data.num_args_tested() != 2) return false;
56 56
57 Function& target = Function::Handle(); 57 Function& target = Function::Handle();
58 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { 58 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
59 GrowableArray<intptr_t> class_ids; 59 GrowableArray<intptr_t> class_ids;
60 ic_data.GetCheckAt(i, &class_ids, &target); 60 ic_data.GetCheckAt(i, &class_ids, &target);
61 ASSERT(class_ids.length() == 2); 61 ASSERT(class_ids.length() == 2);
62 if ((class_ids[0] == receiver_class_id) && 62 if ((class_ids[0] == receiver_class_id) &&
63 (class_ids[1] == argument_class_id)) { 63 (class_ids[1] == argument_class_id)) {
64 return true; 64 return true;
65 } 65 }
66 } 66 }
67 return false; 67 return false;
68 } 68 }
69 69
70 70
71 static bool ClassIdIsOneOf(intptr_t class_id,
72 GrowableArray<intptr_t>* class_ids) {
73 for (intptr_t i = 0; i < class_ids->length(); i++) {
74 if ((*class_ids)[i] == class_id) {
75 return true;
76 }
77 }
78 return false;
79 }
80
81
82 static bool ICDataHasOnlyReceiverArgumentClassIds(
83 const ICData& ic_data,
84 GrowableArray<intptr_t>* receiver_class_ids,
85 GrowableArray<intptr_t>* argument_class_ids) {
86 if (ic_data.num_args_tested() != 2) return false;
87
88 Function& target = Function::Handle();
89 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
90 GrowableArray<intptr_t> class_ids;
91 ic_data.GetCheckAt(i, &class_ids, &target);
92 ASSERT(class_ids.length() == 2);
93 if (!ClassIdIsOneOf(class_ids[0], receiver_class_ids) ||
94 !ClassIdIsOneOf(class_ids[1], argument_class_ids)) {
95 return false;
96 }
97 }
98 return true;
99 }
100
101
71 static bool HasOneSmi(const ICData& ic_data) { 102 static bool HasOneSmi(const ICData& ic_data) {
72 return ICDataHasReceiverClassId(ic_data, kSmi); 103 return ICDataHasReceiverClassId(ic_data, kSmi);
73 } 104 }
74 105
75 106
76 static bool HasTwoSmi(const ICData& ic_data) { 107 static bool HasTwoSmi(const ICData& ic_data) {
77 return ICDataHasReceiverArgumentClasses(ic_data, kSmi, kSmi); 108 return ICDataHasReceiverArgumentClassIds(ic_data, kSmi, kSmi);
78 } 109 }
79 110
80 111
81 static bool HasMintSmi(const ICData& ic_data) { 112 // Returns false if the ICData contains anything other than the 4 combinations
82 return ICDataHasReceiverArgumentClasses(ic_data, kMint, kSmi); 113 // of Mint and Smi for the receiver and argument classes.
114 static bool HasTwoMintOrSmi(const ICData& ic_data) {
115 GrowableArray<intptr_t> class_ids;
116 class_ids.Add(kSmi);
117 class_ids.Add(kMint);
118 return ICDataHasOnlyReceiverArgumentClassIds(ic_data, &class_ids, &class_ids);
83 } 119 }
84 120
85 121
86 static bool HasOneDouble(const ICData& ic_data) { 122 static bool HasOneDouble(const ICData& ic_data) {
87 return ICDataHasReceiverClassId(ic_data, kDouble); 123 return ICDataHasReceiverClassId(ic_data, kDouble);
88 } 124 }
89 125
90 126
91 static bool HasTwoDouble(const ICData& ic_data) { 127 static bool HasTwoDouble(const ICData& ic_data) {
92 return ICDataHasReceiverArgumentClasses(ic_data, kDouble, kDouble); 128 return ICDataHasReceiverArgumentClassIds(ic_data, kDouble, kDouble);
93 } 129 }
94 130
95 131
96 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallComp* comp, 132 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallComp* comp,
97 Token::Kind op_kind) { 133 Token::Kind op_kind) {
98 BinaryOpComp::OperandsType operands_type; 134 BinaryOpComp::OperandsType operands_type;
99 135
100 if (HasMintSmi(*comp->ic_data())) { 136 const intptr_t num_checks = comp->ic_data()->NumberOfChecks();
101 // We check for Mint receiver and Smi argument, but we try to support any 137 if (num_checks == 1) {
srdjan 2012/06/21 16:02:37 What if it has only Mint and Smi (1 check). Wouldn
regis 2012/06/21 18:26:42 True. I did not want to skip other Smi optimizatio
102 // combination of Mint and Smi. 138 if (HasTwoSmi(*comp->ic_data())) {
103 if (op_kind != Token::kBIT_AND) { 139 if (op_kind == Token::kDIV ||
104 // TODO(regis): Not yet supported. 140 op_kind == Token::kMOD) {
105 return false; 141 // TODO(srdjan): Not yet supported.
106 } 142 return false;
107 143 }
108 operands_type = BinaryOpComp::kMintOperands; 144 operands_type = BinaryOpComp::kSmiOperands;
109 } 145 } else if (HasTwoDouble(*comp->ic_data())) {
110 146 if (op_kind != Token::kADD &&
111 if (comp->ic_data()->NumberOfChecks() != 1) { 147 op_kind != Token::kSUB &&
112 // TODO(srdjan): Not yet supported. 148 op_kind != Token::kMUL &&
113 return false; 149 op_kind != Token::kDIV) {
114 } 150 // TODO(vegorov): Not yet supported.
115 151 return false;
116 if (HasTwoSmi(*comp->ic_data())) { 152 }
117 if (op_kind == Token::kDIV || 153 operands_type = BinaryOpComp::kDoubleOperands;
118 op_kind == Token::kMOD) { 154 } else {
119 // TODO(srdjan): Not yet supported. 155 // TODO(srdjan): Not yet supported.
120 return false; 156 return false;
121 } 157 }
122 158 } else if (num_checks < 4) {
srdjan 2012/06/21 16:02:37 I would remove the num_checks test. If it has Mint
regis 2012/06/21 18:26:42 Done.
123 operands_type = BinaryOpComp::kSmiOperands; 159 if (HasTwoMintOrSmi(*comp->ic_data())) {
124 } else if (HasTwoDouble(*comp->ic_data())) { 160 // We check for Mint or Smi receiver and Mint or Smi argument.
125 if (op_kind != Token::kADD && 161 if (op_kind != Token::kBIT_AND) {
126 op_kind != Token::kSUB && 162 // TODO(regis): Not yet supported.
127 op_kind != Token::kMUL && 163 return false;
128 op_kind != Token::kDIV) { 164 }
129 // TODO(vegorov): Not yet supported. 165 operands_type = BinaryOpComp::kMintOperands;
166 } else {
167 // TODO(srdjan): Not yet supported.
130 return false; 168 return false;
131 } 169 }
132
133 operands_type = BinaryOpComp::kDoubleOperands;
134 } else { 170 } else {
135 // TODO(srdjan): Not yet supported. 171 // TODO(srdjan): Not yet supported.
136 return false; 172 return false;
137 } 173 }
138 174
139 ASSERT(comp->instr() != NULL); 175 ASSERT(comp->instr() != NULL);
140 ASSERT(comp->InputCount() == 2); 176 ASSERT(comp->InputCount() == 2);
141 Value* left = comp->InputAt(0); 177 Value* left = comp->InputAt(0);
142 Value* right = comp->InputAt(1); 178 Value* right = comp->InputAt(1);
143 BinaryOpComp* bin_op = 179 BinaryOpComp* bin_op =
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 instr->computation()->Accept(this); 594 instr->computation()->Accept(this);
559 } 595 }
560 596
561 597
562 void FlowGraphOptimizer::VisitBind(BindInstr* instr) { 598 void FlowGraphOptimizer::VisitBind(BindInstr* instr) {
563 instr->computation()->Accept(this); 599 instr->computation()->Accept(this);
564 } 600 }
565 601
566 602
567 } // namespace dart 603 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intermediate_language_ia32.cc » ('j') | runtime/vm/intermediate_language_x64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698