OLD | NEW |
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.h" | 5 #include "vm/flow_graph.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 2034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2045 it.Current()->AsInvokeMathCFunction(); | 2045 it.Current()->AsInvokeMathCFunction(); |
2046 if ((math_unary->recognized_kind() == MethodRecognizer::kMathSin) || | 2046 if ((math_unary->recognized_kind() == MethodRecognizer::kMathSin) || |
2047 (math_unary->recognized_kind() == MethodRecognizer::kMathCos)) { | 2047 (math_unary->recognized_kind() == MethodRecognizer::kMathCos)) { |
2048 if (math_unary->HasUses()) { | 2048 if (math_unary->HasUses()) { |
2049 sin_cos_merge.Add(math_unary); | 2049 sin_cos_merge.Add(math_unary); |
2050 } | 2050 } |
2051 } | 2051 } |
2052 } | 2052 } |
2053 } | 2053 } |
2054 TryMergeTruncDivMod(&div_mod_merge); | 2054 TryMergeTruncDivMod(&div_mod_merge); |
2055 TryMergeMathUnary(&sin_cos_merge); | |
2056 } | 2055 } |
2057 } | 2056 } |
2058 | 2057 |
2059 | 2058 |
2060 // Returns true if use is dominated by the given instruction. | 2059 // Returns true if use is dominated by the given instruction. |
2061 // Note: uses that occur at instruction itself are not dominated by it. | 2060 // Note: uses that occur at instruction itself are not dominated by it. |
2062 static bool IsDominatedUse(Instruction* dom, Value* use) { | 2061 static bool IsDominatedUse(Instruction* dom, Value* use) { |
2063 BlockEntryInstr* dom_block = dom->GetBlock(); | 2062 BlockEntryInstr* dom_block = dom->GetBlock(); |
2064 | 2063 |
2065 Instruction* instr = use->instruction(); | 2064 Instruction* instr = use->instruction(); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2218 // Only one merge possible. Because canonicalization happens later, | 2217 // Only one merge possible. Because canonicalization happens later, |
2219 // more candidates are possible. | 2218 // more candidates are possible. |
2220 // TODO(srdjan): Allow merging of trunc-div/mod into truncDivMod. | 2219 // TODO(srdjan): Allow merging of trunc-div/mod into truncDivMod. |
2221 break; | 2220 break; |
2222 } | 2221 } |
2223 } | 2222 } |
2224 } | 2223 } |
2225 } | 2224 } |
2226 | 2225 |
2227 | 2226 |
2228 // Tries to merge MathUnary operations, in this case sine and cosine. | |
2229 void FlowGraph::TryMergeMathUnary( | |
2230 GrowableArray<InvokeMathCFunctionInstr*>* merge_candidates) { | |
2231 if (!FlowGraphCompiler::SupportsSinCos() || !CanUnboxDouble() || | |
2232 !FLAG_merge_sin_cos) { | |
2233 return; | |
2234 } | |
2235 if (merge_candidates->length() < 2) { | |
2236 // Need at least a SIN and a COS. | |
2237 return; | |
2238 } | |
2239 for (intptr_t i = 0; i < merge_candidates->length(); i++) { | |
2240 InvokeMathCFunctionInstr* curr_instr = (*merge_candidates)[i]; | |
2241 if (curr_instr == NULL) { | |
2242 // Instruction was merged already. | |
2243 continue; | |
2244 } | |
2245 const MethodRecognizer::Kind kind = curr_instr->recognized_kind(); | |
2246 ASSERT((kind == MethodRecognizer::kMathSin) || | |
2247 (kind == MethodRecognizer::kMathCos)); | |
2248 // Check if there is sin/cos binop with same inputs. | |
2249 const MethodRecognizer::Kind other_kind = | |
2250 (kind == MethodRecognizer::kMathSin) ? MethodRecognizer::kMathCos | |
2251 : MethodRecognizer::kMathSin; | |
2252 Definition* def = curr_instr->InputAt(0)->definition(); | |
2253 for (intptr_t k = i + 1; k < merge_candidates->length(); k++) { | |
2254 InvokeMathCFunctionInstr* other_op = (*merge_candidates)[k]; | |
2255 // 'other_op' can be NULL if it was already merged. | |
2256 if ((other_op != NULL) && (other_op->recognized_kind() == other_kind) && | |
2257 (other_op->InputAt(0)->definition() == def)) { | |
2258 (*merge_candidates)[k] = NULL; // Clear it. | |
2259 ASSERT(curr_instr->HasUses()); | |
2260 AppendExtractNthOutputForMerged(curr_instr, | |
2261 MergedMathInstr::OutputIndexOf(kind), | |
2262 kUnboxedDouble, kDoubleCid); | |
2263 ASSERT(other_op->HasUses()); | |
2264 AppendExtractNthOutputForMerged( | |
2265 other_op, MergedMathInstr::OutputIndexOf(other_kind), | |
2266 kUnboxedDouble, kDoubleCid); | |
2267 ZoneGrowableArray<Value*>* args = new (Z) ZoneGrowableArray<Value*>(1); | |
2268 args->Add(new (Z) Value(curr_instr->InputAt(0)->definition())); | |
2269 // Replace with SinCos. | |
2270 MergedMathInstr* sin_cos = new (Z) MergedMathInstr( | |
2271 args, curr_instr->DeoptimizationTarget(), MergedMathInstr::kSinCos); | |
2272 curr_instr->ReplaceWith(sin_cos, NULL); | |
2273 other_op->ReplaceUsesWith(sin_cos); | |
2274 other_op->RemoveFromGraph(); | |
2275 // Only one merge possible. Because canonicalization happens later, | |
2276 // more candidates are possible. | |
2277 // TODO(srdjan): Allow merging of sin/cos into sincos. | |
2278 break; | |
2279 } | |
2280 } | |
2281 } | |
2282 } | |
2283 | |
2284 | |
2285 void FlowGraph::AppendExtractNthOutputForMerged(Definition* instr, | 2227 void FlowGraph::AppendExtractNthOutputForMerged(Definition* instr, |
2286 intptr_t index, | 2228 intptr_t index, |
2287 Representation rep, | 2229 Representation rep, |
2288 intptr_t cid) { | 2230 intptr_t cid) { |
2289 ExtractNthOutputInstr* extract = | 2231 ExtractNthOutputInstr* extract = |
2290 new (Z) ExtractNthOutputInstr(new (Z) Value(instr), index, rep, cid); | 2232 new (Z) ExtractNthOutputInstr(new (Z) Value(instr), index, rep, cid); |
2291 instr->ReplaceUsesWith(extract); | 2233 instr->ReplaceUsesWith(extract); |
2292 InsertAfter(instr, extract, NULL, FlowGraph::kValue); | 2234 InsertAfter(instr, extract, NULL, FlowGraph::kValue); |
2293 } | 2235 } |
2294 | 2236 |
2295 | 2237 |
2296 } // namespace dart | 2238 } // namespace dart |
OLD | NEW |