| /********************************************************************** |
| * Copyright (c) 2007 IBM Corporation. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.ptp.pldt.mpi.analysis.analysis; |
| |
| import java.util.ArrayList; |
| import java.util.Enumeration; |
| import java.util.Hashtable; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Stack; |
| |
| import org.eclipse.cdt.core.dom.ast.ASTVisitor; |
| import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTBreakStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTCaseStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTCastExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTContinueStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTDeclaration; |
| import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTDeclarator; |
| import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTDoStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTExpressionList; |
| import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTFieldReference; |
| import org.eclipse.cdt.core.dom.ast.IASTForStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; |
| import org.eclipse.cdt.core.dom.ast.IASTGotoStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTIdExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTIfStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTInitializer; |
| import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTInitializerList; |
| import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTNode; |
| import org.eclipse.cdt.core.dom.ast.IASTNullStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTProblemStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTReturnStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; |
| import org.eclipse.cdt.core.dom.ast.IASTStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement; |
| import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTWhileStatement; |
| import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression; |
| import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement; |
| import org.eclipse.ptp.pldt.mpi.analysis.analysis.BarrierExpression.BarrierExpressionOP; |
| import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.ICallGraph; |
| import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.ICallGraphNode; |
| |
| public class MPIBarrierExprModified extends ASTVisitor { |
| protected BarrierTable bTable_; |
| protected ICallGraph cg_; |
| /** One stack for each communicator */ |
| protected Hashtable<String, Stack<BarrierExpression>> stacks_; |
| private static final boolean traceOn = false; |
| |
| protected MPICallGraphNode currentNode_; |
| |
| /** |
| * switch statement may be nested |
| */ |
| protected int depth = 0; |
| |
| /** |
| * This field is used to recognize the associated case body. The idea is |
| * the case body should have the same parent with the "case" statement. |
| * One element in this stack is shared by all cases (and default) in one |
| * switch statement. This is possible because of the tree structure. |
| */ |
| protected Stack<IASTNode> caseParent = null; |
| |
| /** |
| * This field is used to record whether the current case has "break" |
| * statement. Same as above, one element is shared by all cases and default |
| * in a switch statement. |
| */ |
| protected Stack<Boolean> withBreak = null; |
| |
| //@formatter:off |
| /** |
| * Each bucket in this hashtable is a List, hashed by communicator. |
| * The List records the current barrier |
| * expression for each case statement in the current (nested)switch statement. |
| * So: Hashtable(for each communicator) --> |
| * Stack(for each nested switch statement) --> |
| * ArrayList(for each case body) --> |
| * Tuple(caseStatement, CaseBarrierExpr) |
| */ |
| //@formatter:on |
| protected Hashtable<String, Stack<List>> caseBE = null; |
| |
| public MPIBarrierExprModified(BarrierTable btable, ICallGraph cg) { |
| bTable_ = btable; |
| cg_ = cg; |
| } |
| |
| private void init() { |
| stacks_ = new Hashtable<String, Stack<BarrierExpression>>(); |
| for (Enumeration<String> e = bTable_.getTable().keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| stacks_.put(comm, new Stack<BarrierExpression>()); |
| } |
| |
| depth = 0; |
| caseParent = new Stack<IASTNode>(); |
| withBreak = new Stack<Boolean>(); |
| caseBE = new Hashtable<String, Stack<List>>(); |
| for (Enumeration<String> e = bTable_.getTable().keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| caseBE.put(comm, new Stack<List>()); |
| } |
| } |
| |
| public void run() { |
| if (bTable_.isEmpty()) |
| return; |
| this.shouldVisitExpressions = true; |
| this.shouldVisitStatements = true; |
| this.shouldVisitDeclarations = true; |
| for (ICallGraphNode n = cg_.botEntry(); n != null; n = n.botNext()) { |
| currentNode_ = (MPICallGraphNode) n; |
| if (!currentNode_.marked) |
| continue; |
| if (!currentNode_.barrierRelated()) |
| continue; |
| // System.out.println("Barrier related function " + currentNode_.getFuncName()); |
| init(); |
| IASTFunctionDefinition func = currentNode_.getFuncDef(); |
| func.accept(this); |
| for (Enumeration<String> e = stacks_.keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| Stack<BarrierExpression> sk = stacks_.get(comm); |
| BarrierExpression be = sk.pop(); |
| if (traceOn) |
| System.out.println(currentNode_.getFuncName() + "(" + comm + "): " + be.prettyPrinter()); //$NON-NLS-1$ //$NON-NLS-2$ |
| if (traceOn) |
| System.out.println(" "); //$NON-NLS-1$ |
| currentNode_.setBarrierExpr(comm, be); |
| } |
| } |
| if (traceOn) |
| System.out.println("Total number of nodes: " + BarrierExpression.count_node); //$NON-NLS-1$ |
| } |
| |
| public int visit(IASTStatement stmt) { |
| if (stmt instanceof IASTSwitchStatement) { |
| for (Enumeration<Stack<List>> e = caseBE.elements(); e.hasMoreElements();) { |
| Stack<List> caseBEsk = e.nextElement(); |
| caseBEsk.push(new ArrayList<Object>()); |
| } |
| withBreak.push(new Boolean(false)); |
| depth++; |
| } |
| return PROCESS_CONTINUE; |
| } |
| |
| public int leave(IASTStatement stmt) { |
| BarrierExpression be = null; |
| BarrierExpression operand1 = null; |
| BarrierExpression operand2 = null; |
| BarrierExpression condBE = null; |
| |
| if (stmt instanceof IASTAmbiguousStatement) { |
| |
| } |
| else if (stmt instanceof IASTBreakStatement) { |
| IASTBreakStatement bkStmt = (IASTBreakStatement) stmt; |
| if (inCaseStmt(bkStmt)) { |
| for (Enumeration<String> e = caseBE.keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| Stack<List> caseBEsk = caseBE.get(comm); |
| Stack<BarrierExpression> sk = stacks_.get(comm); |
| be = new BarrierExpression(BarrierExpression.BE_bot); |
| sk.push(be); |
| List list = caseBEsk.peek(); |
| for (int i = 1; i < list.size(); i += 2) { |
| CaseBarrierExpr cbe = (CaseBarrierExpr) list.get(i); |
| cbe.close(); |
| } |
| } |
| } |
| else { |
| for (Enumeration<String> e = caseBE.keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| Stack<BarrierExpression> sk = stacks_.get(comm); |
| be = new BarrierExpression(BarrierExpression.BE_bot); |
| sk.push(be); |
| } |
| } |
| } |
| else if (stmt instanceof IASTCaseStatement) { |
| IASTCaseStatement caseStmt = (IASTCaseStatement) stmt; |
| /* Override the old parent if it exists */ |
| if (!caseParent.empty()) |
| caseParent.pop(); |
| caseParent.push(caseStmt.getParent()); |
| |
| for (Enumeration e = caseBE.keys(); e.hasMoreElements();) { |
| String comm = (String) e.nextElement(); |
| Stack<List> caseBEsk = caseBE.get(comm); |
| Stack<BarrierExpression> sk = stacks_.get(comm); |
| be = new BarrierExpression(BarrierExpression.BE_bot); |
| sk.push(be); |
| List list = caseBEsk.peek(); |
| list.add(caseStmt); |
| list.add(new CaseBarrierExpr(be, caseStmt.getExpression())); |
| } |
| |
| /* Toggle the withBreak sign of the previous case */ |
| if (!withBreak.empty()) |
| withBreak.pop(); |
| withBreak.push(new Boolean(false)); |
| } |
| else if (stmt instanceof IASTCompoundStatement) { |
| IASTCompoundStatement cmpStmt = (IASTCompoundStatement) stmt; |
| IASTStatement[] s = cmpStmt.getStatements(); |
| if (s.length == 0) |
| return PROCESS_CONTINUE; |
| |
| for (Enumeration<String> e = stacks_.keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| Stack<BarrierExpression> sk = stacks_.get(comm); |
| /* The concatenate operator is left-associative */ |
| int count = 0; |
| int i; |
| BarrierExpression[] BElist = new BarrierExpression[s.length]; |
| for (i = 0; i < s.length; i++) { |
| if (s[i] == null) |
| continue; |
| BElist[count] = sk.pop(); |
| count++; |
| } |
| operand1 = BElist[count - 1]; |
| for (i = count - 2; i >= 0; i--) { |
| operand2 = BElist[i]; |
| be = BarrierExpression.concatBE(operand1, operand2); |
| operand1 = be; |
| } |
| sk.push(operand1); |
| fixSwitch(comm, cmpStmt, operand1); |
| } |
| } |
| else if (stmt instanceof IASTContinueStatement) { |
| for (Enumeration<String> e = caseBE.keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| Stack<BarrierExpression> sk = stacks_.get(comm); |
| be = new BarrierExpression(BarrierExpression.BE_bot); |
| sk.push(be); |
| } |
| } |
| else if (stmt instanceof IASTDeclarationStatement) { |
| boolean initialized = false; |
| IASTDeclarationStatement declStmt = (IASTDeclarationStatement) stmt; |
| IASTDeclaration decl = declStmt.getDeclaration(); |
| if (decl instanceof IASTSimpleDeclaration) { |
| IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) decl; |
| IASTDeclarator[] declarators = simpleDecl.getDeclarators(); |
| for (int i = 0; i < declarators.length; i++) { |
| IASTInitializer init = declarators[i].getInitializer(); |
| if (init != null) { |
| initialized = true; |
| for (Enumeration<String> e = stacks_.keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| Stack<BarrierExpression> sk = stacks_.get(comm); |
| be = getInitializerBE(sk, init); |
| sk.push(be); |
| } |
| } |
| } |
| } |
| if (!initialized) { |
| for (Enumeration<String> e = stacks_.keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| Stack<BarrierExpression> sk = stacks_.get(comm); |
| be = new BarrierExpression(BarrierExpression.BE_bot); |
| sk.push(be); |
| } |
| } |
| } |
| else if (stmt instanceof IASTDefaultStatement) { |
| /* DefaultStatement = CaseStatement + BreakStatement */ |
| IASTDefaultStatement dfStmt = (IASTDefaultStatement) stmt; |
| /* Override the old parent if it exists */ |
| if (!caseParent.empty()) |
| caseParent.pop(); |
| caseParent.push(dfStmt.getParent()); |
| |
| for (Enumeration<String> e = caseBE.keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| Stack<List> caseBEsk = caseBE.get(comm); |
| Stack<BarrierExpression> sk = stacks_.get(comm); |
| be = new BarrierExpression(BarrierExpression.BE_bot); |
| List list = caseBEsk.peek(); |
| list.add(dfStmt); |
| list.add(new CaseBarrierExpr(be, null)); |
| } |
| } |
| else if (stmt instanceof IASTDoStatement) { |
| IASTDoStatement doStmt = (IASTDoStatement) stmt; |
| for (Enumeration<String> e = stacks_.keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| Stack<BarrierExpression> sk = stacks_.get(comm); |
| /* condition */ |
| if (doStmt.getCondition() != null) |
| condBE = (BarrierExpression) sk.pop(); |
| else |
| condBE = new BarrierExpression(BarrierExpression.BE_bot); |
| /* loop body */ |
| if (doStmt.getBody() != null) |
| operand1 = (BarrierExpression) sk.pop(); |
| else |
| operand1 = new BarrierExpression(BarrierExpression.BE_bot); |
| /* BE = body . cond. (body . cond)* */ |
| be = BarrierExpression.concatBE(operand1, condBE, |
| BarrierExpression.repeatBE( |
| BarrierExpression.concatBE(operand1, condBE), |
| doStmt.getCondition(), stmt)); |
| sk.push(be); |
| fixSwitch(comm, stmt, be); |
| } |
| } |
| else if (stmt instanceof IASTExpressionStatement) { |
| for (Enumeration<String> e = stacks_.keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| Stack<BarrierExpression> sk = stacks_.get(comm); |
| be = sk.pop(); |
| sk.push(be); |
| fixSwitch(comm, stmt, be); |
| } |
| } |
| else if (stmt instanceof IASTForStatement) { |
| IASTForStatement forStmt = (IASTForStatement) stmt; |
| BarrierExpression initBE = null; |
| BarrierExpression iterBE = null; |
| for (Enumeration<String> e = stacks_.keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| Stack<BarrierExpression> sk = stacks_.get(comm); |
| /* loop body */ |
| if (forStmt.getBody() != null) |
| operand1 = sk.pop(); |
| else |
| operand1 = new BarrierExpression(BarrierExpression.BE_bot); |
| /* iterator */ |
| if (forStmt.getIterationExpression() != null) |
| iterBE = sk.pop(); |
| else |
| iterBE = new BarrierExpression(BarrierExpression.BE_bot); |
| /* condition */ |
| if (forStmt.getConditionExpression() != null) |
| condBE = sk.pop(); |
| else |
| condBE = new BarrierExpression(BarrierExpression.BE_bot); |
| /* initializer */ |
| if (forStmt.getInitializerStatement() != null) |
| initBE = sk.pop(); |
| else |
| initBE = new BarrierExpression(BarrierExpression.BE_bot); |
| /* BE = init . cond. (body . iter . cond)* */ |
| be = BarrierExpression.concatBE(initBE, condBE, |
| BarrierExpression.repeatBE( |
| BarrierExpression.concatBE(operand1, iterBE, condBE), |
| forStmt.getConditionExpression(), stmt)); |
| sk.push(be); |
| fixSwitch(comm, stmt, be); |
| } |
| } |
| else if (stmt instanceof IASTGotoStatement) { |
| /* TODO */ |
| } |
| else if (stmt instanceof IASTIfStatement) { |
| IASTIfStatement ifStmt = (IASTIfStatement) stmt; |
| for (Enumeration<String> e = stacks_.keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| Stack<BarrierExpression> sk = stacks_.get(comm); |
| /* else clause */ |
| if (ifStmt.getElseClause() != null) |
| operand2 = sk.pop(); |
| else |
| operand2 = new BarrierExpression(BarrierExpression.BE_bot); |
| /* then clause */ |
| if (ifStmt.getThenClause() != null) |
| operand1 = sk.pop(); |
| else |
| operand1 = new BarrierExpression(BarrierExpression.BE_bot); |
| /* condition */ |
| if (ifStmt.getConditionExpression() != null) |
| condBE = sk.pop(); |
| else |
| condBE = new BarrierExpression(BarrierExpression.BE_bot); |
| /* BE = cond. (then | else) */ |
| be = BarrierExpression.concatBE(condBE, |
| BarrierExpression.branchBE(operand1, operand2, |
| ifStmt.getConditionExpression(), stmt)); |
| sk.push(be); |
| fixSwitch(comm, stmt, be); |
| } |
| } |
| else if (stmt instanceof IASTLabelStatement) { |
| /* TODO */ |
| } |
| else if (stmt instanceof IASTNullStatement) { |
| for (Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();) { |
| Stack<BarrierExpression> sk = e.nextElement(); |
| be = new BarrierExpression(BarrierExpression.BE_bot); |
| sk.push(be); |
| } |
| } |
| else if (stmt instanceof IASTProblemStatement) { |
| for (Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();) { |
| Stack<BarrierExpression> sk = e.nextElement(); |
| be = new BarrierExpression(BarrierExpression.BE_bot); |
| sk.push(be); |
| } |
| } |
| else if (stmt instanceof IASTReturnStatement) { |
| IASTReturnStatement rStmt = (IASTReturnStatement) stmt; |
| if (rStmt.getReturnValue() == null) { |
| for (Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();) { |
| Stack<BarrierExpression> sk = e.nextElement(); |
| be = new BarrierExpression(BarrierExpression.BE_bot); |
| sk.push(be); |
| } |
| } else { |
| for (Enumeration<String> e = caseBE.keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| Stack<BarrierExpression> sk = stacks_.get(comm); |
| be = sk.pop(); |
| sk.push(be); |
| if (!withBreak.empty()) { |
| withBreak.pop(); |
| withBreak.push(new Boolean(true)); |
| } |
| fixSwitch(comm, rStmt, be); |
| } |
| } |
| } |
| else if (stmt instanceof IASTSwitchStatement) { |
| IASTSwitchStatement swStmt = (IASTSwitchStatement) stmt; |
| for (Enumeration<String> e = caseBE.keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| Stack<List> caseBEsk = caseBE.get(comm); |
| List list = caseBEsk.pop(); |
| CaseBarrierExpr cbe = (CaseBarrierExpr) list.get(1); |
| operand1 = (BarrierExpression) cbe.getBE(); |
| for (int i = 3; i < list.size(); i += 2) { |
| cbe = (CaseBarrierExpr) list.get(i); |
| operand2 = (BarrierExpression) cbe.getBE(); |
| be = BarrierExpression.branchBE(operand1, operand2, |
| swStmt.getControllerExpression(), stmt); |
| operand1 = be; |
| } |
| Stack<BarrierExpression> sk = stacks_.get(comm); |
| sk.pop(); |
| sk.push(operand1); |
| } |
| withBreak.pop(); |
| caseParent.pop(); |
| depth--; |
| } |
| else if (stmt instanceof IASTWhileStatement) { |
| IASTWhileStatement whStmt = (IASTWhileStatement) stmt; |
| for (Enumeration<String> e = stacks_.keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| Stack<BarrierExpression> sk = stacks_.get(comm); |
| /* loop body */ |
| if (whStmt.getBody() != null) |
| operand1 = sk.pop(); |
| else |
| operand1 = new BarrierExpression(BarrierExpression.BE_bot); |
| /* condition */ |
| if (whStmt.getCondition() != null) |
| condBE = sk.pop(); |
| else |
| condBE = new BarrierExpression(BarrierExpression.BE_bot); |
| /* BE = cond . (body . cond)* */ |
| be = BarrierExpression.concatBE(condBE, |
| BarrierExpression.repeatBE( |
| BarrierExpression.concatBE(operand1, condBE), |
| whStmt.getCondition(), stmt)); |
| sk.push(be); |
| fixSwitch(comm, stmt, be); |
| } |
| } |
| |
| return PROCESS_CONTINUE; |
| } |
| |
| /** |
| * If the current statement is a case body |
| */ |
| private void fixSwitch(String key, IASTStatement stmt, BarrierExpression BE) { |
| if (depth <= 0) |
| return; |
| if (stmt.getParent() == caseParent.peek()) { |
| Stack<List> caseBEsk = caseBE.get(key); |
| List list = caseBEsk.peek(); |
| boolean flag = ((Boolean) withBreak.peek()).booleanValue(); |
| for (int i = 1; i < list.size(); i += 2) { |
| CaseBarrierExpr cbe = (CaseBarrierExpr) list.get(i); |
| if (flag) |
| cbe.addFinalBEElement(BE); |
| else |
| cbe.addBEElement(BE); |
| } |
| } |
| } |
| |
| private boolean inCaseStmt(IASTBreakStatement stmt) { |
| IASTNode parent = stmt.getParent(); |
| while (parent != null) { |
| if (parent instanceof IASTForStatement || |
| parent instanceof IASTDoStatement || |
| parent instanceof IASTWhileStatement) |
| return false; |
| else if (parent instanceof IASTSwitchStatement) |
| return true; |
| else if (parent instanceof IASTFunctionDefinition) |
| return false; |
| else |
| parent = parent.getParent(); |
| } |
| return false; |
| } |
| |
| private BarrierExpression getInitializerBE(Stack sk, IASTInitializer init) { |
| BarrierExpression BE = null; |
| if (init instanceof IASTInitializerExpression) { |
| BE = (BarrierExpression) sk.pop(); |
| } |
| else if (init instanceof IASTInitializerList) { |
| IASTInitializerList list = (IASTInitializerList) init; |
| IASTInitializer[] inits = list.getInitializers(); |
| for (int j = 0; j < inits.length; j++) { |
| if (BE == null) |
| BE = getInitializerBE(sk, inits[j]); |
| else |
| BE = BarrierExpression.concatBE(BE, |
| getInitializerBE(sk, inits[j])); |
| } |
| } |
| return BE; |
| } |
| |
| /* |
| * An expression which doesn't have any "expression" |
| * field is a terminal. |
| */ |
| public int leave(IASTExpression expr) { |
| BarrierExpression be = null; |
| BarrierExpression operand1 = null; |
| BarrierExpression operand2 = null; |
| BarrierExpression operand3 = null; |
| |
| if (expr instanceof IASTAmbiguousExpression) { |
| /* nothing */ |
| } |
| else if (expr instanceof IASTArraySubscriptExpression) { |
| for (Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();) { |
| Stack<BarrierExpression> sk = e.nextElement(); |
| operand2 = sk.pop(); // subscript |
| operand1 = sk.pop(); // array |
| be = BarrierExpression.concatBE(operand1, operand2); |
| sk.push(be); |
| } |
| } |
| else if (expr instanceof IASTBinaryExpression) { |
| for (Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();) { |
| Stack<BarrierExpression> sk = e.nextElement(); |
| operand2 = sk.pop(); |
| operand1 = sk.pop(); |
| be = BarrierExpression.concatBE(operand1, operand2); |
| sk.push(be); |
| } |
| } |
| else if (expr instanceof IASTCastExpression) { |
| /* Has only one operator, leave it there */ |
| } |
| else if (expr instanceof IASTConditionalExpression) { |
| IASTConditionalExpression cExpr = (IASTConditionalExpression) expr; |
| IASTNode parent = expr.getParent(); |
| while (!(parent instanceof IASTStatement)) |
| parent = parent.getParent(); |
| for (Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();) { |
| Stack<BarrierExpression> sk = e.nextElement(); |
| operand2 = sk.pop(); /* negative */ |
| operand1 = sk.pop(); /* positive */ |
| operand3 = sk.pop(); /* condition */ |
| /* E = C ( P | N ) */ |
| be = BarrierExpression.concatBE(operand3, |
| BarrierExpression.branchBE(operand1, operand2, |
| cExpr.getLogicalConditionExpression(), |
| (IASTStatement) parent)); |
| sk.push(be); |
| } |
| } |
| else if (expr instanceof IASTExpressionList) { |
| IASTExpressionList exprList = (IASTExpressionList) expr; |
| IASTExpression[] exps = exprList.getExpressions(); |
| if (exps.length == 0) |
| return PROCESS_CONTINUE; |
| for (Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();) { |
| Stack<BarrierExpression> sk = e.nextElement(); |
| int count = 0; |
| int i; |
| BarrierExpression[] BElist = new BarrierExpression[exps.length]; |
| for (i = 0; i < exps.length; i++) { |
| if (exps[i] == null) |
| continue; |
| BElist[count] = sk.pop(); |
| count++; |
| } |
| operand1 = BElist[count - 1]; |
| for (i = count - 2; i >= 0; i--) { |
| operand2 = BElist[i]; |
| be = BarrierExpression.concatBE(operand1, operand2); |
| operand1 = be; |
| } |
| sk.push(operand1); |
| } |
| } |
| else if (expr instanceof IASTFieldReference) { |
| /* |
| * for(Enumeration e = stacks_.elements(); e.hasMoreElements();){ |
| * Stack sk = (Stack)e.nextElement(); |
| * operand2 = (BarrierExpression)sk.pop(); //name |
| * operand1 = (BarrierExpression)sk.pop(); //owner |
| * be = BarrierExpression.concatBE(operand1, operand2); |
| * sk.push(be); |
| * } |
| */ |
| } |
| else if (expr instanceof IASTFunctionCallExpression) { |
| IASTFunctionCallExpression fExpr = (IASTFunctionCallExpression) expr; |
| IASTExpression funcname = fExpr.getFunctionNameExpression(); |
| IASTExpression parameter = fExpr.getParameterExpression(); |
| String signature = funcname.getRawSignature(); |
| int id = bTable_.isBarrier(fExpr); |
| if (id != -1) { /* barrier */ |
| be = new BarrierExpression(id); |
| String comm = bTable_.getComm(id); |
| for (Enumeration<String> e = stacks_.keys(); e.hasMoreElements();) { |
| String commkey = e.nextElement(); |
| Stack<BarrierExpression> sk = stacks_.get(commkey); |
| if (parameter != null) |
| sk.pop(); // parameter |
| sk.pop(); // functionName |
| if (commkey.equals(comm)) |
| sk.push(be); |
| else |
| sk.push(new BarrierExpression(BarrierExpression.BE_bot)); |
| } |
| } |
| else { |
| MPICallGraphNode node = (MPICallGraphNode) cg_.getNode(currentNode_.getFileName(), signature); |
| if (node != null && node.barrierRelated()) { |
| /* a function (directly or indirectly) with barriers */ |
| for (Enumeration<String> e = stacks_.keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| Stack<BarrierExpression> sk = stacks_.get(comm); |
| BarrierExpression funcBE = node.getBarrierExpr().get(comm); |
| if (parameter != null) |
| sk.pop(); // parameter |
| sk.pop(); // functionName |
| if (node == currentNode_) { // recursive functions |
| be = new BarrierExpression(node.getFuncName()); |
| } |
| else if (funcBE.isBot()) { |
| be = new BarrierExpression(BarrierExpression.BE_bot); |
| } |
| else { |
| be = new BarrierExpression(signature); |
| } |
| sk.push(be); |
| } |
| } else { // not a barrier related function |
| be = new BarrierExpression(BarrierExpression.BE_bot); |
| for (Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();) { |
| Stack<BarrierExpression> sk = e.nextElement(); |
| if (parameter != null) |
| sk.pop(); // parameter |
| sk.pop(); // functionName |
| sk.push(be); |
| } |
| } |
| } |
| } |
| else if (expr instanceof IASTIdExpression) { // terminal |
| // System.out.println(((IASTIdExpression)expr).getName().toString()); |
| for (Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();) { |
| Stack<BarrierExpression> sk = e.nextElement(); |
| be = new BarrierExpression(BarrierExpression.BE_bot); |
| sk.push(be); |
| } |
| } |
| else if (expr instanceof IASTLiteralExpression) { // terminal |
| // System.out.println(((IASTLiteralExpression)expr).toString()); |
| for (Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();) { |
| Stack<BarrierExpression> sk = e.nextElement(); |
| be = new BarrierExpression(BarrierExpression.BE_bot); |
| sk.push(be); |
| } |
| } |
| /* |
| * else if(expr instanceof IASTProblemExpression){ |
| * System.out.println("IASTProblemExpression"); |
| * } |
| */ |
| else if (expr instanceof IASTTypeIdExpression) { |
| for (Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();) { |
| Stack<BarrierExpression> sk = e.nextElement(); |
| be = new BarrierExpression(BarrierExpression.BE_bot); |
| sk.push(be); |
| } |
| } |
| else if (expr instanceof IASTUnaryExpression) { |
| /* has only one operand, leave it there */ |
| } |
| /* |
| * else if(expr instanceof ICASTTypeIdInitializerExpression){ |
| * System.out.println("ICASTTypeIdInitializerExpression"); |
| * } |
| */ |
| return PROCESS_CONTINUE; |
| } |
| |
| class CaseBarrierExpr { |
| protected BarrierExpression BE; |
| protected boolean closed; |
| protected IASTExpression cond; |
| |
| CaseBarrierExpr(BarrierExpression be, IASTExpression cond) { |
| BE = be; |
| closed = false; |
| this.cond = cond; |
| } |
| |
| public void close() { |
| closed = true; |
| } |
| |
| public BarrierExpression getBE() { |
| return BE; |
| } |
| |
| public IASTExpression getCond() { |
| return cond; |
| } |
| |
| public void addBEElement(BarrierExpression be) { |
| if (closed) |
| return; |
| if (BE == null) { |
| BE = be; |
| } else { |
| BE = BarrierExpression.concatBE(BE, be); |
| } |
| } |
| |
| public void addFinalBEElement(BarrierExpression be) { |
| addBEElement(be); |
| close(); |
| } |
| } |
| |
| protected void checkBarrierRecursion() { |
| for (Iterator<List<ICallGraphNode>> i = cg_.getCycles().iterator(); i.hasNext();) { |
| List<ICallGraphNode> cycle = i.next(); |
| boolean barrierRelated = false; |
| for (Iterator<ICallGraphNode> ii = cycle.iterator(); ii.hasNext();) { |
| MPICallGraphNode node = (MPICallGraphNode) ii.next(); |
| if (node.barrierRelated) { |
| barrierRelated = true; |
| break; |
| } |
| } |
| if (!barrierRelated) |
| continue; |
| if (cycle.size() > 1) { |
| System.out.println("Multi-Function barrier related cycles"); //$NON-NLS-1$ |
| return; |
| } |
| currentNode_ = (MPICallGraphNode) cycle.get(0); |
| for (Enumeration<String> e = currentNode_.getBarrierExpr().keys(); e.hasMoreElements();) { |
| String comm = e.nextElement(); |
| BarrierExpression BE = currentNode_.getBarrierExpr().get(comm); |
| if (recursion(BE) == recursionError) { |
| System.out.println("Recursion Error in " + comm); //$NON-NLS-1$ |
| } |
| } |
| |
| } |
| } |
| |
| protected final int recursionCorrect = 0; |
| protected final int recursionError = 1; |
| protected final int noRecursion = 2; |
| |
| protected int recursion(BarrierExpression BE) { |
| System.out.println(BE.prettyPrinter()); |
| BarrierExpressionOP OP = BE.getOP(); |
| if (OP == null) { |
| if (BE.isFunc()) { // function call |
| String funcName = BE.getFuncName(); |
| MPICallGraphNode fnode = (MPICallGraphNode) cg_.getNode(currentNode_.getFileName(), funcName); |
| if (fnode == currentNode_) |
| return recursionCorrect; |
| else |
| return noRecursion; |
| } |
| else |
| return noRecursion; |
| } |
| else if (OP.getOperator() == BarrierExpressionOP.op_concat) { |
| int v1 = recursion(BE.getOP1()); |
| int v2 = recursion(BE.getOP2()); |
| if (v1 == recursionError || v2 == recursionError) |
| return recursionError; |
| else if (v1 == recursionCorrect || v2 == recursionCorrect) |
| return recursionCorrect; |
| else |
| return noRecursion; |
| |
| } |
| else if (OP.getOperator() == BarrierExpressionOP.op_branch) { |
| int v1 = recursion(BE.getOP1()); |
| int v2 = recursion(BE.getOP2()); |
| if (v1 == noRecursion && v2 == noRecursion) |
| return noRecursion; |
| else |
| return recursionError; |
| } |
| else { // BarrierExpressionOP.op_repeat |
| return recursion(BE.getOP1()); |
| |
| } |
| } |
| |
| } |