| /********************************************************************** |
| * 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; |
| |
| /** |
| * 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) |
| */ |
| 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()); |
| if(traceOn)System.out.println(" "); |
| currentNode_.setBarrierExpr(comm, be); |
| } |
| } |
| if(traceOn)System.out.println("Total number of nodes: " + BarrierExpression.count_node); |
| } |
| |
| 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"); |
| 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); |
| } |
| } |
| |
| } |
| } |
| |
| 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()); |
| |
| } |
| } |
| |
| |
| } |
| |