Package com.dragome.compiler.parser

Source Code of com.dragome.compiler.parser.Optimizer

package com.dragome.compiler.parser;

import java.util.Iterator;
import java.util.List;

import org.apache.bcel.generic.Type;

import com.dragome.compiler.ast.ASTNode;
import com.dragome.compiler.ast.Assignable;
import com.dragome.compiler.ast.Assignment;
import com.dragome.compiler.ast.Block;
import com.dragome.compiler.ast.Expression;
import com.dragome.compiler.ast.FieldAccess;
import com.dragome.compiler.ast.InfixExpression;
import com.dragome.compiler.ast.MethodDeclaration;
import com.dragome.compiler.ast.NumberLiteral;
import com.dragome.compiler.ast.PStarExpression;
import com.dragome.compiler.ast.PostfixExpression;
import com.dragome.compiler.ast.PrefixExpression;
import com.dragome.compiler.ast.VariableBinding;
import com.dragome.compiler.ast.VariableDeclaration;

public class Optimizer
{

  private MethodDeclaration methodDecl;

  private List tempDecls;

  public Optimizer(MethodDeclaration theMethodDecl, List theTempDecls)
  {
    methodDecl= theMethodDecl;
    tempDecls= theTempDecls;
  }

  public static Expression negate(Expression expr)
  {
    PrefixExpression pe= new PrefixExpression();
    pe.setOperator(PrefixExpression.NOT);
    pe.setOperand(expr);
    return pe;
  }

  public static Expression simplifyBooleanExpression(Expression expr, boolean negate)
  {
    if (expr instanceof PrefixExpression)
    {
      PrefixExpression pe= (PrefixExpression) expr;
      if (pe.getOperator() != PrefixExpression.NOT)
        return expr;
      return simplifyBooleanExpression((Expression) pe.getOperand(), !negate);
    }

    if (expr instanceof InfixExpression && expr.getTypeBinding() == Type.BOOLEAN)
    {
      InfixExpression in= (InfixExpression) expr;
      InfixExpression.Operator op= in.getOperator();
      if (negate)
      {
        op= op.getComplement();
        if (op != InfixExpression.Operator.CONDITIONAL_AND && op != InfixExpression.Operator.CONDITIONAL_OR)
          negate= false;
      }
      InfixExpression out= new InfixExpression(op);
      out.widen(in);
      out.setOperands(simplifyBooleanExpression(in.getLeftOperand(), negate), simplifyBooleanExpression(in.getRightOperand(), negate));
      return out;
    }

    if (negate)
    {
      PrefixExpression pe= new PrefixExpression();
      pe.setOperator(PrefixExpression.NOT);
      pe.setOperand(expr);
      return pe;
    }

    return expr;
  }

  private boolean representSameAssignables(Assignable a, Assignable b)
  {
    if (!(a instanceof FieldAccess && b instanceof FieldAccess))
      return false;
    FieldAccess faa= (FieldAccess) a;
    FieldAccess fab= (FieldAccess) b;
    if (!faa.getName().equals(fab.getName()))
      return false;
    if (faa.getExpression() instanceof VariableBinding && fab.getExpression() instanceof VariableBinding)
    {
      VariableBinding vba= (VariableBinding) faa.getExpression();
      VariableBinding vbb= (VariableBinding) fab.getExpression();
      return vba.getVariableDeclaration() == vbb.getVariableDeclaration();
    }
    return false;
  }

  private VariableBinding fetchVariableBinding(Expression expr, VariableDeclaration decl)
  {
    ASTNode child= expr.getFirstChild();
    while (child != null)
    {
      if (child instanceof VariableBinding && ((VariableBinding) child).getVariableDeclaration() == decl)
        return (VariableBinding) child;
      VariableBinding vb= fetchVariableBinding((Expression) child, decl);
      if (vb != null)
        return vb;
      child= child.getNextSibling();
    }
    return null;
  }

  private PStarExpression.Operator getOp(InfixExpression expr)
  {
    NumberLiteral nl;
    if (expr.getRightOperand() instanceof NumberLiteral)
    {
      nl= (NumberLiteral) expr.getRightOperand();
    }
    else
      return null;

    PStarExpression.Operator op;
    if (expr.getOperator() == InfixExpression.Operator.PLUS)
    {
      op= PStarExpression.INCREMENT;
    }
    else if (expr.getOperator() == InfixExpression.Operator.MINUS)
    {
      op= PStarExpression.DECREMENT;
    }
    else
    {
      return null;
    }

    if (NumberLiteral.isOne(nl))
    {

    }
    else if (NumberLiteral.isMinusOne(nl))
    {
      op= op.complement();
    }
    else
    {
      return null;
    }
    return op;
  }

  private boolean reduceXCrement(VariableDeclaration decl)
  {
    Assignment a1= null;
    Assignment a2= null;
    VariableBinding vb1= null;
    VariableBinding vb2= null;

    Assignable fa1= null;
    Assignable fa2= null;

    InfixExpression sum= null;

    Iterator iter= decl.vbs.iterator();

    while (iter.hasNext())
    {
      VariableBinding vb= (VariableBinding) iter.next();

      if (vb.getParentNode() instanceof Assignment)
      {
        Assignment a= (Assignment) vb.getParentNode();
        if (a.getLeftHandSide() == vb && a.getRightHandSide() instanceof Assignable)
        {
          vb1= vb;
          a1= a;
          fa1= (Assignable) a.getRightHandSide();
          continue;
        }
      }

      if (vb.getParentNode() instanceof InfixExpression)
      {
        InfixExpression infix= (InfixExpression) vb.getParentNode();
        if (infix.getParentNode() instanceof Assignment)
        {
          Assignment a= (Assignment) infix.getParentNode();
          if (a.getLeftHandSide() instanceof Assignable)
          {
            vb2= vb;
            fa2= (Assignable) a.getLeftHandSide();
            a2= a;
            sum= infix;
            continue;
          }
        }
      }
    }

    if (a1 == null || a2 == null)
      return false;
    if (!fa1.isSame(fa2))
      return false;

    PStarExpression.Operator operator= getOp(sum);
    if (operator == null)
      return false;

    PStarExpression p= new PostfixExpression();
    p.setOperand((Expression) fa1);
    p.setOperator(operator);

    decl.vbs.remove(vb1);
    decl.vbs.remove(vb2);
    VariableBinding vb= decl.vbs.get(0);
    vb.getParentBlock().replaceChild(p, vb);

    Block b= a1.getParentBlock();
    b.removeChild(a1);
    b.removeChild(a2);
    return true;
  }

  private boolean reduceYCrement(VariableDeclaration decl)
  {
    Assignment a1= null;
    Assignment a2= null;
    VariableBinding vb1= null;
    VariableBinding vb2= null;

    Assignable fa1= null;
    Assignable fa2= null;

    InfixExpression infixExpr= null;

    Iterator iter= decl.vbs.iterator();

    while (iter.hasNext())
    {
      VariableBinding vb= (VariableBinding) iter.next();

      if (!(vb.getParentNode() instanceof Assignment))
        continue;

      Assignment a= (Assignment) vb.getParentNode();
      if (a.getRightHandSide() == vb && a.getLeftHandSide() instanceof Assignable)
      {
        vb2= vb;
        a2= a;
        fa2= (Assignable) a.getLeftHandSide();
        continue;
      }

      if (a.getLeftHandSide() == vb && a.getRightHandSide() instanceof InfixExpression)
      {
        InfixExpression infix= (InfixExpression) a.getRightHandSide();
        if (!(infix.getLeftOperand() instanceof Assignable))
          continue;
        vb1= vb;
        a1= a;
        fa1= (Assignable) infix.getLeftOperand();
        infixExpr= infix;
        continue;
      }
    }

    if (a1 == null || a2 == null)
      return false;
    if (!fa1.isSame(fa2))
      return false;

    decl.vbs.remove(vb1);
    decl.vbs.remove(vb2);
    VariableBinding vb= decl.vbs.get(0);
    Expression replacement= null;

    PStarExpression.Operator operator= getOp(infixExpr);
    if (operator != null)
    {
      PrefixExpression p= new PrefixExpression();
      p.setOperand((Expression) fa1);
      p.setOperator(operator);
      replacement= p;
    }
    else
    {
      InfixExpression.Operator op= infixExpr.getOperator();
      Assignment.Operator opp= Assignment.Operator.lookup(op.toString() + '=');
      Assignment a= new Assignment(opp);
      a.setLeftHandSide((Expression) fa2);
      a.setRightHandSide(infixExpr.getRightOperand());
      replacement= a;
    }

    vb.getParentBlock().replaceChild(replacement, vb);

    Block b= a1.getParentBlock();
    b.removeChild(a1);
    b.removeChild(a2);
    return true;
  }

  public void optimize()
  {
    if (false)
      return;

    Iterator iter= tempDecls.iterator();
    while (iter.hasNext())
    {
      VariableDeclaration decl= (VariableDeclaration) iter.next();
      int count= decl.vbs.size();
      if (count == 3)
      {
        if (reduceXCrement(decl))
        {
          iter.remove();
          methodDecl.removeLocalVariable(decl.getName());
        }
        else if (reduceYCrement(decl))
        {
          iter.remove();
          methodDecl.removeLocalVariable(decl.getName());
        }
      }
    }
  }

}
TOP

Related Classes of com.dragome.compiler.parser.Optimizer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.