blob: 17ec67e0bbe889474f3f8ab6fd2667fc9cf5d72e [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.dev.jjs.impl.gflow.constants;
import com.google.gwt.dev.jjs.ast.JBooleanLiteral;
import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JLocal;
import com.google.gwt.dev.jjs.ast.JNullLiteral;
import com.google.gwt.dev.jjs.ast.JParameter;
import com.google.gwt.dev.jjs.ast.JValueLiteral;
import com.google.gwt.dev.jjs.ast.JVariable;
import com.google.gwt.dev.jjs.impl.gflow.AssumptionMap;
import com.google.gwt.dev.jjs.impl.gflow.AssumptionUtil;
import com.google.gwt.dev.jjs.impl.gflow.FlowFunction;
import com.google.gwt.dev.jjs.impl.gflow.cfg.Cfg;
import com.google.gwt.dev.jjs.impl.gflow.cfg.CfgConditionalNode;
import com.google.gwt.dev.jjs.impl.gflow.cfg.CfgEdge;
import com.google.gwt.dev.jjs.impl.gflow.cfg.CfgNode;
import com.google.gwt.dev.jjs.impl.gflow.cfg.CfgReadWriteNode;
import com.google.gwt.dev.jjs.impl.gflow.cfg.CfgVisitor;
import com.google.gwt.dev.jjs.impl.gflow.cfg.CfgWriteNode;
import com.google.gwt.dev.jjs.impl.gflow.constants.ConstantsAssumption.Updater;
import com.google.gwt.dev.util.Preconditions;
import java.util.ArrayList;
/**
* Flow function for ConstantsAnalysis.
*/
public class ConstantsFlowFunction implements
FlowFunction<CfgNode<?>, CfgEdge, Cfg, ConstantsAssumption> {
public void interpret(CfgNode<?> node,
final Cfg graph, AssumptionMap<CfgEdge, ConstantsAssumption> assumptionMap) {
ConstantsAssumption in = AssumptionUtil.join(graph.getInEdges(node), assumptionMap);
final int outSize = graph.getOutEdges(node).size();
final ArrayList<ConstantsAssumption> result =
new ArrayList<ConstantsAssumption>(outSize);
final Updater assumption = new Updater(in);
node.accept(new CfgVisitor() {
@Override
public void visitConditionalNode(CfgConditionalNode<?> x) {
JExpression condition = x.getCondition();
Updater thenAssumptions = assumption.copy();
Updater elseAssumptions = assumption.copy();
Preconditions.checkNotNull(condition, "Null condition in %s", x);
AssumptionDeducer.deduceAssumption(condition, JBooleanLiteral.TRUE,
thenAssumptions);
AssumptionDeducer.deduceAssumption(condition, JBooleanLiteral.FALSE,
elseAssumptions);
for (CfgEdge e : graph.getOutEdges(x)) {
if (CfgConditionalNode.THEN.equals(e.getRole())) {
result.add(thenAssumptions.unwrap());
} else if (CfgConditionalNode.ELSE.equals(e.getRole())) {
result.add(elseAssumptions.unwrap());
} else {
result.add(assumption.unwrap());
}
}
}
@Override
public void visitNode(CfgNode<?> node) {
// We can't deduce any assumptions from the node. Just copy incoming
// assumptions further.
for (int i = 0; i < graph.getOutEdges(node).size(); ++i) {
result.add(assumption.unwrap());
}
}
@Override
public void visitReadWriteNode(CfgReadWriteNode node) {
processWrite(assumption, node.getTargetVariable(), node.getValue());
super.visitReadWriteNode(node);
}
@Override
public void visitWriteNode(CfgWriteNode node) {
processWrite(assumption, node.getTargetVariable(), node.getValue());
super.visitWriteNode(node);
}
private void processWrite(final Updater assumption,
JVariable var, JExpression expression) {
if (var == null) {
return;
}
if (var instanceof JParameter || var instanceof JLocal) {
if (expression != null) {
JValueLiteral valueLiteral =
ExpressionEvaluator.evaluate(expression, assumption.unwrap());
if (valueLiteral != null &&
(valueLiteral.getType() == var.getType() ||
valueLiteral instanceof JNullLiteral)) {
assumption.set(var, valueLiteral);
} else {
// Don't bother to try to get conversions right.
assumption.set(var, null);
}
} else {
assumption.set(var, null);
}
}
}
});
AssumptionUtil.setAssumptions(graph.getOutEdges(node), result, assumptionMap);
}
}