OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 19 matching lines...) Expand all Loading... |
30 #include <algorithm> | 30 #include <algorithm> |
31 | 31 |
32 #include "v8.h" | 32 #include "v8.h" |
33 #include "codegen.h" | 33 #include "codegen.h" |
34 #include "full-codegen.h" | 34 #include "full-codegen.h" |
35 #include "hashmap.h" | 35 #include "hashmap.h" |
36 #include "hydrogen-bce.h" | 36 #include "hydrogen-bce.h" |
37 #include "hydrogen-canonicalize.h" | 37 #include "hydrogen-canonicalize.h" |
38 #include "hydrogen-dce.h" | 38 #include "hydrogen-dce.h" |
39 #include "hydrogen-dehoist.h" | 39 #include "hydrogen-dehoist.h" |
| 40 #include "hydrogen-deoptimizing-mark.h" |
40 #include "hydrogen-environment-liveness.h" | 41 #include "hydrogen-environment-liveness.h" |
41 #include "hydrogen-escape-analysis.h" | 42 #include "hydrogen-escape-analysis.h" |
42 #include "hydrogen-infer-representation.h" | 43 #include "hydrogen-infer-representation.h" |
43 #include "hydrogen-infer-types.h" | 44 #include "hydrogen-infer-types.h" |
44 #include "hydrogen-gvn.h" | 45 #include "hydrogen-gvn.h" |
45 #include "hydrogen-minus-zero.h" | 46 #include "hydrogen-minus-zero.h" |
46 #include "hydrogen-osr.h" | 47 #include "hydrogen-osr.h" |
47 #include "hydrogen-range-analysis.h" | 48 #include "hydrogen-range-analysis.h" |
48 #include "hydrogen-redundant-phi.h" | 49 #include "hydrogen-redundant-phi.h" |
49 #include "hydrogen-removable-simulates.h" | 50 #include "hydrogen-removable-simulates.h" |
(...skipping 2370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2420 block->AssignLoopSuccessorDominators(); | 2421 block->AssignLoopSuccessorDominators(); |
2421 } else { | 2422 } else { |
2422 for (int j = blocks_[i]->predecessors()->length() - 1; j >= 0; --j) { | 2423 for (int j = blocks_[i]->predecessors()->length() - 1; j >= 0; --j) { |
2423 blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j)); | 2424 blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j)); |
2424 } | 2425 } |
2425 } | 2426 } |
2426 } | 2427 } |
2427 } | 2428 } |
2428 | 2429 |
2429 | 2430 |
2430 // Mark all blocks that are dominated by an unconditional soft deoptimize to | |
2431 // prevent code motion across those blocks. | |
2432 void HGraph::PropagateDeoptimizingMark() { | |
2433 HPhase phase("H_Propagate deoptimizing mark", this); | |
2434 // Skip this phase if there is nothing to be done anyway. | |
2435 if (!has_soft_deoptimize()) return; | |
2436 MarkAsDeoptimizingRecursively(entry_block()); | |
2437 NullifyUnreachableInstructions(); | |
2438 } | |
2439 | |
2440 | |
2441 void HGraph::MarkAsDeoptimizingRecursively(HBasicBlock* block) { | |
2442 for (int i = 0; i < block->dominated_blocks()->length(); ++i) { | |
2443 HBasicBlock* dominated = block->dominated_blocks()->at(i); | |
2444 if (block->IsDeoptimizing()) dominated->MarkAsDeoptimizing(); | |
2445 MarkAsDeoptimizingRecursively(dominated); | |
2446 } | |
2447 } | |
2448 | |
2449 | |
2450 void HGraph::NullifyUnreachableInstructions() { | |
2451 if (!FLAG_unreachable_code_elimination) return; | |
2452 int block_count = blocks_.length(); | |
2453 for (int i = 0; i < block_count; ++i) { | |
2454 HBasicBlock* block = blocks_.at(i); | |
2455 bool nullify = false; | |
2456 const ZoneList<HBasicBlock*>* predecessors = block->predecessors(); | |
2457 int predecessors_length = predecessors->length(); | |
2458 bool all_predecessors_deoptimizing = (predecessors_length > 0); | |
2459 for (int j = 0; j < predecessors_length; ++j) { | |
2460 if (!predecessors->at(j)->IsDeoptimizing()) { | |
2461 all_predecessors_deoptimizing = false; | |
2462 break; | |
2463 } | |
2464 } | |
2465 if (all_predecessors_deoptimizing) nullify = true; | |
2466 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { | |
2467 HInstruction* instr = it.Current(); | |
2468 // Leave the basic structure of the graph intact. | |
2469 if (instr->IsBlockEntry()) continue; | |
2470 if (instr->IsControlInstruction()) continue; | |
2471 if (instr->IsSimulate()) continue; | |
2472 if (instr->IsEnterInlined()) continue; | |
2473 if (instr->IsLeaveInlined()) continue; | |
2474 if (nullify) { | |
2475 HInstruction* last_dummy = NULL; | |
2476 for (int j = 0; j < instr->OperandCount(); ++j) { | |
2477 HValue* operand = instr->OperandAt(j); | |
2478 // Insert an HDummyUse for each operand, unless the operand | |
2479 // is an HDummyUse itself. If it's even from the same block, | |
2480 // remember it as a potential replacement for the instruction. | |
2481 if (operand->IsDummyUse()) { | |
2482 if (operand->block() == instr->block() && | |
2483 last_dummy == NULL) { | |
2484 last_dummy = HInstruction::cast(operand); | |
2485 } | |
2486 continue; | |
2487 } | |
2488 if (operand->IsControlInstruction()) { | |
2489 // Inserting a dummy use for a value that's not defined anywhere | |
2490 // will fail. Some instructions define fake inputs on such | |
2491 // values as control flow dependencies. | |
2492 continue; | |
2493 } | |
2494 HDummyUse* dummy = new(zone()) HDummyUse(operand); | |
2495 dummy->InsertBefore(instr); | |
2496 last_dummy = dummy; | |
2497 } | |
2498 if (last_dummy == NULL) last_dummy = GetConstant1(); | |
2499 instr->DeleteAndReplaceWith(last_dummy); | |
2500 continue; | |
2501 } | |
2502 if (instr->IsSoftDeoptimize()) { | |
2503 ASSERT(block->IsDeoptimizing()); | |
2504 nullify = true; | |
2505 } | |
2506 } | |
2507 } | |
2508 } | |
2509 | |
2510 | |
2511 bool HGraph::CheckArgumentsPhiUses() { | 2431 bool HGraph::CheckArgumentsPhiUses() { |
2512 int block_count = blocks_.length(); | 2432 int block_count = blocks_.length(); |
2513 for (int i = 0; i < block_count; ++i) { | 2433 for (int i = 0; i < block_count; ++i) { |
2514 for (int j = 0; j < blocks_[i]->phis()->length(); ++j) { | 2434 for (int j = 0; j < blocks_[i]->phis()->length(); ++j) { |
2515 HPhi* phi = blocks_[i]->phis()->at(j); | 2435 HPhi* phi = blocks_[i]->phis()->at(j); |
2516 // We don't support phi uses of arguments for now. | 2436 // We don't support phi uses of arguments for now. |
2517 if (phi->CheckFlag(HValue::kIsArguments)) return false; | 2437 if (phi->CheckFlag(HValue::kIsArguments)) return false; |
2518 } | 2438 } |
2519 } | 2439 } |
2520 return true; | 2440 return true; |
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3019 | 2939 |
3020 #ifdef DEBUG | 2940 #ifdef DEBUG |
3021 // Do a full verify after building the graph and computing dominators. | 2941 // Do a full verify after building the graph and computing dominators. |
3022 Verify(true); | 2942 Verify(true); |
3023 #endif | 2943 #endif |
3024 | 2944 |
3025 if (FLAG_analyze_environment_liveness && maximum_environment_size() != 0) { | 2945 if (FLAG_analyze_environment_liveness && maximum_environment_size() != 0) { |
3026 Run<HEnvironmentLivenessAnalysisPhase>(); | 2946 Run<HEnvironmentLivenessAnalysisPhase>(); |
3027 } | 2947 } |
3028 | 2948 |
3029 PropagateDeoptimizingMark(); | 2949 Run<HPropagateDeoptimizingMarkPhase>(); |
3030 if (!CheckConstPhiUses()) { | 2950 if (!CheckConstPhiUses()) { |
3031 *bailout_reason = SmartArrayPointer<char>(StrDup( | 2951 *bailout_reason = SmartArrayPointer<char>(StrDup( |
3032 "Unsupported phi use of const variable")); | 2952 "Unsupported phi use of const variable")); |
3033 return false; | 2953 return false; |
3034 } | 2954 } |
3035 Run<HRedundantPhiEliminationPhase>(); | 2955 Run<HRedundantPhiEliminationPhase>(); |
3036 if (!CheckArgumentsPhiUses()) { | 2956 if (!CheckArgumentsPhiUses()) { |
3037 *bailout_reason = SmartArrayPointer<char>(StrDup( | 2957 *bailout_reason = SmartArrayPointer<char>(StrDup( |
3038 "Unsupported phi use of arguments")); | 2958 "Unsupported phi use of arguments")); |
3039 return false; | 2959 return false; |
(...skipping 6991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10031 if (ShouldProduceTraceOutput()) { | 9951 if (ShouldProduceTraceOutput()) { |
10032 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9952 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10033 } | 9953 } |
10034 | 9954 |
10035 #ifdef DEBUG | 9955 #ifdef DEBUG |
10036 graph_->Verify(false); // No full verify. | 9956 graph_->Verify(false); // No full verify. |
10037 #endif | 9957 #endif |
10038 } | 9958 } |
10039 | 9959 |
10040 } } // namespace v8::internal | 9960 } } // namespace v8::internal |
OLD | NEW |