| /* |
| * 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); |
| } |
| } |