OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 zone_(info->zone()), | 696 zone_(info->zone()), |
697 is_recursive_(false) { | 697 is_recursive_(false) { |
698 start_environment_ = | 698 start_environment_ = |
699 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); | 699 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); |
700 start_environment_->set_ast_id(AstNode::kFunctionEntryId); | 700 start_environment_->set_ast_id(AstNode::kFunctionEntryId); |
701 entry_block_ = CreateBasicBlock(); | 701 entry_block_ = CreateBasicBlock(); |
702 entry_block_->SetInitialEnvironment(start_environment_); | 702 entry_block_->SetInitialEnvironment(start_environment_); |
703 } | 703 } |
704 | 704 |
705 | 705 |
706 Handle<Code> HGraph::Compile() { | |
707 int values = GetMaximumValueID(); | |
708 if (values > LUnallocated::kMaxVirtualRegisters) { | |
709 if (FLAG_trace_bailout) { | |
710 PrintF("Not enough virtual registers for (values).\n"); | |
711 } | |
712 return Handle<Code>::null(); | |
713 } | |
714 LAllocator allocator(values, this); | |
715 LChunkBuilder builder(info(), this, &allocator); | |
716 LChunk* chunk = builder.Build(); | |
717 if (chunk == NULL) return Handle<Code>::null(); | |
718 | |
719 if (!allocator.Allocate(chunk)) { | |
720 if (FLAG_trace_bailout) { | |
721 PrintF("Not enough virtual registers (regalloc).\n"); | |
722 } | |
723 return Handle<Code>::null(); | |
724 } | |
725 | |
726 MacroAssembler assembler(isolate(), NULL, 0); | |
727 LCodeGen generator(chunk, &assembler, info()); | |
728 | |
729 chunk->MarkEmptyBlocks(); | |
730 | |
731 if (generator.GenerateCode()) { | |
732 if (FLAG_trace_codegen) { | |
733 PrintF("Crankshaft Compiler - "); | |
734 } | |
735 CodeGenerator::MakeCodePrologue(info()); | |
736 Code::Flags flags = Code::ComputeFlags(Code::OPTIMIZED_FUNCTION); | |
737 Handle<Code> code = | |
738 CodeGenerator::MakeCodeEpilogue(&assembler, flags, info()); | |
739 generator.FinishCode(code); | |
740 CodeGenerator::PrintCode(code, info()); | |
741 return code; | |
742 } | |
743 return Handle<Code>::null(); | |
744 } | |
745 | |
746 | |
747 HBasicBlock* HGraph::CreateBasicBlock() { | 706 HBasicBlock* HGraph::CreateBasicBlock() { |
748 HBasicBlock* result = new(zone()) HBasicBlock(this); | 707 HBasicBlock* result = new(zone()) HBasicBlock(this); |
749 blocks_.Add(result, zone()); | 708 blocks_.Add(result, zone()); |
750 return result; | 709 return result; |
751 } | 710 } |
752 | 711 |
753 | 712 |
754 void HGraph::Canonicalize() { | 713 void HGraph::Canonicalize() { |
755 if (!FLAG_use_canonicalizing) return; | 714 if (!FLAG_use_canonicalizing) return; |
756 HPhase phase("H_Canonicalize", this); | 715 HPhase phase("H_Canonicalize", this); |
(...skipping 2358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3115 VisitStatements(info()->function()->body()); | 3074 VisitStatements(info()->function()->body()); |
3116 if (HasStackOverflow()) return NULL; | 3075 if (HasStackOverflow()) return NULL; |
3117 | 3076 |
3118 if (current_block() != NULL) { | 3077 if (current_block() != NULL) { |
3119 HReturn* instr = new(zone()) HReturn(graph()->GetConstantUndefined()); | 3078 HReturn* instr = new(zone()) HReturn(graph()->GetConstantUndefined()); |
3120 current_block()->FinishExit(instr); | 3079 current_block()->FinishExit(instr); |
3121 set_current_block(NULL); | 3080 set_current_block(NULL); |
3122 } | 3081 } |
3123 } | 3082 } |
3124 | 3083 |
3125 graph()->OrderBlocks(); | 3084 return graph(); |
3126 graph()->AssignDominators(); | 3085 } |
| 3086 |
| 3087 bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) { |
| 3088 *bailout_reason = SmartArrayPointer<char>(); |
| 3089 OrderBlocks(); |
| 3090 AssignDominators(); |
3127 | 3091 |
3128 #ifdef DEBUG | 3092 #ifdef DEBUG |
3129 // Do a full verify after building the graph and computing dominators. | 3093 // Do a full verify after building the graph and computing dominators. |
3130 graph()->Verify(true); | 3094 Verify(true); |
3131 #endif | 3095 #endif |
3132 | 3096 |
3133 graph()->PropagateDeoptimizingMark(); | 3097 PropagateDeoptimizingMark(); |
3134 if (!graph()->CheckConstPhiUses()) { | 3098 if (!CheckConstPhiUses()) { |
3135 Bailout("Unsupported phi use of const variable"); | 3099 *bailout_reason = SmartArrayPointer<char>(StrDup( |
3136 return NULL; | 3100 "Unsupported phi use of const variable")); |
| 3101 return false; |
3137 } | 3102 } |
3138 graph()->EliminateRedundantPhis(); | 3103 EliminateRedundantPhis(); |
3139 if (!graph()->CheckArgumentsPhiUses()) { | 3104 if (!CheckArgumentsPhiUses()) { |
3140 Bailout("Unsupported phi use of arguments"); | 3105 *bailout_reason = SmartArrayPointer<char>(StrDup( |
3141 return NULL; | 3106 "Unsupported phi use of arguments")); |
| 3107 return false; |
3142 } | 3108 } |
3143 if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis(); | 3109 if (FLAG_eliminate_dead_phis) EliminateUnreachablePhis(); |
3144 graph()->CollectPhis(); | 3110 CollectPhis(); |
3145 | 3111 |
3146 if (graph()->has_osr_loop_entry()) { | 3112 if (has_osr_loop_entry()) { |
3147 const ZoneList<HPhi*>* phis = graph()->osr_loop_entry()->phis(); | 3113 const ZoneList<HPhi*>* phis = osr_loop_entry()->phis(); |
3148 for (int j = 0; j < phis->length(); j++) { | 3114 for (int j = 0; j < phis->length(); j++) { |
3149 HPhi* phi = phis->at(j); | 3115 HPhi* phi = phis->at(j); |
3150 graph()->osr_values()->at(phi->merged_index())->set_incoming_value(phi); | 3116 osr_values()->at(phi->merged_index())->set_incoming_value(phi); |
3151 } | 3117 } |
3152 } | 3118 } |
3153 | 3119 |
3154 HInferRepresentation rep(graph()); | 3120 HInferRepresentation rep(this); |
3155 rep.Analyze(); | 3121 rep.Analyze(); |
3156 | 3122 |
3157 graph()->MarkDeoptimizeOnUndefined(); | 3123 MarkDeoptimizeOnUndefined(); |
3158 graph()->InsertRepresentationChanges(); | 3124 InsertRepresentationChanges(); |
3159 | 3125 |
3160 graph()->InitializeInferredTypes(); | 3126 InitializeInferredTypes(); |
3161 graph()->Canonicalize(); | 3127 Canonicalize(); |
3162 | 3128 |
3163 // Perform common subexpression elimination and loop-invariant code motion. | 3129 // Perform common subexpression elimination and loop-invariant code motion. |
3164 if (FLAG_use_gvn) { | 3130 if (FLAG_use_gvn) { |
3165 HPhase phase("H_Global value numbering", graph()); | 3131 HPhase phase("H_Global value numbering", this); |
3166 HGlobalValueNumberer gvn(graph(), info()); | 3132 HGlobalValueNumberer gvn(this, info()); |
3167 bool removed_side_effects = gvn.Analyze(); | 3133 bool removed_side_effects = gvn.Analyze(); |
3168 // Trigger a second analysis pass to further eliminate duplicate values that | 3134 // Trigger a second analysis pass to further eliminate duplicate values that |
3169 // could only be discovered by removing side-effect-generating instructions | 3135 // could only be discovered by removing side-effect-generating instructions |
3170 // during the first pass. | 3136 // during the first pass. |
3171 if (FLAG_smi_only_arrays && removed_side_effects) { | 3137 if (FLAG_smi_only_arrays && removed_side_effects) { |
3172 removed_side_effects = gvn.Analyze(); | 3138 removed_side_effects = gvn.Analyze(); |
3173 ASSERT(!removed_side_effects); | 3139 ASSERT(!removed_side_effects); |
3174 } | 3140 } |
3175 } | 3141 } |
3176 | 3142 |
3177 if (FLAG_use_range) { | 3143 if (FLAG_use_range) { |
3178 HRangeAnalysis rangeAnalysis(graph()); | 3144 HRangeAnalysis rangeAnalysis(this); |
3179 rangeAnalysis.Analyze(); | 3145 rangeAnalysis.Analyze(); |
3180 } | 3146 } |
3181 graph()->ComputeMinusZeroChecks(); | 3147 ComputeMinusZeroChecks(); |
3182 | 3148 |
3183 // Eliminate redundant stack checks on backwards branches. | 3149 // Eliminate redundant stack checks on backwards branches. |
3184 HStackCheckEliminator sce(graph()); | 3150 HStackCheckEliminator sce(this); |
3185 sce.Process(); | 3151 sce.Process(); |
3186 | 3152 |
3187 graph()->EliminateRedundantBoundsChecks(); | 3153 EliminateRedundantBoundsChecks(); |
3188 graph()->DehoistSimpleArrayIndexComputations(); | 3154 DehoistSimpleArrayIndexComputations(); |
3189 | 3155 |
3190 return graph(); | 3156 return true; |
3191 } | 3157 } |
3192 | 3158 |
3193 | 3159 |
3194 // We try to "factor up" HBoundsCheck instructions towards the root of the | 3160 // We try to "factor up" HBoundsCheck instructions towards the root of the |
3195 // dominator tree. | 3161 // dominator tree. |
3196 // For now we handle checks where the index is like "exp + int32value". | 3162 // For now we handle checks where the index is like "exp + int32value". |
3197 // If in the dominator tree we check "exp + v1" and later (dominated) | 3163 // If in the dominator tree we check "exp + v1" and later (dominated) |
3198 // "exp + v2", if v2 <= v1 we can safely remove the second check, and if | 3164 // "exp + v2", if v2 <= v1 we can safely remove the second check, and if |
3199 // v2 > v1 we can use v2 in the 1st check and again remove the second. | 3165 // v2 > v1 we can use v2 in the 1st check and again remove the second. |
3200 // To do so we keep a dictionary of all checks where the key if the pair | 3166 // To do so we keep a dictionary of all checks where the key if the pair |
(...skipping 6365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9566 } | 9532 } |
9567 } | 9533 } |
9568 | 9534 |
9569 #ifdef DEBUG | 9535 #ifdef DEBUG |
9570 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 9536 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
9571 if (allocator_ != NULL) allocator_->Verify(); | 9537 if (allocator_ != NULL) allocator_->Verify(); |
9572 #endif | 9538 #endif |
9573 } | 9539 } |
9574 | 9540 |
9575 } } // namespace v8::internal | 9541 } } // namespace v8::internal |
OLD | NEW |