Commit 98786ae0 authored by bmeurer@chromium.org's avatar bmeurer@chromium.org

Refactor Hydrogen GVN into an HPhase and use the phase zone.

The HGlobalValueNumberer class is renamed to HGlobalValueNumberingPhase,
following the naming scheme suggested by danno@chromium.org in
https://codereview.chromium.org/17458002

The GVN phase now uses the phase zone for all its allocations.

Depends upon https://codereview.chromium.org/18022002

R=danno@chromium.org
BUG=

Review URL: https://codereview.chromium.org/17657004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15353 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 073b1d1d
......@@ -626,7 +626,8 @@ class CompilationPhase BASE_EMBEDDED {
bool ShouldProduceTraceOutput() const;
const char* name() const { return name_; }
Isolate* isolate() const { return info_->isolate(); }
CompilationInfo* info() const { return info_; }
Isolate* isolate() const { return info()->isolate(); }
Zone* zone() { return &zone_; }
private:
......
......@@ -361,42 +361,39 @@ void HSideEffectMap::Store(GVNFlagSet flags, HInstruction* instr) {
}
HGlobalValueNumberer::HGlobalValueNumberer(HGraph* graph, CompilationInfo* info)
: graph_(graph),
info_(info),
HGlobalValueNumberingPhase::HGlobalValueNumberingPhase(HGraph* graph)
: HPhase("H_Global value numbering", graph),
removed_side_effects_(false),
zone_(graph->isolate()),
block_side_effects_(graph->blocks()->length(), zone()),
loop_side_effects_(graph->blocks()->length(), zone()),
visited_on_paths_(zone(), graph->blocks()->length()) {
ASSERT(!AllowHandleAllocation::IsAllowed());
block_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length(),
block_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(),
zone());
loop_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length(),
loop_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(),
zone());
}
bool HGlobalValueNumberer::Analyze() {
void HGlobalValueNumberingPhase::Analyze() {
removed_side_effects_ = false;
ComputeBlockSideEffects();
if (FLAG_loop_invariant_code_motion) {
LoopInvariantCodeMotion();
}
AnalyzeGraph();
return removed_side_effects_;
}
void HGlobalValueNumberer::ComputeBlockSideEffects() {
void HGlobalValueNumberingPhase::ComputeBlockSideEffects() {
// The Analyze phase of GVN can be called multiple times. Clear loop side
// effects before computing them to erase the contents from previous Analyze
// passes.
for (int i = 0; i < loop_side_effects_.length(); ++i) {
loop_side_effects_[i].RemoveAll();
}
for (int i = graph_->blocks()->length() - 1; i >= 0; --i) {
for (int i = graph()->blocks()->length() - 1; i >= 0; --i) {
// Compute side effects for the block.
HBasicBlock* block = graph_->blocks()->at(i);
HBasicBlock* block = graph()->blocks()->at(i);
HInstruction* instr = block->first();
int id = block->block_id();
GVNFlagSet side_effects;
......@@ -513,11 +510,11 @@ GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
}
void HGlobalValueNumberer::LoopInvariantCodeMotion() {
void HGlobalValueNumberingPhase::LoopInvariantCodeMotion() {
TRACE_GVN_1("Using optimistic loop invariant code motion: %s\n",
graph_->use_optimistic_licm() ? "yes" : "no");
for (int i = graph_->blocks()->length() - 1; i >= 0; --i) {
HBasicBlock* block = graph_->blocks()->at(i);
graph()->use_optimistic_licm() ? "yes" : "no");
for (int i = graph()->blocks()->length() - 1; i >= 0; --i) {
HBasicBlock* block = graph()->blocks()->at(i);
if (block->IsLoopHeader()) {
GVNFlagSet side_effects = loop_side_effects_[block->block_id()];
TRACE_GVN_2("Try loop invariant motion for block B%d %s\n",
......@@ -528,7 +525,7 @@ void HGlobalValueNumberer::LoopInvariantCodeMotion() {
GVNFlagSet accumulated_first_time_changes;
HBasicBlock* last = block->loop_information()->GetLastBackEdge();
for (int j = block->block_id(); j <= last->block_id(); ++j) {
ProcessLoopBlock(graph_->blocks()->at(j), block, side_effects,
ProcessLoopBlock(graph()->blocks()->at(j), block, side_effects,
&accumulated_first_time_depends,
&accumulated_first_time_changes);
}
......@@ -537,7 +534,7 @@ void HGlobalValueNumberer::LoopInvariantCodeMotion() {
}
void HGlobalValueNumberer::ProcessLoopBlock(
void HGlobalValueNumberingPhase::ProcessLoopBlock(
HBasicBlock* block,
HBasicBlock* loop_header,
GVNFlagSet loop_kills,
......@@ -602,20 +599,21 @@ void HGlobalValueNumberer::ProcessLoopBlock(
}
bool HGlobalValueNumberer::AllowCodeMotion() {
bool HGlobalValueNumberingPhase::AllowCodeMotion() {
return info()->IsStub() || info()->opt_count() + 1 < FLAG_max_opt_count;
}
bool HGlobalValueNumberer::ShouldMove(HInstruction* instr,
HBasicBlock* loop_header) {
bool HGlobalValueNumberingPhase::ShouldMove(HInstruction* instr,
HBasicBlock* loop_header) {
// If we've disabled code motion or we're in a block that unconditionally
// deoptimizes, don't move any instructions.
return AllowCodeMotion() && !instr->block()->IsDeoptimizing();
}
GVNFlagSet HGlobalValueNumberer::CollectSideEffectsOnPathsToDominatedBlock(
GVNFlagSet
HGlobalValueNumberingPhase::CollectSideEffectsOnPathsToDominatedBlock(
HBasicBlock* dominator, HBasicBlock* dominated) {
GVNFlagSet side_effects;
for (int i = 0; i < dominated->predecessors()->length(); ++i) {
......@@ -755,8 +753,8 @@ class GvnBasicBlockState: public ZoneObject {
// into a loop to avoid stack overflows.
// The logical "stack frames" of the recursion are kept in a list of
// GvnBasicBlockState instances.
void HGlobalValueNumberer::AnalyzeGraph() {
HBasicBlock* entry_block = graph_->entry_block();
void HGlobalValueNumberingPhase::AnalyzeGraph() {
HBasicBlock* entry_block = graph()->entry_block();
HValueMap* entry_map = new(zone()) HValueMap(zone());
GvnBasicBlockState* current =
GvnBasicBlockState::CreateEntry(zone(), entry_block, entry_map);
......
......@@ -76,14 +76,24 @@ class SparseSet {
};
class HGlobalValueNumberer BASE_EMBEDDED {
// Perform common subexpression elimination and loop-invariant code motion.
class HGlobalValueNumberingPhase : public HPhase {
public:
HGlobalValueNumberer(HGraph* graph, CompilationInfo* info);
// Returns true if values with side effects are removed.
bool Analyze();
explicit HGlobalValueNumberingPhase(HGraph* graph);
void Run() {
Analyze();
// Trigger a second analysis pass to further eliminate duplicate values
// that could only be discovered by removing side-effect-generating
// instructions during the first pass.
if (FLAG_smi_only_arrays && removed_side_effects_) {
Analyze();
ASSERT(!removed_side_effects_);
}
}
private:
void Analyze();
GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock(
HBasicBlock* dominator,
HBasicBlock* dominated);
......@@ -98,16 +108,8 @@ class HGlobalValueNumberer BASE_EMBEDDED {
bool AllowCodeMotion();
bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header);
HGraph* graph() { return graph_; }
CompilationInfo* info() { return info_; }
Zone* zone() { return &zone_; }
HGraph* graph_;
CompilationInfo* info_;
bool removed_side_effects_;
Zone zone_;
// A map of block IDs to their side effects.
ZoneList<GVNFlagSet> block_side_effects_;
......@@ -117,6 +119,8 @@ class HGlobalValueNumberer BASE_EMBEDDED {
// Used when collecting side effects on paths from dominator to
// dominated.
SparseSet visited_on_paths_;
DISALLOW_COPY_AND_ASSIGN(HGlobalValueNumberingPhase);
};
......
......@@ -3946,21 +3946,6 @@ bool HOptimizedGraphBuilder::BuildGraph() {
}
// Perform common subexpression elimination and loop-invariant code motion.
void HGraph::GlobalValueNumbering() {
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
// during the first pass.
if (FLAG_smi_only_arrays && removed_side_effects) {
removed_side_effects = gvn.Analyze();
ASSERT(!removed_side_effects);
}
}
bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
*bailout_reason = SmartArrayPointer<char>();
OrderBlocks();
......@@ -4029,7 +4014,10 @@ bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
if (FLAG_use_canonicalizing) Canonicalize();
if (FLAG_use_gvn) GlobalValueNumbering();
if (FLAG_use_gvn) {
HGlobalValueNumberingPhase phase(this);
phase.Run();
}
if (FLAG_use_range) {
HRangeAnalysis rangeAnalysis(this);
......
......@@ -284,7 +284,6 @@ class HGraph: public ZoneObject {
void MarkDeoptimizeOnUndefined();
void ComputeMinusZeroChecks();
void ComputeSafeUint32Operations();
void GlobalValueNumbering();
bool ProcessArgumentsObject();
void EliminateRedundantPhis();
void Canonicalize();
......@@ -1962,6 +1961,9 @@ class HPhase : public CompilationPhase {
graph_(graph) { }
~HPhase();
protected:
HGraph* graph() const { return graph_; }
private:
HGraph* graph_;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment