| 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 |