Better dynamic constant support in repo mode

A constant defined in a function/method should be treated as
dynamic.
A class constant with a dynamic initializer should evaluate to
the value of its initializer at the time the constant was first
seen; so the optimization should be all or nothing - either
turn the class constant into a scalar, or leave it in its original
form.
Esse commit está contido em:
mwilliams
2013-04-18 16:32:39 -07:00
commit de Sara Golemon
commit fb214b9655
2 arquivos alterados com 37 adições e 1 exclusões
@@ -144,6 +144,19 @@ ExpressionPtr ClassConstantExpression::preOptimize(AnalysisResultConstPtr ar) {
ExpressionPtr value = dynamic_pointer_cast<Expression>(decl);
BlockScope::s_constMutex.unlock();
if (!value->isScalar() &&
(value->is(KindOfClassConstantExpression) ||
value->is(KindOfConstantExpression))) {
std::set<ExpressionPtr> seen;
do {
if (!seen.insert(value).second) return ExpressionPtr();
value = value->preOptimize(ar);
if (!value) return ExpressionPtr();
} while (!value->isScalar() &&
(value->is(KindOfClassConstantExpression) ||
value->is(KindOfConstantExpression)));
}
ExpressionPtr rep = Clone(value, getScope());
bool annotate = Option::FlAnnotate;
Option::FlAnnotate = false; // avoid nested comments on getText
@@ -332,7 +332,8 @@ void SimpleFunctionCall::analyzeProgram(AnalysisResultPtr ar) {
// check for dynamic constant and volatile function/class
if (!m_class && m_className.empty() &&
(m_type == DefinedFunction ||
(m_type == DefineFunction ||
m_type == DefinedFunction ||
m_type == FunctionExistsFunction ||
m_type == FBCallUserFuncSafeFunction ||
m_type == ClassExistsFunction ||
@@ -345,6 +346,28 @@ void SimpleFunctionCall::analyzeProgram(AnalysisResultPtr ar) {
if (name && name->isLiteralString()) {
string symbol = name->getLiteralString();
switch (m_type) {
case DefineFunction: {
ConstantTableConstPtr constants = ar->getConstants();
// system constant
if (constants->isPresent(symbol)) {
break;
}
// user constant
BlockScopeConstPtr block = ar->findConstantDeclarer(symbol);
// not found (i.e., undefined)
if (!block) break;
constants = block->getConstants();
const Symbol *sym = constants->getSymbol(symbol);
always_assert(sym);
if (!sym->isDynamic()) {
if (FunctionScopeRawPtr fsc = getFunctionScope()) {
if (!fsc->inPseudoMain()) {
const_cast<Symbol*>(sym)->setDynamic();
}
}
}
break;
}
case DefinedFunction: {
ConstantTablePtr constants = ar->getConstants();
if (!constants->isPresent(symbol)) {