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; }
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; }
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; }
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; }
/** * @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); }
/** * 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); } }
/** * Returns the loop stride. * * @return The stride/step */ public Expression getStep() { return m_exprStep.clone(); }
/** * Returns the end index of the loop. * * @return The end index */ public Expression getEnd() { return m_exprEnd.clone(); }
/** * Returns the start index of the loop. * * @return The start index */ public Expression getStart() { return m_exprStart.clone(); }
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"); } } } } }
/** 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; }