diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h index 880d22523e..0236494d11 100644 --- a/src/arm/lithium-codegen-arm.h +++ b/src/arm/lithium-codegen-arm.h @@ -43,9 +43,9 @@ class SafepointGenerator; class LCodeGen BASE_EMBEDDED { public: - LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) + LCodeGen(LChunkBase* chunk, MacroAssembler* assembler, CompilationInfo* info) : zone_(info->zone()), - chunk_(chunk), + chunk_(static_cast(chunk)), masm_(assembler), info_(info), current_block_(-1), diff --git a/src/compiler.cc b/src/compiler.cc index 6340773eab..e341accd90 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -308,11 +308,19 @@ static bool MakeCrankshaftCode(CompilationInfo* info) { } if (graph != NULL) { - Handle optimized_code = graph->Compile(); - if (!optimized_code.is_null()) { - info->SetCode(optimized_code); - FinishOptimization(info->closure(), start); - return true; + SmartArrayPointer bailout_reason; + if (!graph->Optimize(&bailout_reason)) { + if (!bailout_reason.is_empty()) builder.Bailout(*bailout_reason); + } else { + LChunkBase* chunk = LChunkBase::NewChunk(graph); + if (chunk != NULL) { + Handle optimized_code = chunk->Codegen(); + if (!optimized_code.is_null()) { + info->SetCode(optimized_code); + FinishOptimization(info->closure(), start); + return true; + } + } } } diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 2ba79b9bf5..76ccc064f2 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -703,47 +703,6 @@ HGraph::HGraph(CompilationInfo* info) } -Handle HGraph::Compile() { - int values = GetMaximumValueID(); - if (values > LUnallocated::kMaxVirtualRegisters) { - if (FLAG_trace_bailout) { - PrintF("Not enough virtual registers for (values).\n"); - } - return Handle::null(); - } - LAllocator allocator(values, this); - LChunkBuilder builder(info(), this, &allocator); - LChunk* chunk = builder.Build(); - if (chunk == NULL) return Handle::null(); - - if (!allocator.Allocate(chunk)) { - if (FLAG_trace_bailout) { - PrintF("Not enough virtual registers (regalloc).\n"); - } - return Handle::null(); - } - - MacroAssembler assembler(isolate(), NULL, 0); - LCodeGen generator(chunk, &assembler, info()); - - chunk->MarkEmptyBlocks(); - - if (generator.GenerateCode()) { - if (FLAG_trace_codegen) { - PrintF("Crankshaft Compiler - "); - } - CodeGenerator::MakeCodePrologue(info()); - Code::Flags flags = Code::ComputeFlags(Code::OPTIMIZED_FUNCTION); - Handle code = - CodeGenerator::MakeCodeEpilogue(&assembler, flags, info()); - generator.FinishCode(code); - CodeGenerator::PrintCode(code, info()); - return code; - } - return Handle::null(); -} - - HBasicBlock* HGraph::CreateBasicBlock() { HBasicBlock* result = new(zone()) HBasicBlock(this); blocks_.Add(result, zone()); @@ -3122,48 +3081,55 @@ HGraph* HGraphBuilder::CreateGraph() { } } - graph()->OrderBlocks(); - graph()->AssignDominators(); + return graph(); +} + +bool HGraph::Optimize(SmartArrayPointer* bailout_reason) { + *bailout_reason = SmartArrayPointer(); + OrderBlocks(); + AssignDominators(); #ifdef DEBUG // Do a full verify after building the graph and computing dominators. - graph()->Verify(true); + Verify(true); #endif - graph()->PropagateDeoptimizingMark(); - if (!graph()->CheckConstPhiUses()) { - Bailout("Unsupported phi use of const variable"); - return NULL; + PropagateDeoptimizingMark(); + if (!CheckConstPhiUses()) { + *bailout_reason = SmartArrayPointer(StrDup( + "Unsupported phi use of const variable")); + return false; } - graph()->EliminateRedundantPhis(); - if (!graph()->CheckArgumentsPhiUses()) { - Bailout("Unsupported phi use of arguments"); - return NULL; + EliminateRedundantPhis(); + if (!CheckArgumentsPhiUses()) { + *bailout_reason = SmartArrayPointer(StrDup( + "Unsupported phi use of arguments")); + return false; } - if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis(); - graph()->CollectPhis(); + if (FLAG_eliminate_dead_phis) EliminateUnreachablePhis(); + CollectPhis(); - if (graph()->has_osr_loop_entry()) { - const ZoneList* phis = graph()->osr_loop_entry()->phis(); + if (has_osr_loop_entry()) { + const ZoneList* phis = osr_loop_entry()->phis(); for (int j = 0; j < phis->length(); j++) { HPhi* phi = phis->at(j); - graph()->osr_values()->at(phi->merged_index())->set_incoming_value(phi); + osr_values()->at(phi->merged_index())->set_incoming_value(phi); } } - HInferRepresentation rep(graph()); + HInferRepresentation rep(this); rep.Analyze(); - graph()->MarkDeoptimizeOnUndefined(); - graph()->InsertRepresentationChanges(); + MarkDeoptimizeOnUndefined(); + InsertRepresentationChanges(); - graph()->InitializeInferredTypes(); - graph()->Canonicalize(); + InitializeInferredTypes(); + Canonicalize(); // Perform common subexpression elimination and loop-invariant code motion. if (FLAG_use_gvn) { - HPhase phase("H_Global value numbering", graph()); - HGlobalValueNumberer gvn(graph(), info()); + HPhase phase("H_Global value numbering", this); + HGlobalValueNumberer gvn(this, info()); bool removed_side_effects = gvn.Analyze(); // Trigger a second analysis pass to further eliminate duplicate values that // could only be discovered by removing side-effect-generating instructions @@ -3175,19 +3141,19 @@ HGraph* HGraphBuilder::CreateGraph() { } if (FLAG_use_range) { - HRangeAnalysis rangeAnalysis(graph()); + HRangeAnalysis rangeAnalysis(this); rangeAnalysis.Analyze(); } - graph()->ComputeMinusZeroChecks(); + ComputeMinusZeroChecks(); // Eliminate redundant stack checks on backwards branches. - HStackCheckEliminator sce(graph()); + HStackCheckEliminator sce(this); sce.Process(); - graph()->EliminateRedundantBoundsChecks(); - graph()->DehoistSimpleArrayIndexComputations(); + EliminateRedundantBoundsChecks(); + DehoistSimpleArrayIndexComputations(); - return graph(); + return true; } diff --git a/src/hydrogen.h b/src/hydrogen.h index 93873b10f6..37db7accb5 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -281,8 +281,6 @@ class HGraph: public ZoneObject { void CollectPhis(); - Handle Compile(); - void set_undefined_constant(HConstant* constant) { undefined_constant_.set(constant); } @@ -313,6 +311,8 @@ class HGraph: public ZoneObject { return NULL; } + bool Optimize(SmartArrayPointer* bailout_reason); + #ifdef DEBUG void Verify(bool do_full_verify) const; #endif diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h index 2c6fb8bb90..ff906350b6 100644 --- a/src/ia32/lithium-codegen-ia32.h +++ b/src/ia32/lithium-codegen-ia32.h @@ -46,9 +46,9 @@ class SafepointGenerator; class LCodeGen BASE_EMBEDDED { public: - LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) + LCodeGen(LChunkBase* chunk, MacroAssembler* assembler, CompilationInfo* info) : zone_(info->zone()), - chunk_(chunk), + chunk_(static_cast(chunk)), masm_(assembler), info_(info), current_block_(-1), diff --git a/src/lithium-allocator.cc b/src/lithium-allocator.cc index bbc405ba0b..9134f373f3 100644 --- a/src/lithium-allocator.cc +++ b/src/lithium-allocator.cc @@ -1062,9 +1062,9 @@ void LAllocator::ResolvePhis(HBasicBlock* block) { } -bool LAllocator::Allocate(LChunk* chunk) { +bool LAllocator::Allocate(LChunkBase* chunk) { ASSERT(chunk_ == NULL); - chunk_ = chunk; + chunk_ = static_cast(chunk); MeetRegisterConstraints(); if (!AllocationOk()) return false; ResolvePhis(); diff --git a/src/lithium-allocator.h b/src/lithium-allocator.h index d47e33595a..6a060de8ff 100644 --- a/src/lithium-allocator.h +++ b/src/lithium-allocator.h @@ -445,7 +445,7 @@ class LAllocator BASE_EMBEDDED { // Returns the register kind required by the given virtual register. RegisterKind RequiredRegisterKind(int virtual_register) const; - bool Allocate(LChunk* chunk); + bool Allocate(LChunkBase* chunk); const ZoneList* live_ranges() const { return &live_ranges_; } const Vector* fixed_live_ranges() const { diff --git a/src/lithium.cc b/src/lithium.cc index c317cf4a93..4e429d9e50 100644 --- a/src/lithium.cc +++ b/src/lithium.cc @@ -31,12 +31,16 @@ #if V8_TARGET_ARCH_IA32 #include "ia32/lithium-ia32.h" +#include "ia32/lithium-codegen-ia32.h" #elif V8_TARGET_ARCH_X64 #include "x64/lithium-x64.h" +#include "x64/lithium-codegen-x64.h" #elif V8_TARGET_ARCH_ARM #include "arm/lithium-arm.h" +#include "arm/lithium-codegen-arm.h" #elif V8_TARGET_ARCH_MIPS #include "mips/lithium-mips.h" +#include "mips/lithium-codegen-mips.h" #else #error "Unknown architecture." #endif @@ -386,4 +390,50 @@ Representation LChunkBase::LookupLiteralRepresentation( } +LChunkBase* LChunkBase::NewChunk(HGraph* graph) { + int values = graph->GetMaximumValueID(); + if (values > LUnallocated::kMaxVirtualRegisters) { + if (FLAG_trace_bailout) { + PrintF("Not enough virtual registers for (values).\n"); + } + return NULL; + } + LAllocator allocator(values, graph); + LChunkBuilder builder(graph->info(), graph, &allocator); + LChunkBase* chunk = builder.Build(); + if (chunk == NULL) return NULL; + + if (!allocator.Allocate(chunk)) { + if (FLAG_trace_bailout) { + PrintF("Not enough virtual registers (regalloc).\n"); + } + return NULL; + } + + return chunk; +} + + +Handle LChunkBase::Codegen() { + MacroAssembler assembler(info()->isolate(), NULL, 0); + LCodeGen generator(this, &assembler, info()); + + MarkEmptyBlocks(); + + if (generator.GenerateCode()) { + if (FLAG_trace_codegen) { + PrintF("Crankshaft Compiler - "); + } + CodeGenerator::MakeCodePrologue(info()); + Code::Flags flags = Code::ComputeFlags(Code::OPTIMIZED_FUNCTION); + Handle code = + CodeGenerator::MakeCodeEpilogue(&assembler, flags, info()); + generator.FinishCode(code); + CodeGenerator::PrintCode(code, info()); + return code; + } + return Handle::null(); +} + + } } // namespace v8::internal diff --git a/src/lithium.h b/src/lithium.h index 686441e383..ceca5478e3 100644 --- a/src/lithium.h +++ b/src/lithium.h @@ -622,6 +622,7 @@ class DeepIterator BASE_EMBEDDED { }; +class LChunk; class LGap; class LLabel; @@ -629,13 +630,7 @@ class LLabel; // arch-specific LChunk classes. class LChunkBase: public ZoneObject { public: - LChunkBase(CompilationInfo* info, HGraph* graph) - : spill_slot_count_(0), - info_(info), - graph_(graph), - instructions_(32, graph->zone()), - pointer_maps_(8, graph->zone()), - inlined_closures_(1, graph->zone()) { } + static LChunkBase* NewChunk(HGraph* graph); void AddInstruction(LInstruction* instruction, HBasicBlock* block); LConstantOperand* DefineConstantOperand(HConstant* constant); @@ -668,7 +663,17 @@ class LChunkBase: public ZoneObject { Zone* zone() const { return info_->zone(); } + Handle Codegen(); + protected: + LChunkBase(CompilationInfo* info, HGraph* graph) + : spill_slot_count_(0), + info_(info), + graph_(graph), + instructions_(32, graph->zone()), + pointer_maps_(8, graph->zone()), + inlined_closures_(1, graph->zone()) { } + int spill_slot_count_; private: diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h index 148273dbf9..a1953e14ad 100644 --- a/src/mips/lithium-codegen-mips.h +++ b/src/mips/lithium-codegen-mips.h @@ -43,9 +43,9 @@ class SafepointGenerator; class LCodeGen BASE_EMBEDDED { public: - LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) + LCodeGen(LChunkBase* chunk, MacroAssembler* assembler, CompilationInfo* info) : zone_(info->zone()), - chunk_(chunk), + chunk_(static_cast(chunk)), masm_(assembler), info_(info), current_block_(-1), diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h index d7fe26b3aa..96ad6ae0a4 100644 --- a/src/x64/lithium-codegen-x64.h +++ b/src/x64/lithium-codegen-x64.h @@ -45,9 +45,9 @@ class SafepointGenerator; class LCodeGen BASE_EMBEDDED { public: - LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) + LCodeGen(LChunkBase* chunk, MacroAssembler* assembler, CompilationInfo* info) : zone_(info->zone()), - chunk_(chunk), + chunk_(static_cast(chunk)), masm_(assembler), info_(info), current_block_(-1),