From 8fa1c51ee8dd13d05bb20c1574d773423ab86ef5 Mon Sep 17 00:00:00 2001 From: jan Date: Fri, 22 Mar 2013 01:18:52 -0700 Subject: [PATCH] Fix ref generator parameters Alias manager does not know whether generator parameters are passed by reference. This didn't matter, because every generator had at least one function call (hphp_continuation_done()) that pretty much disabled unused variable elimination. This diff fixes that, lets us get rid of artificial function calls in generators and will allow later improvements in alias manager. --- hphp/compiler/analysis/symbol_table.h | 3 +++ hphp/compiler/analysis/variable_table.cpp | 4 ++++ hphp/compiler/statement/method_statement.cpp | 8 ++++++++ 3 files changed, 15 insertions(+) diff --git a/hphp/compiler/analysis/symbol_table.h b/hphp/compiler/analysis/symbol_table.h index d8b1b3d88..513549c3f 100644 --- a/hphp/compiler/analysis/symbol_table.h +++ b/hphp/compiler/analysis/symbol_table.h @@ -116,6 +116,7 @@ public: bool isReferenced() const { return !m_flags.m_notReferenced; } bool isHidden() const { return m_flags.m_hidden; } bool isGeneratorParameter() const { return m_flags.m_generatorParameter; } + bool isRefGeneratorParameter() const { return m_flags.m_refGeneratorParameter; } bool isClosureVar() const { return m_flags.m_closureVar; } bool isRefClosureVar() const { return m_flags.m_refClosureVar; } bool isPassClosureVar() const { return m_flags.m_passClosureVar; } @@ -142,6 +143,7 @@ public: void setReferenced() { m_flags.m_notReferenced = false; } void setHidden() { m_flags.m_hidden = true; } void setGeneratorParameter() { m_flags.m_generatorParameter = true; } + void setRefGeneratorParameter() { m_flags.m_refGeneratorParameter = true; } void setClosureVar() { m_flags.m_closureVar = true; } void setRefClosureVar() { m_flags.m_refClosureVar = true; } void setPassClosureVar() { m_flags.m_passClosureVar = true; } @@ -222,6 +224,7 @@ private: unsigned m_notReferenced : 1; unsigned m_hidden : 1; unsigned m_generatorParameter : 1; + unsigned m_refGeneratorParameter : 1; unsigned m_closureVar : 1; unsigned m_refClosureVar : 1; unsigned m_passClosureVar : 1; diff --git a/hphp/compiler/analysis/variable_table.cpp b/hphp/compiler/analysis/variable_table.cpp index a6116c4aa..fc9df2aa2 100644 --- a/hphp/compiler/analysis/variable_table.cpp +++ b/hphp/compiler/analysis/variable_table.cpp @@ -567,6 +567,10 @@ void VariableTable::clearUsed() { } else { sym.second.setReferenced(); } + + if (sym.second.isRefGeneratorParameter()) { + sym.second.setReferenced(); + } } } diff --git a/hphp/compiler/statement/method_statement.cpp b/hphp/compiler/statement/method_statement.cpp index 28ed30f49..dd810cb86 100644 --- a/hphp/compiler/statement/method_statement.cpp +++ b/hphp/compiler/statement/method_statement.cpp @@ -390,6 +390,10 @@ void MethodStatement::analyzeProgram(AnalysisResultPtr ar) { Symbol *gp = variables->addDeclaredSymbol( param->getName(), ConstructPtr()); gp->setGeneratorParameter(); + if (param->isRef()) { + gp->setRefGeneratorParameter(); + gp->setReferenced(); + } } } @@ -400,6 +404,10 @@ void MethodStatement::analyzeProgram(AnalysisResultPtr ar) { Symbol *gp = variables->addDeclaredSymbol( param->getName(), ConstructPtr()); gp->setGeneratorParameter(); + if (param->isRef()) { + gp->setRefGeneratorParameter(); + gp->setReferenced(); + } } } }