Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
| 9 #include "vm/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
| 10 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 160 | 160 |
| 161 const bool with_checks = false; | 161 const bool with_checks = false; |
| 162 PolymorphicInstanceCallInstr* specialized = | 162 PolymorphicInstanceCallInstr* specialized = |
| 163 new PolymorphicInstanceCallInstr(call->instance_call(), | 163 new PolymorphicInstanceCallInstr(call->instance_call(), |
| 164 ic_data, | 164 ic_data, |
| 165 with_checks); | 165 with_checks); |
| 166 call->ReplaceWith(specialized, current_iterator()); | 166 call->ReplaceWith(specialized, current_iterator()); |
| 167 } | 167 } |
| 168 | 168 |
| 169 | 169 |
| 170 static BinarySmiOpInstr* AsSmiLeftShiftInstruction(Value* v) { | |
| 171 BinarySmiOpInstr* instr = v->definition()->AsBinarySmiOp(); | |
| 172 if ((instr != NULL) && (instr->op_kind() == Token::kSHL)) { | |
| 173 return instr; | |
| 174 } | |
| 175 return NULL; | |
| 176 } | |
| 177 | |
| 178 | |
| 179 Value* AsPositiveSmiConstValue(Value* v) { | |
| 180 if (v->BindsToConstant() && v->BoundConstant().IsSmi()) { | |
| 181 if (Smi::Cast(v->BoundConstant()).Value() >= 0) { | |
| 182 return v; | |
| 183 } | |
| 184 } | |
| 185 return NULL; | |
| 186 } | |
| 187 | |
| 188 | |
| 189 void FlowGraphOptimizer::OptimizeLeftShiftBitAndSmiOp( | |
| 190 Definition* bit_and_instr, | |
| 191 Value* left, | |
| 192 Value* right) { | |
| 193 // Both left and right may have only one use. | |
|
Vyacheslav Egorov (Google)
2013/02/20 00:37:06
The constant can have many uses it does not invali
srdjan
2013/02/21 00:47:17
Done.
| |
| 194 if ((left->next_use() != NULL) || (left->previous_use() != NULL)) { | |
| 195 return; | |
| 196 } | |
| 197 if ((right->next_use() != NULL) || (right->previous_use() != NULL)) { | |
| 198 return; | |
| 199 } | |
|
Vyacheslav Egorov (Google)
2013/02/20 00:37:06
This does not check for environment uses. I think
srdjan
2013/02/21 00:47:17
It fails, thanks. Added to test suite. Punted on f
| |
| 200 // Check for pattern | |
| 201 BinarySmiOpInstr* smi_left_shift = NULL; | |
| 202 Value* smi_const = AsPositiveSmiConstValue(left); | |
| 203 if (smi_const == NULL) { | |
| 204 smi_const = AsPositiveSmiConstValue(right); | |
| 205 if (smi_const != NULL) { | |
| 206 smi_left_shift = AsSmiLeftShiftInstruction(left); | |
| 207 } | |
| 208 } else { | |
| 209 smi_left_shift = AsSmiLeftShiftInstruction(right); | |
| 210 } | |
| 211 if ((smi_left_shift == NULL) || (smi_const == NULL)) { | |
| 212 // Not the pattern 'BIT_AND with smi-left-shift and smi-constant'. | |
| 213 return; | |
| 214 } | |
| 215 if (bit_and_instr->IsBinarySmiOp()) { | |
| 216 smi_left_shift->set_is_truncating(true); | |
| 217 } else { | |
| 218 ASSERT(bit_and_instr->IsBinaryMintOp()); | |
| 219 smi_left_shift->set_is_truncating(true); | |
| 220 // Replace Mint op with Smi op. | |
| 221 BinarySmiOpInstr* smi_op = new BinarySmiOpInstr( | |
| 222 Token::kBIT_AND, | |
| 223 bit_and_instr->AsBinaryMintOp()->instance_call(), | |
| 224 left->Copy(), | |
| 225 right->Copy()); | |
| 226 bit_and_instr->ReplaceWith(smi_op, current_iterator()); | |
| 227 } | |
| 228 } | |
| 229 | |
| 230 | |
| 231 // Optimize (a << b) & c pattern: if c is a positive smi, then the | |
| 232 // shift can be a truncating Smi shift and result is always Smi. | |
| 233 void FlowGraphOptimizer::TryOptimizeLeftShiftWithBitAndPattern() { | |
| 234 ASSERT(current_iterator_ == NULL); | |
| 235 for (intptr_t i = 0; i < block_order_.length(); ++i) { | |
| 236 BlockEntryInstr* entry = block_order_[i]; | |
| 237 ForwardInstructionIterator it(entry); | |
| 238 current_iterator_ = ⁢ | |
| 239 for (; !it.Done(); it.Advance()) { | |
| 240 if (it.Current()->IsBinarySmiOp()) { | |
| 241 BinarySmiOpInstr* binop = it.Current()->AsBinarySmiOp(); | |
| 242 if (binop->op_kind() == Token::kBIT_AND) { | |
| 243 OptimizeLeftShiftBitAndSmiOp(binop, binop->left(), binop->right()); | |
| 244 } | |
| 245 } else if (it.Current()->IsBinaryMintOp()) { | |
| 246 BinaryMintOpInstr* mintop = it.Current()->AsBinaryMintOp(); | |
| 247 if (mintop->op_kind() == Token::kBIT_AND) { | |
| 248 OptimizeLeftShiftBitAndSmiOp(mintop, mintop->left(), mintop->right()); | |
| 249 } | |
| 250 } | |
| 251 } | |
| 252 current_iterator_ = NULL; | |
| 253 } | |
| 254 } | |
| 255 | |
| 256 | |
| 170 static void EnsureSSATempIndex(FlowGraph* graph, | 257 static void EnsureSSATempIndex(FlowGraph* graph, |
| 171 Definition* defn, | 258 Definition* defn, |
| 172 Definition* replacement) { | 259 Definition* replacement) { |
| 173 if ((replacement->ssa_temp_index() == -1) && | 260 if ((replacement->ssa_temp_index() == -1) && |
| 174 (defn->ssa_temp_index() != -1)) { | 261 (defn->ssa_temp_index() != -1)) { |
| 175 replacement->set_ssa_temp_index(graph->alloc_ssa_temp_index()); | 262 replacement->set_ssa_temp_index(graph->alloc_ssa_temp_index()); |
| 176 } | 263 } |
| 177 } | 264 } |
| 178 | 265 |
| 179 | 266 |
| (...skipping 4006 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4186 | 4273 |
| 4187 if (FLAG_trace_constant_propagation) { | 4274 if (FLAG_trace_constant_propagation) { |
| 4188 OS::Print("\n==== After constant propagation ====\n"); | 4275 OS::Print("\n==== After constant propagation ====\n"); |
| 4189 FlowGraphPrinter printer(*graph_); | 4276 FlowGraphPrinter printer(*graph_); |
| 4190 printer.PrintBlocks(); | 4277 printer.PrintBlocks(); |
| 4191 } | 4278 } |
| 4192 } | 4279 } |
| 4193 | 4280 |
| 4194 | 4281 |
| 4195 } // namespace dart | 4282 } // namespace dart |
| OLD | NEW |