Break Crankshaft into phases.

Crankshaft now runs by calling CreateGraph on the HGraphBuilder, then
calling Optimize and Codegen on the HGraph.

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/10700115

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12064 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
sanjoy@chromium.org 2012-07-12 15:10:34 +00:00
parent 1132b27e25
commit c1ee1b457f
11 changed files with 124 additions and 95 deletions

View File

@ -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<LChunk*>(chunk)),
masm_(assembler),
info_(info),
current_block_(-1),

View File

@ -308,11 +308,19 @@ static bool MakeCrankshaftCode(CompilationInfo* info) {
}
if (graph != NULL) {
Handle<Code> optimized_code = graph->Compile();
if (!optimized_code.is_null()) {
info->SetCode(optimized_code);
FinishOptimization(info->closure(), start);
return true;
SmartArrayPointer<char> 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<Code> optimized_code = chunk->Codegen();
if (!optimized_code.is_null()) {
info->SetCode(optimized_code);
FinishOptimization(info->closure(), start);
return true;
}
}
}
}

View File

@ -703,47 +703,6 @@ HGraph::HGraph(CompilationInfo* info)
}
Handle<Code> HGraph::Compile() {
int values = GetMaximumValueID();
if (values > LUnallocated::kMaxVirtualRegisters) {
if (FLAG_trace_bailout) {
PrintF("Not enough virtual registers for (values).\n");
}
return Handle<Code>::null();
}
LAllocator allocator(values, this);
LChunkBuilder builder(info(), this, &allocator);
LChunk* chunk = builder.Build();
if (chunk == NULL) return Handle<Code>::null();
if (!allocator.Allocate(chunk)) {
if (FLAG_trace_bailout) {
PrintF("Not enough virtual registers (regalloc).\n");
}
return Handle<Code>::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> code =
CodeGenerator::MakeCodeEpilogue(&assembler, flags, info());
generator.FinishCode(code);
CodeGenerator::PrintCode(code, info());
return code;
}
return Handle<Code>::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<char>* bailout_reason) {
*bailout_reason = SmartArrayPointer<char>();
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<char>(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<char>(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<HPhi*>* phis = graph()->osr_loop_entry()->phis();
if (has_osr_loop_entry()) {
const ZoneList<HPhi*>* 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;
}

View File

@ -281,8 +281,6 @@ class HGraph: public ZoneObject {
void CollectPhis();
Handle<Code> Compile();
void set_undefined_constant(HConstant* constant) {
undefined_constant_.set(constant);
}
@ -313,6 +311,8 @@ class HGraph: public ZoneObject {
return NULL;
}
bool Optimize(SmartArrayPointer<char>* bailout_reason);
#ifdef DEBUG
void Verify(bool do_full_verify) const;
#endif

View File

@ -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<LChunk*>(chunk)),
masm_(assembler),
info_(info),
current_block_(-1),

View File

@ -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<LChunk*>(chunk);
MeetRegisterConstraints();
if (!AllocationOk()) return false;
ResolvePhis();

View File

@ -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<LiveRange*>* live_ranges() const { return &live_ranges_; }
const Vector<LiveRange*>* fixed_live_ranges() const {

View File

@ -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<Code> 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> code =
CodeGenerator::MakeCodeEpilogue(&assembler, flags, info());
generator.FinishCode(code);
CodeGenerator::PrintCode(code, info());
return code;
}
return Handle<Code>::null();
}
} } // namespace v8::internal

View File

@ -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<Code> 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:

View File

@ -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<LChunk*>(chunk)),
masm_(assembler),
info_(info),
current_block_(-1),

View File

@ -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<LChunk*>(chunk)),
masm_(assembler),
info_(info),
current_block_(-1),