예제 #1
0
 Expression Identifier() {
   Expression expr;
   Expect(1);
   expr = t.val.equals("%pi") ? new FloatLiteral(Math.PI) : getIdentifier(t.val);
   if (la.kind == 21) {
     Get();
     Expression exprSubscript = Identifier();
     expr = new AccessExpression(expr.clone(), AccessOperator.MEMBER_ACCESS, exprSubscript);
   }
   return expr;
 }
예제 #2
0
 Expression ExponentExpression() {
   Expression expr;
   Expression expr0 = UnaryExpression();
   expr = expr0;
   while (la.kind == 14) {
     Get();
     Expression expr1 = UnarySignExpression();
     expr = ExpressionUtil.createExponentExpression(expr.clone(), expr1, null);
   }
   return expr;
 }
예제 #3
0
 Expression MultiplicativeExpression() {
   Expression expr;
   Expression expr0 = UnarySignExpression();
   expr = expr0;
   while (la.kind == 12 || la.kind == 13) {
     BinaryOperator op = BinaryOperator.MULTIPLY;
     if (la.kind == 12) {
       Get();
     } else {
       Get();
       op = BinaryOperator.DIVIDE;
     }
     m_nFlops++;
     Expression expr1 = UnarySignExpression();
     expr = new BinaryExpression(expr.clone(), op, expr1);
   }
   return expr;
 }
예제 #4
0
 Expression AdditiveExpression() {
   Expression expr;
   Expression expr0 = MultiplicativeExpression();
   expr = expr0;
   while (la.kind == 10 || la.kind == 11) {
     BinaryOperator op = BinaryOperator.ADD;
     if (la.kind == 10) {
       Get();
     } else {
       Get();
       op = BinaryOperator.SUBTRACT;
     }
     m_nFlops++;
     Expression expr1 = MultiplicativeExpression();
     expr = new BinaryExpression(expr.clone(), op, expr1);
   }
   return expr;
 }
예제 #5
0
  /**
   * @param exprStart
   * @param exprEnd
   * @param exprStep
   */
  public void setRange(Expression exprStart, Expression exprEnd, Expression exprStep) {
    m_exprStart = exprStart == null ? new IntegerLiteral(0) : (Expression) exprStart.clone();
    m_exprEnd = exprEnd == null ? new IntegerLiteral(0) : (Expression) exprEnd.clone();
    m_exprStep = exprStep == null ? new IntegerLiteral(1) : (Expression) exprStep.clone();

    m_exprStart.setParent(this);
    m_exprEnd.setParent(this);
    m_exprStep.setParent(this);
  }
예제 #6
0
 /**
  * Performs normalization of the non-identifier arguments. It creates a temporary compound
  * statement filled with the temporary assignments to set of identifiers that takes the original
  * arugments as RHS.
  */
 @SuppressWarnings("unchecked")
 protected void normalizeArguments() {
   if (exception != 0) { // no normalization is possible.
     return;
   }
   temp_assignments = new CompoundStatement();
   norm_arguments = new ArrayList<Expression>(4);
   for (int i = 0; i < arguments.size(); i++) {
     Symbol param = getParameters().get(i);
     Expression arg = Symbolic.simplify(arguments.get(i));
     // Allows normalization of identifers which are global array names.
     if (arg instanceof Identifier) {
       Symbol base = ((Identifier) arg).getSymbol();
       if (SymbolTools.isGlobal(base) && SymbolTools.isArray(base)) {
         arg =
             new UnaryExpression(
                 UnaryOperator.ADDRESS_OF, new ArrayAccess(arg.clone(), new IntegerLiteral(0)));
       }
     }
     Expression new_arg = arg;
     if (!(arg instanceof Literal || arg instanceof Identifier)) {
       arg = normalize(arg, param);
       List type_spec = param.getTypeSpecifiers();
       List array_spec = param.getArraySpecifiers();
       // Assumes there is only one element in array_spec.
       if (!array_spec.isEmpty()) {
         type_spec.add(PointerSpecifier.UNQUALIFIED);
       }
       new_arg = SymbolTools.getTemp(temp_assignments, type_spec, "arg");
       Expression assign =
           new AssignmentExpression(new_arg, AssignmentOperator.NORMAL, arg.clone());
       temp_assignments.addStatement(new ExpressionStatement(assign));
     }
     norm_arguments.add(new_arg);
   }
 }
예제 #7
0
 /**
  * Returns the loop stride.
  *
  * @return The stride/step
  */
 public Expression getStep() {
   return m_exprStep.clone();
 }
예제 #8
0
 /**
  * Returns the end index of the loop.
  *
  * @return The end index
  */
 public Expression getEnd() {
   return m_exprEnd.clone();
 }
예제 #9
0
 /**
  * Returns the start index of the loop.
  *
  * @return The start index
  */
 public Expression getStart() {
   return m_exprStart.clone();
 }
예제 #10
0
  private void buildCDG() {
    if (this.procSet == null) {
      procSet = cfgMap.keySet();
    }
    for (Procedure proc : procSet) {
      System.out.println(
          "Building Control Dependence Graph for Proc: "
              + proc.getSymbolName()
              + ", time: "
              + (new Date()).toString());
      CFGraph cfg = cfgMap.get(proc);
      // reverse the control flow graph
      DFAGraph reversedCFG = SlicingTools.reverseCFGraph(cfg);
      // add additional start node for connecting multiple return node
      // single return node works fine with this.
      DFANode dummyEntryNode = new DFANode();
      List<DFANode> entryList = reversedCFG.getEntryNodes();
      reversedCFG.addNode(dummyEntryNode);
      for (DFANode entry : entryList) {
        dummyEntryNode.addSucc(entry);
        reversedCFG.addEdge(dummyEntryNode, entry);
      }
      //
      ArrayList<DFANode> nodeList = new ArrayList<DFANode>();

      // extract dominator
      BitSet[] dominator = SlicingTools.getDominators(reversedCFG, nodeList);
      int nodeSize = nodeList.size();
      DFANode[] nodeArray = new DFANode[nodeSize];
      nodeList.toArray(nodeArray);
      Set<Integer> entryIdxSet = SlicingTools.getEntryIdxSet(reversedCFG, nodeList);
      List<DFANode> entryNodeList = reversedCFG.getEntryNodes();

      // print dominator
      //            SlicingTools.printDominator(dominator, nodeArray, proc);

      // extract immediate dominator
      BitSet[] immediateDom =
          SlicingTools.getImmediateDominator(dominator, entryIdxSet, entryNodeList, nodeArray);

      // print immediate dominator
      //            SlicingTools.printDominator(immediateDom, nodeArray, proc);

      // build Post Dominance Tree
      if (PrintTools.getVerbosity() > 1)
        System.out.println(
            "############# build Post Dominace Tree (Graph) for "
                + proc.getSymbolName()
                + " ###########");
      DFAGraph postDomTree =
          SlicingTools.buildImmediateDominanceTree(reversedCFG, immediateDom, nodeArray, nodeList);

      // print post dominance tree
      //            SlicingTools.printDominanceTree(postDomTree, proc);

      // extract edges m --> n such that n does not postdominate(dominate in reversed) m
      // CFGEdge's head and tail are on reversed cfg.
      // can get PDTree node by getData("pdtNode")
      Set<CFGEdge> nonPDEdgeSet = extractNonPostdominatingEdges(reversedCFG, postDomTree, proc);

      List<DFANode> pdtNodeList = new ArrayList<DFANode>();
      Iterator<DFANode> pdtIter = postDomTree.iterator();
      int idx = 0;
      while (pdtIter.hasNext()) {
        DFANode node = pdtIter.next();
        pdtNodeList.add(node);
        //            	System.out.println("[" + idx++ + "]" +
        // ((DFANode)((DFANode)node.getData("revNode")).getData("cfgNode")).getData("ir"));
      }
      for (CFGEdge edge : nonPDEdgeSet) {
        // find lowest common ancestor of m and n (result: l)
        DFANode commonAncestor = getLowestCommonAncestor(edge, postDomTree, pdtNodeList);

        // all nodes in N on the path from l to n in the postdominance tree except l
        // are control dependent on m
        Set<DFANode> cdSet = getControlDependentSet(edge, commonAncestor);
        DFANode controllingNode = edge.tail.getData("cfgNode");
        // TODO: handled some corner cases this way but should be fixed later
        // Some wrong controlling nodes are inserted, maybe due to the problem of control flow graph
        if ((controllingNode.getData("ir") instanceof Expression) == false
            && (controllingNode.getData("ir") instanceof SwitchStatement) == false) {
          // filter if a statement is a controlling node (wrong)
          continue;
          // throw new RuntimeException("controllingNode is not expression: " +
          // controllingNode.getData("ir"));
        } else {
          if (controllingNode.getData("ir") instanceof Expression) {
            // filter a stepping expression in the for loop is a controlling node (wrong)
            Expression exp = controllingNode.getData("ir");
            Traversable parent = exp.getParent();
            if (parent instanceof ForLoop) {
              ForLoop fLoop = (ForLoop) parent;
              if (exp.equals(fLoop.getStep())) {
                continue;
              }
            }
          } else if (controllingNode.getData("ir") instanceof SwitchStatement) {

          } else {
            throw new RuntimeException(
                "controllingNode is unexpected type: " + controllingNode.getData("ir"));
          }
        }
        //
        for (DFANode node : cdSet) {
          DFANode revNode = node.getData("revNode");
          if (revNode == null) {
            continue;
          }
          DFANode controlledNode = revNode.getData("cfgNode");
          controlledNode.putData("controlNode", controllingNode);
          if (PrintTools.getVerbosity() > 1)
            System.out.println(
                "[Node]"
                    + controlledNode.getData("ir")
                    + " == control dependent on == [Node]"
                    + controllingNode.getData("ir"));
        }
      }
      // check inter-dependent node
      // remove the controlling node for coming first node toward coming later node
      Iterator<DFANode> cfgIter = cfg.iterator();
      while (cfgIter.hasNext()) {
        DFANode n = cfgIter.next();
        DFANode cdNode = n.getData("controlNode");
        if (cdNode == null) {
          continue;
        }
        DFANode cdCDNode = cdNode.getData("controlNode");
        if (n.equals(cdCDNode)) {
          n.removeData("controlNode");
          //            		throw new RuntimeException("My contol node is dependent on me. my: " + n +
          // ",\n cd: " + cdNode);
        }
      }
      // check a cyclic dependent node and remove it
      cfgIter = cfg.iterator();
      while (cfgIter.hasNext()) {
        DFANode n = cfgIter.next();
        DFANode cdNode = n.getData("controlNode");
        while (cdNode != null) {
          if (cdNode.equals(n)) {
            cdNode.removeData("controlNode");
            break;
            //            			throw new RuntimeException("Cyclic dependency was found!!");
          } else {
            cdNode = cdNode.getData("controlNode");
          }
        }
      }
    }
  }
예제 #11
0
 /** Normalization for points-to analysis. */
 private static Expression normalize(Expression arg, Symbol param) {
   Expression ret = arg.clone(); // default behavior.
   // Converts array accesses to address-of expressions.
   if (ret instanceof ArrayAccess) {
     ArrayAccess array = (ArrayAccess) ret;
     // Normalize the array name.
     Expression name = normalize(array.getArrayName(), null);
     Symbol base = SymbolTools.getSymbolOf(name);
     if (base != null && param != null && SymbolTools.isPointerParameter(param)) {
       // case 1: the base symbol has an array specifier.
       // --> - keeps the array indices while adding trailing [0].
       //     - converts to address-of expression.
       //     - adds dereference operator if base is a formal parameter
       if (SymbolTools.isArray(base)) {
         // Adds a trailing subscript "[0]" intentionally.
         array.addIndex(new IntegerLiteral(0));
         ret = new UnaryExpression(UnaryOperator.ADDRESS_OF, ret);
         // Formal parameter is normalized: a[10] to (*a)[10].
         // This conversion is used only internally (not legal in C).
         if (SymbolTools.isPointerParameter(base)) {
           array
               .getArrayName()
               .swapWith(new UnaryExpression(UnaryOperator.DEREFERENCE, name.clone()));
         }
         // case 2: the base symbol does not have an array specifier.
         // --> just take the base object while converting a subscript
         // to a dereference.
       } else {
         ret = name;
         for (int i = 0; i < array.getNumIndices(); i++) {
           ret = new UnaryExpression(UnaryOperator.DEREFERENCE, ret.clone());
         }
       }
     } else { // just normalizes the array name.
       array.getArrayName().swapWith(name);
     }
     // Removes pointer access and adds trailing dummy index for pointer
     // type.
   } else if (ret instanceof AccessExpression) {
     AccessExpression access = (AccessExpression) ret;
     // POINTER_ACCESS to MEMBER_ACCESS
     if (access.getOperator() == AccessOperator.POINTER_ACCESS) {
       // Normalize the LHS.
       Expression lhs = normalize(access.getLHS(), null);
       ret =
           new AccessExpression(
               new UnaryExpression(UnaryOperator.DEREFERENCE, lhs.clone()),
               AccessOperator.MEMBER_ACCESS,
               access.getRHS().clone());
     }
     // Pointer type to address-of expression.
     if (param != null && SymbolTools.isPointerParameter(param)) {
       ret =
           new UnaryExpression(
               UnaryOperator.ADDRESS_OF, new ArrayAccess(ret.clone(), new IntegerLiteral(0)));
     }
     // Just normalize the expression child.
   } else if (ret instanceof UnaryExpression) {
     UnaryExpression ue = (UnaryExpression) ret;
     ue.setExpression(normalize(ue.getExpression(), null));
     // Tries to convert simple pointer arithmetic to array access.
   } else if (ret instanceof BinaryExpression) {
     BinaryExpression be = (BinaryExpression) ret;
     Expression lhs = normalize(be.getLHS(), null);
     Expression rhs = normalize(be.getRHS(), null);
     if (param != null
         && SymbolTools.isPointerParameter(param)
         && be.getOperator() == BinaryOperator.ADD) {
       if (isPointerArithmeticOperand(lhs, rhs)) {
         ret =
             new UnaryExpression(
                 UnaryOperator.ADDRESS_OF, new ArrayAccess(rhs.clone(), lhs.clone()));
       } else if (isPointerArithmeticOperand(rhs, lhs)) {
         ret =
             new UnaryExpression(
                 UnaryOperator.ADDRESS_OF, new ArrayAccess(lhs.clone(), rhs.clone()));
       }
     } else {
       ret = new BinaryExpression(lhs.clone(), be.getOperator(), rhs.clone());
     }
     // Type cast is discarded.
   } else if (ret instanceof Typecast) {
     ret = (Expression) ret.getChildren().get(0);
   }
   return ret;
 }