blob: 35280b0cdf39381b6648158b17dc8beb453b086b [file] [log] [blame]
/**********************************************************************
* Copyright (c) 2007,2010 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.LinkedList;
import java.util.List;
import java.util.Stack;
import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTCompoundStatement;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.ptp.pldt.common.Artifact;
import org.eclipse.ptp.pldt.common.util.SourceInfo;
import org.eclipse.ptp.pldt.mpi.analysis.IDs;
import org.eclipse.ptp.pldt.mpi.analysis.analysis.BarrierExpression.BarrierExpressionOP;
import org.eclipse.ptp.pldt.mpi.analysis.analysis.BarrierTable.BarrierInfo;
import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.ICallGraph;
import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.ICallGraphNode;
import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.IControlFlowGraph;
import org.eclipse.ptp.pldt.mpi.analysis.messages.Messages;
import org.eclipse.ptp.pldt.mpi.analysis.popup.actions.ShowMatchSet;
public class MPIBarrierMatching {
protected ICallGraph cg_;
protected IControlFlowGraph cfg_;
protected MPICallGraphNode currentFunc_;
protected String currentComm_;
protected Hashtable<BarrierExpression,List<BarrierExpression>> visited_;
protected BarrierTable barrierTable_;
protected List<ErrorMessage> barrierErrors_;
protected boolean error;
protected int mv = 0;
protected int sv = 0;
private static final boolean traceOn=false;
public MPIBarrierMatching(ICallGraph cg, BarrierTable table){
cg_ = cg;
barrierTable_ = table;
visited_ = new Hashtable<BarrierExpression,List<BarrierExpression>>();
barrierErrors_ = new ArrayList<ErrorMessage>();
}
public List<ErrorMessage> getErrors(){
return barrierErrors_;
}
/**
* Determine matching of MPI barriers.
* @param reportErrors if true, produces a popup warning of barrier errors when found.
* <br>if false, no popup occurs. Useful for running under JUnit test, with no user interaction.
* Note that reportErrors is also used to make sure only a single error is reported -
* the popup warning, if shown, is only shown once per analysis.
* @since 4.0
*/
public void run(boolean reportErrors){
for(ICallGraphNode n = cg_.botEntry(); n != null; n = n.botNext()){
MPICallGraphNode node = (MPICallGraphNode)n;
if(!node.marked || !node.barrierRelated()) continue;
//System.out.println(node.getFuncName());
currentFunc_ = node;
cfg_ = node.getCFG();
Hashtable<String,BarrierExpression> barrierExpr = node.getBarrierExpr();
for(Enumeration<String> e = barrierExpr.keys(); e.hasMoreElements();){
currentComm_ = (String)e.nextElement();
BarrierExpression be = barrierExpr.get(currentComm_);
error = false;
fixedLength(be);
if(error){
// Don't report an error dialog for *each* barrier matching error found
// Only the first one, if at all
if (reportErrors) {
reportErrors=false; // don't report any more
String errorMsg = Messages.MPIBarrierMatching_foundBarrierSyncError;
MessageDialog.openInformation(ShowMatchSet
.getStandardDisplay().getActiveShell(),
Messages.MPIBarrierMatching_mpiBarrierAnalysis, errorMsg);
}
}
findMatches(be);
}
}
//symmMatches();
if(traceOn)printMatches();
if(traceOn)System.out.println("mv = " + mv + ", sv = " + sv); //$NON-NLS-1$ //$NON-NLS-2$
}
protected void fixedLength(BarrierExpression BE){
//System.out.println(BE.prettyPrinter());
BarrierExpressionOP OP = BE.getOP();
if(OP == null){
if(BE.isBot()){
BE.setLength(0);
}
else if(BE.isBarrier()){
BE.setLength(1);
}
else { //function call
String funcName = BE.getFuncName();
MPICallGraphNode fnode = (MPICallGraphNode)cg_.getNode(currentFunc_.getFileName(), funcName);
if(fnode != null && fnode.barrierRelated()){
if(fnode.isRecursive())
BE.setLength(BarrierExpression.TOP);
else{
BarrierExpression fBE = fnode.getBarrierExpr().get(currentComm_);
BE.setLength(fBE.getLength());
}
} else {
BE.setLength(0);
}
}
}
else if(OP.getOperator() == BarrierExpressionOP.op_concat){
BarrierExpression oprd1 = BE.getOP1();
BarrierExpression oprd2 = BE.getOP2();
fixedLength(oprd1);
fixedLength(oprd2);
int length1 = oprd1.getLength();
int length2 = oprd2.getLength();
if(length1 == BarrierExpression.TOP || length2 == BarrierExpression.TOP){
BE.setLength(BarrierExpression.TOP);
} else {
BE.setLength(length1 + length2);
}
}
else if(OP.getOperator() == BarrierExpressionOP.op_branch){
/* need special treatment for conditional expression */
BarrierExpression oprd1 = BE.getOP1();
BarrierExpression oprd2 = BE.getOP2();
fixedLength(oprd1);
fixedLength(oprd2);
int length1 = oprd1.getLength();
int length2 = oprd2.getLength();
MPIBlock cond = (MPIBlock)cfg_.getBlock(OP.getCondition(), OP.getStatement());
if(cond.getMV()) mv ++;
else sv ++;
if(length1 == BarrierExpression.TOP || length2 == BarrierExpression.TOP){
BE.setLength(BarrierExpression.TOP);
if(cond.getMV()){
BE.setErrorFlag(true);
if(!(oprd1.getErrorFlag() || oprd2.getErrorFlag())){
// We only report errors in the lowest level
reportWarning(BE);
}
}
} else if(length1 == length2){
BE.setLength(length1);
} else { // length1 != TOP && length2 != TOP && length1 != length2
BE.setLength(BarrierExpression.TOP);
if(cond.getMV()){
BE.setErrorFlag(true);
if(!(oprd1.getErrorFlag() || oprd2.getErrorFlag())){
reportWarning(BE);
}
}
}
}
else { //BarrierExpressionOP.op_repeat
BarrierExpression oprd = BE.getOP1();
fixedLength(oprd);
MPIBlock cond = (MPIBlock)cfg_.getBlock(OP.getCondition(), OP.getStatement());
if(cond.getMV()) mv ++;
else sv ++;
if(oprd.getLength() == 0){
BE.setLength(0);
} else {
BE.setLength(BarrierExpression.TOP);
if(cond.getMV()){
BE.setErrorFlag(true);
if(!oprd.getErrorFlag()){
reportWarning(BE);
}
}
}
}
}
protected void reportWarning(BarrierExpression BE){
error = true;
IASTStatement stmt = BE.getOP().getStatement();
if(traceOn)System.out.println("Barrier mismatching found in " + stmt); //$NON-NLS-1$
IASTExpression cond = null;
if(stmt instanceof IASTIfStatement)
cond = ((IASTIfStatement)stmt).getConditionExpression();
else if(stmt instanceof IASTDoStatement)
cond = ((IASTDoStatement)stmt).getCondition();
else if(stmt instanceof IASTForStatement)
cond = ((IASTForStatement)stmt).getConditionExpression();
else if(stmt instanceof IASTWhileStatement)
cond = ((IASTWhileStatement)stmt).getCondition();
else if(stmt instanceof IASTSwitchStatement)
cond = ((IASTSwitchStatement)stmt).getControllerExpression();
else{
System.out.println("Barrier Expression doesn't have valid condition"); //$NON-NLS-1$
return;
}
int line = -1;
IASTNodeLocation[] locations = cond.getNodeLocations();
if (locations.length == 1) {
IASTFileLocation astFileLocation = null;
if (locations[0] instanceof IASTFileLocation){
astFileLocation = (IASTFileLocation) locations[0];
line = astFileLocation.getStartingLineNumber();
}
}
try{
// Don't want it to be a problem marker: then it's harder to delete (don't
// want to delete the other problem markers)
//IMarker m = currentFunc_.getResource().createMarker(IMarker.PROBLEM);
IMarker m = currentFunc_.getResource().createMarker(IDs.errorMarkerID);
//IMarker m = currentFunc_.getResource().createMarker(IDs.errorMarkerID);
m.setAttribute(IMarker.LINE_NUMBER, line);
m.setAttribute(IMarker.MESSAGE, Messages.MPIBarrierMatching_barrierSyncError);
m.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);
m.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
}catch(CoreException e){
System.out.println("RM: exception creating markers."); //$NON-NLS-1$
e.printStackTrace();
}
ErrorMessage err = new ErrorMessage(cond, stmt, currentFunc_.getFuncName(),
currentFunc_.getFileName(), currentFunc_.getResource());
counterExample(BE, err);
barrierErrors_.add(err);
}
private boolean changed = false;
protected void counterExample(BarrierExpression BE, ErrorMessage err){
BarrierExpressionOP op = BE.getOP();
if(op.getOperator() == BarrierExpressionOP.op_branch){
List<PathNode> path1 = new ArrayList<PathNode>();
List<PathNode> path2 = new ArrayList<PathNode>();
boolean first = true;
while(true){
changed = false;
traverseBarrierExpr(path1, BE.getOP1(), cfg_);
traverseBarrierExpr(path2, BE.getOP2(), cfg_);
if(differentLength(path1, path2))
break;
if(!changed && !first){
System.out.println("We cannot find the counter example!"); //$NON-NLS-1$
}
if(first) first = true;
path1 = new ArrayList<PathNode>();
path2 = new ArrayList<PathNode>();
}
err.setPath1(path1);
err.setPath2(path2);
if(traceOn)System.out.println("Path 1: "); //$NON-NLS-1$
for(Iterator<PathNode> i=path1.iterator(); i.hasNext();){
PathNode pn = i.next();
pn.print();
if(traceOn)System.out.print(", "); //$NON-NLS-1$
}
if(traceOn)System.out.println(" "); //$NON-NLS-1$
if(traceOn)System.out.println("Path 2: "); //$NON-NLS-1$
for(Iterator<PathNode> i=path2.iterator(); i.hasNext();){
PathNode pn = i.next();
pn.print();
if(traceOn)System.out.print(", "); //$NON-NLS-1$
}
if(traceOn)System.out.println(" "); //$NON-NLS-1$
}
else if(op.getOperator() == BarrierExpressionOP.op_repeat){
List<PathNode> path1 = new ArrayList<PathNode>();
traverseBarrierExpr(path1, BE.getOP1(), cfg_);
for(Iterator<PathNode> i = path1.iterator(); i.hasNext();){
PathNode pn = i.next();
pn.setRepeat(true);
}
err.setPath1(path1);
if(traceOn)System.out.println("Path: "); //$NON-NLS-1$
for(Iterator<PathNode> i=path1.iterator(); i.hasNext();){
PathNode pn = i.next();
pn.print();
if(traceOn)System.out.print(", "); //$NON-NLS-1$
}
if(traceOn)System.out.println(" "); //$NON-NLS-1$
}
}
protected void traverseBarrierExpr(List<PathNode> path, BarrierExpression BE,
IControlFlowGraph cfg){
//System.out.println(BE.prettyPrinter());
BarrierExpressionOP op = BE.getOP();
if(op == null){
if(BE.isBot()){
return;
}
else if(BE.isBarrier()){
BarrierInfo barrier = barrierTable_.searchBarrierbyID(BE.getBarrierID());
PathNode pn = new PathNode(barrier, false);
path.add(pn);
}
else { //function call
String funcName = BE.getFuncName();
MPICallGraphNode fnode = (MPICallGraphNode)cg_.getNode(currentFunc_.getFileName(), funcName);
if(fnode != null && fnode.barrierRelated()){
BarrierExpression fBE = (BarrierExpression)fnode.getBarrierExpr().get(currentComm_);
traverseBarrierExpr(path, fBE, fnode.getCFG());
} else {
return;
}
}
}
else if(op.getOperator() == BarrierExpressionOP.op_branch){
MPIBlock cond = (MPIBlock)cfg.getBlock(op.getCondition(), op.getStatement());
if(cond.getMV()){
/* Concurrent branch. Both branches should have same lengths,
* thus it doesn't matter which branch to choose. By default
* we choose the left branch.
*/
traverseBarrierExpr(path, BE.getOP1(), cfg);
} else if(BE.getLength() != BarrierExpression.TOP){
/* Both branches have same length that are not \TOP */
traverseBarrierExpr(path, BE.getOP1(), cfg);
} else if(changed){
/* Some change has been made somewhere else. So keep the
* previous choice at this point
*/
if(BE.getOP2().ceVisited)
traverseBarrierExpr(path, BE.getOP2(), cfg);
else
traverseBarrierExpr(path, BE.getOP1(), cfg);
} else {
/* Nothing changed till now */
if(BE.getOP2().ceVisited){
/* We cannot make any change. Keep the previous choice */
traverseBarrierExpr(path, BE.getOP2(), cfg);
} else if(BE.getOP1().ceVisited){
/* Make change here */
traverseBarrierExpr(path, BE.getOP2(), cfg);
changed = true;
} else {
/* This BE is visited the first time */
traverseBarrierExpr(path, BE.getOP1(), cfg);
}
}
}
else if(op.getOperator() == BarrierExpressionOP.op_concat){
traverseBarrierExpr(path, BE.getOP1(), cfg);
traverseBarrierExpr(path, BE.getOP2(), cfg);
}
else if(op.getOperator() == BarrierExpressionOP.op_repeat){
traverseBarrierExpr(path, BE.getOP1(), cfg);
for(Iterator<PathNode> i = path.iterator(); i.hasNext();){
PathNode pn = i.next();
pn.setRepeat(true);
}
}
BE.ceVisited = true;
}
protected boolean differentLength(List<PathNode> path1, List<PathNode> path2){
if(path1.size() != path2.size()) return true;
for(int i = 0; i<path1.size(); i++){
if(path1.get(i).isRepeat() || path2.get(i).isRepeat())
return true;
}
return false;
}
public class PathNode{
private BarrierInfo barrier_;
private boolean repeat;
public PathNode(BarrierInfo barrier, boolean repeat){
this.barrier_ = barrier;
this.repeat = repeat;
}
public PathNode(BarrierInfo barrier){
this.barrier_ = barrier;
repeat = false;
}
public void setRepeat(boolean val){
repeat = val;
}
public boolean isRepeat(){
return repeat;
}
public BarrierInfo getBarrier(){
return barrier_;
}
public void print(){
if(traceOn)System.out.print(barrier_.getID());
if(repeat)
if(traceOn)System.out.print("(*)"); //$NON-NLS-1$
}
}
public class ErrorMessage{
private IASTExpression position_;
private IASTStatement errStmt_;
private String funcName_;
private String fileName_;
private SourceInfo sourceInfo_;
private SourceInfo path1SourceInfo_;
private SourceInfo path2SourceInfo_;
private IResource resource_;
private List<PathNode> path1_ = null;
private List<PathNode> path2_ = null;
private int length1 = 0;
private int length2 = 0;
public ErrorMessage(IASTExpression pos, IASTStatement stmt, String funcName,
String fileName, IResource res){
position_ = pos;
errStmt_ = stmt;
funcName_ = funcName;
fileName_ = fileName;
resource_ = res;
sourceInfo_ = getSourceInfo(position_);
if(errStmt_ instanceof IASTIfStatement){
IASTIfStatement ifS = (IASTIfStatement)errStmt_;
path1SourceInfo_ = getSourceInfo(ifS.getThenClause());
path2SourceInfo_ = getSourceInfo(ifS.getElseClause());
} else if(errStmt_ instanceof IASTDoStatement){
IASTDoStatement doS = (IASTDoStatement)errStmt_;
path1SourceInfo_ = getSourceInfo(doS.getBody());
path2SourceInfo_ = null;
} else if(errStmt_ instanceof IASTForStatement){
IASTForStatement forS = (IASTForStatement)errStmt_;
path1SourceInfo_ = getSourceInfo(forS.getBody());
path2SourceInfo_ = null;
} else if(errStmt_ instanceof IASTWhileStatement){
IASTWhileStatement whileS = (IASTWhileStatement)errStmt_;
path1SourceInfo_ = getSourceInfo(whileS.getBody());
path2SourceInfo_ = null;
} else if(errStmt_ instanceof IASTSwitchStatement){
IASTSwitchStatement switchS = (IASTSwitchStatement)errStmt_;
path1SourceInfo_ = getSourceInfo(switchS.getBody());
path2SourceInfo_ = path1SourceInfo_;
}
}
SourceInfo getSourceInfo(IASTNode node){
SourceInfo sourceInfo = new SourceInfo();
if(node == null) return sourceInfo;
IASTNodeLocation[] locations = node.getNodeLocations();
if (locations.length == 1) {
IASTFileLocation astFileLocation = null;
if (locations[0] instanceof IASTFileLocation){
astFileLocation = (IASTFileLocation) locations[0];
sourceInfo.setStartingLine(astFileLocation.getStartingLineNumber());
sourceInfo.setStart(astFileLocation.getNodeOffset());
sourceInfo.setEnd(astFileLocation.getNodeOffset() + astFileLocation.getNodeLength());
sourceInfo.setConstructType(Artifact.NONE);
}
}
else {
//System.out.println("MPIBarrierMatching.getSourceInfo().. ! More than one IASTNodeLocation !");
// CASTCompoundStatement causes this. Probably ok? assuming it descends into the child nodes
if (traceOn) {
if (node instanceof CASTCompoundStatement) {
CASTCompoundStatement cstmt = (CASTCompoundStatement) node;
System.out.println("Compound stmt: " + cstmt.getRawSignature()); //$NON-NLS-1$
IASTNodeLocation[] locs = cstmt.getNodeLocations();
for (int i = 0; i < locs.length; i++) {
IASTNodeLocation loc = locs[i];
System.out.println(" subnode: " + loc.toString()); //$NON-NLS-1$
}
}
}
}
return sourceInfo;
}
public void setPath1(List<PathNode> path){
path1_ = path;
int count = 0;
for(Iterator<PathNode> i = path.iterator(); i.hasNext();){
PathNode pn = i.next();
if(pn.isRepeat()){
length1 = -1;
return;
} else {
count ++;
}
}
length1 = count;
}
public void setPath2(List<PathNode> path){
path2_ = path;
int count = 0;
for(Iterator<PathNode> i = path.iterator(); i.hasNext();){
PathNode pn = i.next();
if(pn.isRepeat()){
length2 = -1;
return;
} else {
count ++;
}
}
length2 = count;
}
public IASTExpression getPosition(){
return position_;
}
public String getFuncName(){
return funcName_;
}
public String getFileName(){
return fileName_;
}
public SourceInfo getSourceInfo(){
return sourceInfo_;
}
public SourceInfo getPath1SourceInfo(){
return path1SourceInfo_;
}
public SourceInfo getPath2SourceInfo(){
return path2SourceInfo_;
}
public IResource getResource(){
return resource_;
}
public List<PathNode> getPath1(){
return path1_;
}
public List<PathNode> getPath2(){
return path2_;
}
public int getLength1(){
return length1;
}
public int getLength2(){
return length2;
}
}
protected void findMatches(BarrierExpression BE){
if(traceOn)System.out.println(BE.prettyPrinter());
BarrierExpressionOP OP = BE.getOP();
if(BE.visited) return;
BE.visited = true;
if(OP == null){
if(BE.isFunc()){
String funcName = BE.getFuncName();
MPICallGraphNode fnode = (MPICallGraphNode)cg_.getNode(currentFunc_.getFileName(), funcName);
if(fnode != null && fnode.barrierRelated()){
BarrierExpression fBE = (BarrierExpression)fnode.getBarrierExpr().get(currentComm_);
findMatches(fBE);
}
} else {
lstack_ = new Stack<BarrierExpression>();
sstack_ = new Stack<BarrierExpression>();
workList_ = new LinkedList<Work>();
match(BE, BE, down);
while(!workList_.isEmpty()){
Work w = workList_.remove();
match(w.BE1_, w.BE2_, w.direction);
}
}
}
else if(OP.getOperator() == BarrierExpressionOP.op_concat){
BarrierExpression oprd1 = BE.getOP1();
BarrierExpression oprd2 = BE.getOP2();
findMatches(oprd1);
findMatches(oprd2);
}
else if(OP.getOperator() == BarrierExpressionOP.op_branch){
BarrierExpression oprd1 = BE.getOP1();
BarrierExpression oprd2 = BE.getOP2();
MPIBlock cond = (MPIBlock)cfg_.getBlock(OP.getCondition(), OP.getStatement());
if(cond.getMV()){ // concurrent branch
if(!BE.getErrorFlag()){
lstack_ = new Stack<BarrierExpression>();
sstack_ = new Stack<BarrierExpression>();
workList_ = new LinkedList<Work>();
match(oprd1, oprd2, down);
while(!workList_.isEmpty()){
Work w = workList_.remove();
match(w.BE1_, w.BE2_, w.direction);
}
}
}
if(!BE.getErrorFlag()){
findMatches(oprd1);
findMatches(oprd2);
}
}
else { //BarrierExpressionOP.op_repeat
if(!BE.getErrorFlag()){
BarrierExpression oprd = BE.getOP1();
findMatches(oprd);
}
}
}
protected final int down = 0;
protected final int up = 1;
protected Stack<BarrierExpression> lstack_;
protected Stack<BarrierExpression> sstack_;
protected LinkedList<Work> workList_;
class Work{
BarrierExpression BE1_;
BarrierExpression BE2_;
int direction;
Work(BarrierExpression be1, BarrierExpression be2, int direction){
BE1_ = be1;
BE2_ = be2;
this.direction = direction;
}
}
protected void match(BarrierExpression BE1, BarrierExpression BE2, int dir){
BarrierExpression T1 = BE1;
BarrierExpression T2 = BE2;
int direction = dir;
while(true){
if(traceOn)System.out.println("match: "+T1.prettyPrinter()); //$NON-NLS-1$
if(traceOn)System.out.println(" "+T2.prettyPrinter()); //$NON-NLS-1$
if(direction == down) {if(traceOn)System.out.println(" down");} //$NON-NLS-1$
else {if(traceOn)System.out.println(" up");} //$NON-NLS-1$
if(direction == down && !pairVisited(T1, T2))
addVisitedPair(T1, T2);
BarrierExpressionOP OP1 = T1.getOP();
BarrierExpressionOP OP2 = T2.getOP();
if(direction == up && T1 == BE1 && T2 == BE2) break;
else if(direction == down && OP1 == null && OP2 == null &&
T1.isBot() && T2.isBot())
direction = up;
else if(direction == down && OP1 == null && OP2 == null &&
T1.isBarrier() && T2.isBarrier()){
addMatchedPair(T1, T2); // BRT 5 and 5 ???
addMatchedPair(T1, T1);
addMatchedPair(T2, T2);
direction = up;
} else if(direction == down && OP1 == null && T1.isFunc()){ //rule 7
String funcName = T1.getFuncName();
MPICallGraphNode fnode = (MPICallGraphNode)cg_.getNode(currentFunc_.getFileName(), funcName);
if(fnode == null || !fnode.barrierRelated()){
System.out.println("Error in call graph"); //$NON-NLS-1$
}
BarrierExpression fBE = (BarrierExpression)fnode.getBarrierExpr().get(currentComm_);
lstack_.push(T1);
T1 = fBE;
} else if(direction == down && OP2 == null && T2.isFunc()){ //rule 7
String funcName = T2.getFuncName();
MPICallGraphNode fnode = (MPICallGraphNode)cg_.getNode(currentFunc_.getFileName(), funcName);
if(fnode == null || !fnode.barrierRelated()){
System.out.println("Error in call graph"); //$NON-NLS-1$
}
BarrierExpression fBE = (BarrierExpression)fnode.getBarrierExpr().get(currentComm_);
sstack_.push(T2);
T2 = fBE;
} else if(direction == down && OP1 != null &&
OP1.getOperator() == BarrierExpressionOP.op_concat){ //rule 2
T1 = T1.getOP1();
} else if(direction == down && OP2 != null &&
OP2.getOperator() == BarrierExpressionOP.op_concat){ //rule 2
T2 = T2.getOP1();
} else if(direction == up && T1.getParent() == null){ //rule 8
T1 = lstack_.pop();
} else if(direction == up && T2.getParent() == null){ //rule 8
T2 = sstack_.pop();
} else if(direction == up &&
T1.getParent().getOP().getOperator() == BarrierExpressionOP.op_concat
&& T1 == T1.getParent().getOP2()){ //rule 3
T1 = T1.getParent();
direction = up;
} else if(direction == up &&
T2.getParent().getOP().getOperator() == BarrierExpressionOP.op_concat
&& T2 == T2.getParent().getOP2()){ //rule 3
T2 = T2.getParent();
direction = up;
} else if(direction == up && T1.getParent().getOP().getOperator() == BarrierExpressionOP.op_concat
&& T1 == T1.getParent().getOP1()
&& T2.getParent().getOP().getOperator() == BarrierExpressionOP.op_concat
&& T2 == T2.getParent().getOP1()){ //rule 4
T1 = T1.getParent().getOP2();
T2 = T2.getParent().getOP2();
direction = down;
} else if(direction == down && OP1 != null &&
OP1.getOperator() == BarrierExpressionOP.op_branch){ //rule 5
workList_.add(new Work(T1.getOP2(), T2, down));
T1 = T1.getOP1();
} else if(direction == down && OP2 != null &&
OP2.getOperator() == BarrierExpressionOP.op_branch){ //rule 5
workList_.add(new Work(T1, T2.getOP2(), down));
T2 = T2.getOP1();
} else if(direction == up &&
T1.getParent().getOP().getOperator() == BarrierExpressionOP.op_branch){
//rule 6
T1 = T1.getParent();
} else if(direction == up &&
T2.getParent().getOP().getOperator() == BarrierExpressionOP.op_branch){
//rule 6
T2 = T2.getParent();
} else{
System.out.println("cannot find rules for " + T1.prettyPrinter() //$NON-NLS-1$
+ " and " + T2.prettyPrinter() + " and direction = " + direction); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
protected void addVisitedPair(BarrierExpression b1, BarrierExpression b2){
List<BarrierExpression> visitedPair = visited_.get(b1);
if(visitedPair == null){
visitedPair = new ArrayList<BarrierExpression>();
visitedPair.add(b2);
visited_.put(b1, visitedPair);
} else {
if(!visitedPair.contains(b2)) visitedPair.add(b2);
}
visitedPair = visited_.get(b2);
if(visitedPair == null){
visitedPair = new ArrayList<BarrierExpression>();
visitedPair.add(b1);
visited_.put(b2, visitedPair);
} else {
if(!visitedPair.contains(b1)) visitedPair.add(b1);
}
}
protected boolean pairVisited(BarrierExpression b1, BarrierExpression b2){
List<BarrierExpression> pair = visited_.get(b1);
if(pair == null || !pair.contains(b2))
return false;
else
return true;
}
protected void addMatchedPair(BarrierExpression b1, BarrierExpression b2){
BarrierInfo bar1 = barrierTable_.searchBarrierbyID(b1.getBarrierID());
BarrierInfo bar2 = barrierTable_.searchBarrierbyID(b2.getBarrierID());
List<BarrierInfo> set1 = bar1.getMatchingSet();
List<BarrierInfo> set2 = bar2.getMatchingSet();
if(!set1.contains(bar2)) set1.add(bar2); // adds to matchingSet_
if(!set2.contains(bar1)) set2.add(bar1);
}
protected void symmMatches(){
for(Enumeration<List<BarrierInfo>> e = barrierTable_.getTable().elements(); e.hasMoreElements();){
List<BarrierInfo> list = e.nextElement();
for(Iterator<BarrierInfo> i = list.iterator(); i.hasNext();){
BarrierInfo bar = i.next();
if(traceOn)System.out.println("bar = " + bar.getID()); //$NON-NLS-1$
for(Iterator<BarrierInfo> ii = bar.getMatchingSet().iterator(); ii.hasNext();){
BarrierInfo matchedBar = ii.next();
if(traceOn)System.out.println("matchedBar = " + matchedBar.getID()); //$NON-NLS-1$
if(!matchedBar.getMatchingSet().contains(bar)){
if(traceOn)System.out.println("bar = " + bar.getID() + ", matchedBar = " + matchedBar.getID()); //$NON-NLS-1$ //$NON-NLS-2$
matchedBar.getMatchingSet().add(bar);
}
}
}
}
}
protected void printMatches(){
for(Enumeration<List<BarrierInfo>> e = barrierTable_.getTable().elements(); e.hasMoreElements();){
List<BarrierInfo> list = e.nextElement();
for(Iterator<BarrierInfo> i = list.iterator(); i.hasNext();){
BarrierInfo bar = i.next();
if(traceOn)System.out.print("Barrier " + bar.getID() + " matches to : "); //$NON-NLS-1$ //$NON-NLS-2$
for(Iterator<BarrierInfo> ii = bar.getMatchingSet().iterator(); ii.hasNext();){
BarrierInfo matchedBar = ii.next();
if(traceOn)System.out.print(matchedBar.getID() + ", "); //$NON-NLS-1$
}
}
if(traceOn)System.out.println(" "); //$NON-NLS-1$
}
}
}