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 19 matching lines...) Expand all Loading... | |
30 | 30 |
31 #include "codegen.h" | 31 #include "codegen.h" |
32 #include "full-codegen.h" | 32 #include "full-codegen.h" |
33 #include "hashmap.h" | 33 #include "hashmap.h" |
34 #include "lithium-allocator.h" | 34 #include "lithium-allocator.h" |
35 #include "parser.h" | 35 #include "parser.h" |
36 #include "scopeinfo.h" | 36 #include "scopeinfo.h" |
37 #include "scopes.h" | 37 #include "scopes.h" |
38 #include "stub-cache.h" | 38 #include "stub-cache.h" |
39 | 39 |
40 #if V8_TARGET_ARCH_IA32 | 40 #if V8_TARGET_ARCH_IA32 |
sanjoy
2012/07/11 09:55:53
This #include block is needed only by HTracer now.
| |
41 #include "ia32/lithium-codegen-ia32.h" | 41 #include "ia32/lithium-codegen-ia32.h" |
42 #elif V8_TARGET_ARCH_X64 | 42 #elif V8_TARGET_ARCH_X64 |
43 #include "x64/lithium-codegen-x64.h" | 43 #include "x64/lithium-codegen-x64.h" |
44 #elif V8_TARGET_ARCH_ARM | 44 #elif V8_TARGET_ARCH_ARM |
45 #include "arm/lithium-codegen-arm.h" | 45 #include "arm/lithium-codegen-arm.h" |
46 #elif V8_TARGET_ARCH_MIPS | 46 #elif V8_TARGET_ARCH_MIPS |
47 #include "mips/lithium-codegen-mips.h" | 47 #include "mips/lithium-codegen-mips.h" |
48 #else | 48 #else |
49 #error Unsupported target architecture. | 49 #error Unsupported target architecture. |
50 #endif | 50 #endif |
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
684 zone_(info->zone()), | 684 zone_(info->zone()), |
685 is_recursive_(false) { | 685 is_recursive_(false) { |
686 start_environment_ = | 686 start_environment_ = |
687 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); | 687 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); |
688 start_environment_->set_ast_id(AstNode::kFunctionEntryId); | 688 start_environment_->set_ast_id(AstNode::kFunctionEntryId); |
689 entry_block_ = CreateBasicBlock(); | 689 entry_block_ = CreateBasicBlock(); |
690 entry_block_->SetInitialEnvironment(start_environment_); | 690 entry_block_->SetInitialEnvironment(start_environment_); |
691 } | 691 } |
692 | 692 |
693 | 693 |
694 Handle<Code> HGraph::Compile() { | |
695 int values = GetMaximumValueID(); | |
696 if (values > LUnallocated::kMaxVirtualRegisters) { | |
697 if (FLAG_trace_bailout) { | |
698 PrintF("Not enough virtual registers for (values).\n"); | |
699 } | |
700 return Handle<Code>::null(); | |
701 } | |
702 LAllocator allocator(values, this); | |
703 LChunkBuilder builder(info(), this, &allocator); | |
704 LChunk* chunk = builder.Build(); | |
705 if (chunk == NULL) return Handle<Code>::null(); | |
706 | |
707 if (!allocator.Allocate(chunk)) { | |
708 if (FLAG_trace_bailout) { | |
709 PrintF("Not enough virtual registers (regalloc).\n"); | |
710 } | |
711 return Handle<Code>::null(); | |
712 } | |
713 | |
714 MacroAssembler assembler(isolate(), NULL, 0); | |
715 LCodeGen generator(chunk, &assembler, info()); | |
716 | |
717 chunk->MarkEmptyBlocks(); | |
718 | |
719 if (generator.GenerateCode()) { | |
720 if (FLAG_trace_codegen) { | |
721 PrintF("Crankshaft Compiler - "); | |
722 } | |
723 CodeGenerator::MakeCodePrologue(info()); | |
724 Code::Flags flags = Code::ComputeFlags(Code::OPTIMIZED_FUNCTION); | |
725 Handle<Code> code = | |
726 CodeGenerator::MakeCodeEpilogue(&assembler, flags, info()); | |
727 generator.FinishCode(code); | |
728 CodeGenerator::PrintCode(code, info()); | |
729 return code; | |
730 } | |
731 return Handle<Code>::null(); | |
732 } | |
733 | |
734 | |
735 HBasicBlock* HGraph::CreateBasicBlock() { | 694 HBasicBlock* HGraph::CreateBasicBlock() { |
736 HBasicBlock* result = new(zone()) HBasicBlock(this); | 695 HBasicBlock* result = new(zone()) HBasicBlock(this); |
737 blocks_.Add(result, zone()); | 696 blocks_.Add(result, zone()); |
738 return result; | 697 return result; |
739 } | 698 } |
740 | 699 |
741 | 700 |
742 void HGraph::Canonicalize() { | 701 void HGraph::Canonicalize() { |
743 if (!FLAG_use_canonicalizing) return; | 702 if (!FLAG_use_canonicalizing) return; |
744 HPhase phase("H_Canonicalize", this); | 703 HPhase phase("H_Canonicalize", this); |
(...skipping 2358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3103 VisitStatements(info()->function()->body()); | 3062 VisitStatements(info()->function()->body()); |
3104 if (HasStackOverflow()) return NULL; | 3063 if (HasStackOverflow()) return NULL; |
3105 | 3064 |
3106 if (current_block() != NULL) { | 3065 if (current_block() != NULL) { |
3107 HReturn* instr = new(zone()) HReturn(graph()->GetConstantUndefined()); | 3066 HReturn* instr = new(zone()) HReturn(graph()->GetConstantUndefined()); |
3108 current_block()->FinishExit(instr); | 3067 current_block()->FinishExit(instr); |
3109 set_current_block(NULL); | 3068 set_current_block(NULL); |
3110 } | 3069 } |
3111 } | 3070 } |
3112 | 3071 |
3113 graph()->OrderBlocks(); | 3072 return graph(); |
3114 graph()->AssignDominators(); | 3073 } |
3074 | |
3075 bool HGraph::Optimize(const char** bailout_reason) { | |
danno
2012/07/11 10:04:57
Memory management/owner is totally unclear for the
| |
3076 OrderBlocks(); | |
3077 AssignDominators(); | |
3115 | 3078 |
3116 #ifdef DEBUG | 3079 #ifdef DEBUG |
3117 // Do a full verify after building the graph and computing dominators. | 3080 // Do a full verify after building the graph and computing dominators. |
3118 graph()->Verify(true); | 3081 Verify(true); |
3119 #endif | 3082 #endif |
3120 | 3083 |
3121 graph()->PropagateDeoptimizingMark(); | 3084 PropagateDeoptimizingMark(); |
3122 if (!graph()->CheckConstPhiUses()) { | 3085 if (!CheckConstPhiUses()) { |
3123 Bailout("Unsupported phi use of const variable"); | 3086 *bailout_reason = "Unsupported phi use of const variable"; |
3124 return NULL; | 3087 return false; |
3125 } | 3088 } |
3126 graph()->EliminateRedundantPhis(); | 3089 EliminateRedundantPhis(); |
3127 if (!graph()->CheckArgumentsPhiUses()) { | 3090 if (!CheckArgumentsPhiUses()) { |
3128 Bailout("Unsupported phi use of arguments"); | 3091 *bailout_reason = "Unsupported phi use of arguments"; |
3129 return NULL; | 3092 return false; |
3130 } | 3093 } |
3131 if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis(); | 3094 if (FLAG_eliminate_dead_phis) EliminateUnreachablePhis(); |
3132 graph()->CollectPhis(); | 3095 CollectPhis(); |
3133 | 3096 |
3134 if (graph()->has_osr_loop_entry()) { | 3097 if (has_osr_loop_entry()) { |
3135 const ZoneList<HPhi*>* phis = graph()->osr_loop_entry()->phis(); | 3098 const ZoneList<HPhi*>* phis = osr_loop_entry()->phis(); |
3136 for (int j = 0; j < phis->length(); j++) { | 3099 for (int j = 0; j < phis->length(); j++) { |
3137 HPhi* phi = phis->at(j); | 3100 HPhi* phi = phis->at(j); |
3138 graph()->osr_values()->at(phi->merged_index())->set_incoming_value(phi); | 3101 osr_values()->at(phi->merged_index())->set_incoming_value(phi); |
3139 } | 3102 } |
3140 } | 3103 } |
3141 | 3104 |
3142 HInferRepresentation rep(graph()); | 3105 HInferRepresentation rep(this); |
3143 rep.Analyze(); | 3106 rep.Analyze(); |
3144 | 3107 |
3145 graph()->MarkDeoptimizeOnUndefined(); | 3108 MarkDeoptimizeOnUndefined(); |
3146 graph()->InsertRepresentationChanges(); | 3109 InsertRepresentationChanges(); |
3147 | 3110 |
3148 graph()->InitializeInferredTypes(); | 3111 InitializeInferredTypes(); |
3149 graph()->Canonicalize(); | 3112 Canonicalize(); |
3150 | 3113 |
3151 // Perform common subexpression elimination and loop-invariant code motion. | 3114 // Perform common subexpression elimination and loop-invariant code motion. |
3152 if (FLAG_use_gvn) { | 3115 if (FLAG_use_gvn) { |
3153 HPhase phase("H_Global value numbering", graph()); | 3116 HPhase phase("H_Global value numbering", this); |
3154 HGlobalValueNumberer gvn(graph(), info()); | 3117 HGlobalValueNumberer gvn(this, info()); |
3155 bool removed_side_effects = gvn.Analyze(); | 3118 bool removed_side_effects = gvn.Analyze(); |
3156 // Trigger a second analysis pass to further eliminate duplicate values that | 3119 // Trigger a second analysis pass to further eliminate duplicate values that |
3157 // could only be discovered by removing side-effect-generating instructions | 3120 // could only be discovered by removing side-effect-generating instructions |
3158 // during the first pass. | 3121 // during the first pass. |
3159 if (FLAG_smi_only_arrays && removed_side_effects) { | 3122 if (FLAG_smi_only_arrays && removed_side_effects) { |
3160 removed_side_effects = gvn.Analyze(); | 3123 removed_side_effects = gvn.Analyze(); |
3161 ASSERT(!removed_side_effects); | 3124 ASSERT(!removed_side_effects); |
3162 } | 3125 } |
3163 } | 3126 } |
3164 | 3127 |
3165 if (FLAG_use_range) { | 3128 if (FLAG_use_range) { |
3166 HRangeAnalysis rangeAnalysis(graph()); | 3129 HRangeAnalysis rangeAnalysis(this); |
3167 rangeAnalysis.Analyze(); | 3130 rangeAnalysis.Analyze(); |
3168 } | 3131 } |
3169 graph()->ComputeMinusZeroChecks(); | 3132 ComputeMinusZeroChecks(); |
3170 | 3133 |
3171 // Eliminate redundant stack checks on backwards branches. | 3134 // Eliminate redundant stack checks on backwards branches. |
3172 HStackCheckEliminator sce(graph()); | 3135 HStackCheckEliminator sce(this); |
3173 sce.Process(); | 3136 sce.Process(); |
3174 | 3137 |
3175 graph()->EliminateRedundantBoundsChecks(); | 3138 EliminateRedundantBoundsChecks(); |
3176 graph()->DehoistSimpleArrayIndexComputations(); | 3139 DehoistSimpleArrayIndexComputations(); |
3177 | 3140 |
3178 return graph(); | 3141 return true; |
3179 } | 3142 } |
3180 | 3143 |
3181 | 3144 |
3182 // We try to "factor up" HBoundsCheck instructions towards the root of the | 3145 // We try to "factor up" HBoundsCheck instructions towards the root of the |
3183 // dominator tree. | 3146 // dominator tree. |
3184 // For now we handle checks where the index is like "exp + int32value". | 3147 // For now we handle checks where the index is like "exp + int32value". |
3185 // If in the dominator tree we check "exp + v1" and later (dominated) | 3148 // If in the dominator tree we check "exp + v1" and later (dominated) |
3186 // "exp + v2", if v2 <= v1 we can safely remove the second check, and if | 3149 // "exp + v2", if v2 <= v1 we can safely remove the second check, and if |
3187 // v2 > v1 we can use v2 in the 1st check and again remove the second. | 3150 // v2 > v1 we can use v2 in the 1st check and again remove the second. |
3188 // To do so we keep a dictionary of all checks where the key if the pair | 3151 // To do so we keep a dictionary of all checks where the key if the pair |
(...skipping 6381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9570 } | 9533 } |
9571 } | 9534 } |
9572 | 9535 |
9573 #ifdef DEBUG | 9536 #ifdef DEBUG |
9574 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 9537 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
9575 if (allocator_ != NULL) allocator_->Verify(); | 9538 if (allocator_ != NULL) allocator_->Verify(); |
9576 #endif | 9539 #endif |
9577 } | 9540 } |
9578 | 9541 |
9579 } } // namespace v8::internal | 9542 } } // namespace v8::internal |
OLD | NEW |